Package com.salas.bb.persistence.backend

Source Code of com.salas.bb.persistence.backend.TestHsqlPersistenceManagerStats

// BlogBridge -- RSS feed reader, manager, and web based service
// Copyright (C) 2002-2006 by R. Pito Salas
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software Foundation;
// either version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along with this program;
// if not, write to the Free Software Foundation, Inc., 59 Temple Place,
// Suite 330, Boston, MA 02111-1307 USA
//
// Contact: R. Pito Salas
// mailto:pitosalas@users.sourceforge.net
// More information: about BlogBridge
// http://www.blogbridge.com
// http://sourceforge.net/projects/blogbridge
//
// $Id: TestHsqlPersistenceManagerStats.java,v 1.6 2007/10/04 08:49:53 spyromus Exp $
//

package com.salas.bb.persistence.backend;

import com.salas.bb.domain.*;
import com.salas.bb.persistence.PersistenceException;
import com.salas.bb.persistence.domain.CountStats;
import com.salas.bb.persistence.domain.VisitStats;
import com.salas.bb.utils.Constants;

import java.net.MalformedURLException;
import java.net.URL;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

/**
* This suite contains tests for <code>HsqlPersistenceManager</code> unit.
*/
public class TestHsqlPersistenceManagerStats extends AbstractHsqlPersistenceTestCase
{
    private static final int SLEEP_TIME = 100;
    private static final int MS_RANGE = 2000;

    protected DirectFeed feed;
    protected StandardGuide guide;
    protected long creationTime;

    @Override
    protected void setUp() throws Exception
    {
        super.setUp();
        initManager("/resources");

        // Create a feed
        feed = new DirectFeed();
        feed.setXmlURL(new URL("http://localhost/"));

        creationTime = System.currentTimeMillis();

        // Create a guide
        guide = new StandardGuide();
        guide.setTitle("1");
        guide.add(feed);

        // Insert a guide
        pm.insertGuide(guide, 0);
    }

    /**
     * Checks if the stats table record is created.
     *
     * @throws PersistenceException exception.
     * @throws SQLException exception.
     */
    public void testAddGuide()
        throws PersistenceException, SQLException
    {
        // Check if the row is there
        VisitStats stats = getGuideVisitStats(guide.getID());
        assertNotNull(stats);
        assertEquals(0, stats.getCountTotal());
        assertEquals(0, stats.getCountReset());
        assertTrue("Failed range check. initTime = " + stats.getInitTime() + ", now=" + creationTime,
            Math.abs(stats.getInitTime() - creationTime) < MS_RANGE);
        assertTrue("Failed range check. resetTime = " + stats.getResetTime() + ", now=" + creationTime,
            Math.abs(stats.getResetTime() - creationTime) < MS_RANGE);
    }

    /**
     * Checks if the stats table record is created.
     *
     * @throws PersistenceException exception.
     * @throws SQLException exception.
     */
    public void testAddFeed()
        throws PersistenceException, SQLException
    {
        // Check if the row is there
        VisitStats stats = getFeedVisitStats(feed.getID());
        assertNotNull(stats);
        assertEquals(0, stats.getCountTotal());
        assertEquals(0, stats.getCountReset());
        assertTrue("Failed range check. initTime = " + stats.getInitTime() + ", now=" + creationTime,
            Math.abs(stats.getInitTime() - creationTime) < MS_RANGE);
        assertTrue("Failed range check. resetTime = " + stats.getResetTime() + ", now=" + creationTime,
            Math.abs(stats.getResetTime() - creationTime) < MS_RANGE);
    }

    /** Checks visiting a guide. */
    public void testVisitGuide()
    {
        // Visit a guide
        pm.guideVisited(guide);

        // Check
        VisitStats stats = getGuideVisitStats(guide.getID());
        assertEquals(guide.getTitle(), stats.getObjectTitle());
        assertEquals(1, stats.getCountTotal());
        assertEquals(1, stats.getCountReset());
    }

    /** Checks visiting a transient guide. */
    public void testVisitTransientGuide()
    {
        // Create a non-saved guide
        StandardGuide guide2 = new StandardGuide();
        guide2.setTitle("2");

        // Visit a guide -- should be no error
        pm.guideVisited(guide2);
    }

    /** Checks visiting a feed. */
    public void testVisitFeed()
    {
        // Visit a feed
        pm.feedVisited(feed);

        // Check
        VisitStats stats = getFeedVisitStats(feed.getID());
        assertEquals(feed.getTitle(), stats.getObjectTitle());
        assertEquals(1, stats.getCountTotal());
        assertEquals(1, stats.getCountReset());
    }

    /** Visiting a transient feed. */
    public void testVisitTransientFeed()
    {
        // Create a non-saved feed
        DirectFeed feed2 = new DirectFeed();

        // Visit a feed -- should be no error
        pm.feedVisited(feed2);
    }

    /**
     * Recording hour and day stats.
     *
     * @throws PersistenceException exception.
     *
     * @throws SQLException if database fails.
     */
    public void testReadStats()
        throws PersistenceException, SQLException
    {
        PreparedStatement stmt;

        // Check the number of hour records in the database
        stmt = pm.getPreparedStatement("SELECT COUNT(*) FROM READSTATS_HOUR");
        ResultSet rs = stmt.executeQuery();
        assertTrue(rs.next());
        assertEquals(Constants.HOURS_IN_DAY, rs.getInt(1));

        // Check the number of day records in the database
        stmt = pm.getPreparedStatement("SELECT COUNT(*) FROM READSTATS_DAY");
        rs = stmt.executeQuery();
        assertTrue(rs.next());
        assertEquals(Constants.DAYS_IN_WEEK, rs.getInt(1));

        // Get current hour and day
        Calendar cal = new GregorianCalendar();
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int day = cal.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;

        // Read it
        StandardArticle article = new StandardArticle("");
        feed.appendArticle(article);
        pm.articlesRead(null, null, 1);

        // Check hours
        CountStats[] stats = pm.getItemsReadPerHour();
        assertEquals(Constants.HOURS_IN_DAY, stats.length);
        for (int i = 0; i < Constants.HOURS_IN_DAY; i++)
        {
            assertEquals(i == hour ? 1 : 0, stats[i].getCountTotal());
            assertEquals(i == hour ? 1 : 0, stats[i].getCountReset());
        }

        // Check days
        stats = pm.getItemsReadPerWeekday();
        assertEquals(Constants.DAYS_IN_WEEK, stats.length);
        for (int i = 0; i < Constants.DAYS_IN_WEEK; i++)
        {
            assertEquals(i == day ? 1 : 0, stats[i].getCountTotal());
            assertEquals(i == day ? 1 : 0, stats[i].getCountReset());
        }
    }

    /**
     * Reporting top 3 most visited guides.
     *
     * @throws PersistenceException exception.
     * @throws InterruptedException if sleeping is interrupted.
     */
    public void testTopGuideVisits()
        throws PersistenceException, InterruptedException
    {
        // Create 3 more guides and visit them
        StandardGuide guide2 = addAndVisitGuide("2", 2);
        StandardGuide guide3 = addAndVisitGuide("3", 4);
        StandardGuide guide4 = addAndVisitGuide("4", 1);

        // Wait a little
        sleep();

        // Get 3 most visited guides
        List<VisitStats> list = pm.getMostVisitedGuides(3);
        assertEquals(3, list.size());
        assertVisitStats(guide3.getID(), 4, 4, list.get(0));
        assertVisitStats(guide2.getID(), 2, 2, list.get(1));
        assertVisitStats(guide4.getID(), 1, 1, list.get(2));
    }

    /**
     * Reporting top 3 most visited feeds.
     *
     * @throws PersistenceException exception.
     * @throws MalformedURLException exception.
     * @throws InterruptedException if interrupted.
     */
    public void testTopFeedVisits()
        throws MalformedURLException, PersistenceException, InterruptedException
    {
        // Create 3 more feeds and visit them
        DirectFeed feed2 = addAndVisitFeed("2", 2);
        DirectFeed feed3 = addAndVisitFeed("2", 4);
        DirectFeed feed4 = addAndVisitFeed("2", 1);

        // Wait a little
        sleep();

        // Get 3 most visited feeds
        List<VisitStats> list = pm.getMostVisitedFeeds(3);
        assertEquals(3, list.size());
        assertVisitStats(feed3.getID(), 4, 4, list.get(0));
        assertVisitStats(feed2.getID(), 2, 2, list.get(1));
        assertVisitStats(feed4.getID(), 1, 1, list.get(2));
    }

    /**
     * Reseting time.
     *
     * @throws SQLException if database fails.
     * @throws InterruptedException if interrupted.
     */
    public void testResetTime()
        throws SQLException, InterruptedException
    {
        long reset1 = getResetTime();

        // Sleep a bit
        sleep();
        pm.reset();

        long reset2 = getResetTime();
        assertFalse(reset1 == reset2);
    }

    /**
     * Reseting visit stats.
     */
    public void testResetVisits()
    {
        // Visit guides and feeds
        visit(guide, 2);
        visit(feed, 2);

        // Reset
        pm.reset();

        // Visit more
        visit(guide, 2);
        visit(feed, 2);

        // Check
        assertVisitStats(guide.getID(), 4, 2, getGuideVisitStats(guide.getID()));
        assertVisitStats(feed.getID(), 4, 2, getFeedVisitStats(feed.getID()));
    }

    /**
     * Reseting reading stats.
     *
     * @throws PersistenceException if fails to query records from database.
     */
    public void testResetReadStats()
        throws PersistenceException
    {
        // Get current hour and day
        Calendar cal = new GregorianCalendar();
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int day = cal.get(Calendar.DAY_OF_WEEK) - Calendar.SUNDAY;

        // Create a sample article
        StandardArticle article = new StandardArticle("");
        feed.appendArticle(article);

        // Mark two articles
        pm.articlesRead(null, null, 1);
        pm.articlesRead(null, null, 1);

        // Reset
        pm.reset();

        // Mark two more articles
        pm.articlesRead(null, null, 1);
        pm.articlesRead(null, null, 1);

        // Check Read per hour
        CountStats[] stats = pm.getItemsReadPerHour();
        for (int i = 0; i < Constants.HOURS_IN_DAY; i++)
        {
            assertEquals(i == hour ? 4 : 0, stats[i].getCountTotal());
            assertEquals(i == hour ? 2 : 0, stats[i].getCountReset());
        }

        // Check Read per weekday
        stats = pm.getItemsReadPerWeekday();
        for (int i = 0; i < Constants.DAYS_IN_WEEK; i++)
        {
            assertEquals(i == day ? 4 : 0, stats[i].getCountTotal());
            assertEquals(i == day ? 2 : 0, stats[i].getCountReset());
        }

        // Check Read history
    }

    /**
     * Returns guide stats by given guide id.
     *
     * @param id ID.
     *
     * @return stats or <code>NULL</code> if row isn't there.
     */
    private VisitStats getGuideVisitStats(long id)
    {
        VisitStats stats = null;

        try
        {
            Statement stmt = pm.getConnection().createStatement();
            ResultSet rs = stmt.executeQuery(
                "SELECT GS.*, G.TITLE TITLE " +
                "FROM GUIDESTATS GS, GUIDES G " +
                "WHERE G.ID=GUIDEID AND GUIDEID = " + id);
            if (rs.next())
            {
                stats = new VisitStats((int)id,
                    rs.getString("TITLE"),
                    rs.getLong("COUNT_TOTAL"),
                    rs.getLong("COUNT_RESET"),
                    rs.getLong("INIT_TIME"),
                    rs.getLong("RESET_TIME"));
            }
        } catch (SQLException e)
        {
            e.printStackTrace();
            fail("Failed to fetch the guide stats.");
        }

        return stats;
    }

    /**
     * Returns feed stats by given guide ID.
     *
     * @param id ID.
     *
     * @return stats or <code>NULL</code> if row isn't there.
     */
    private VisitStats getFeedVisitStats(long id)
    {
        VisitStats stats = null;

        try
        {
            Statement stmt = pm.getConnection().createStatement();
            ResultSet rs = stmt.executeQuery(
                "SELECT FS.*, COALESCE(DF.TITLE, DF.XMLURL, QF.TITLE, SF.TITLE) TITLE " +
                "FROM FEEDSTATS FS LEFT JOIN DIRECTFEEDS DF ON DF.FEEDID=FS.FEEDID " +
                    "LEFT JOIN QUERYFEEDS QF ON QF.FEEDID=FS.FEEDID " +
                    "LEFT JOIN SEARCHFEEDS SF ON SF.FEEDID=FS.FEEDID " +
                "WHERE FEEDID = " + id);
            if (rs.next())
            {
                stats = new VisitStats((int)id,
                    rs.getString("TITLE"),
                    rs.getLong("COUNT_TOTAL"),
                    rs.getLong("COUNT_RESET"),
                    rs.getLong("INIT_TIME"),
                    rs.getLong("RESET_TIME"));
            }
        } catch (SQLException e)
        {
            e.printStackTrace();
            fail("Failed to fetch the feed stats.");
        }

        return stats;
    }

    /**
     * Create, add and visit guide.
     *
     * @param title         guide title.
     * @param visitsCount   visit count.
     *
     * @return guide.
     *
     * @throws PersistenceException exception.
     */
    private StandardGuide addAndVisitGuide(String title, int visitsCount)
        throws PersistenceException
    {
        StandardGuide guide = new StandardGuide();
        guide.setTitle(title);

        pm.insertGuide(guide, 0);
        visit(guide, visitsCount);

        return guide;
    }

    /**
     * Visit guide.
     *
     * @param guide         guide.
     * @param visitCount    visit count.
     */
    private void visit(IGuide guide, int visitCount)
    {
        for (int i = 0; i < visitCount; i++) pm.guideVisited(guide);
    }


    /**
     * Create, add and visit feed.
     *
     * @param title         feed title.
     * @param visitsCount   visit count.
     *
     * @return feed.
     *
     * @throws PersistenceException exception.
     * @throws MalformedURLException exception.
     */
    private DirectFeed addAndVisitFeed(String title, int visitsCount)
        throws PersistenceException, MalformedURLException
    {
        DirectFeed feed = new DirectFeed();
        feed.setXmlURL(new URL("http://localhost/" + title));
        guide.add(feed);

        pm.insertFeed(feed);
        visit(feed, visitsCount);

        return feed;
    }

    /**
     * Visit feed.
     *
     * @param feed          feed.
     * @param visitCount    visit count.
     */
    private void visit(IFeed feed, int visitCount)
    {
        for (int i = 0; i < visitCount; i++) pm.feedVisited(feed);
    }

    /**
     * Checks if visit stats are right.
     *
     * @param id            object ID.
     * @param visitTotal    visit total.
     * @param visitReset    visit since reset.
     * @param visit         target visit stats.
     */
    protected static void assertVisitStats(long id, int visitTotal, int visitReset, VisitStats visit)
    {
        assertEquals(id, visit.getObjectId());
        assertEquals(visitTotal, visit.getCountTotal());
        assertEquals(visitReset, visit.getCountReset());
    }

    /**
     * Gets the reset time.
     *
     * @return reset time.
     *
     * @throws SQLException if database fails.
     */
    protected long getResetTime()
        throws SQLException
    {
        PreparedStatement stmt = pm.getPreparedStatement(
            "SELECT value FROM APP_PROPERTIES WHERE name = 'statsResetTime'");
        ResultSet rs = stmt.executeQuery();

        rs.next();

        return Long.parseLong(rs.getString(1));
    }

    /**
     * Sleeps a bit to make stats stand appart.
     *
     * @throws InterruptedException in case interrupted.
     */
    protected static void sleep()
        throws InterruptedException
    {
        Thread.sleep(SLEEP_TIME);
    }
}
TOP

Related Classes of com.salas.bb.persistence.backend.TestHsqlPersistenceManagerStats

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.