package com.limegroup.gnutella; import junit.framework.Test; import com.limegroup.gnutella.settings.ApplicationSettings; public class StatisticsTest extends com.limegroup.gnutella.util.BaseTestCase { //Most of this code assumes a window factor W of 7 days. /** Fudge factor */ private float DELTA=0.0001f; private static final int MSECS_PER_HOUR=60*60*1000; private static final int MSECS_PER_DAY=24*MSECS_PER_HOUR; public StatisticsTest(String name) { super(name); } public static Test suite() { return buildTestSuite(StatisticsTest.class); } public void setUp() { ApplicationSettings.LAST_SHUTDOWN_TIME.setValue(0); ApplicationSettings.FRACTIONAL_UPTIME.setValue(0.0f); TestStatistics.now=0; } /** Tests the test! You may laugh, but it took me a while to get that class * working, because the initializer for Statistics depends on template * methods in the subclass, which was previously using uninitialized state * of the subclass. */ public void testTestStatistics() { TestStatistics.now=1000; TestStatistics t=new TestStatistics(); TestStatistics.now+=12; assertEquals(12, t.getUptime()); } /** * Start up for first time. Run for 1 day. Shutdown. */ public void testFirstDay() { TestStatistics.now=MSECS_PER_DAY*8; TestStatistics stats=new TestStatistics(); TestStatistics.now+=MSECS_PER_DAY; assertEquals(1.0f/7.0f, stats.calculateFractionalUptime(), DELTA); } /** * Run half the time: make sure value doesn't change. */ public void testHalfTimeEquilibrium() { // ------up------ // days 0 1 2 ApplicationSettings.FRACTIONAL_UPTIME.setValue(0.5f); TestStatistics.now=MSECS_PER_DAY; TestStatistics stats=new TestStatistics(); TestStatistics.now+=MSECS_PER_DAY; assertEquals(0.5f, stats.calculateFractionalUptime(), DELTA); assertEquals(12*60*60., (float)stats.calculateDailyUptime(), DELTA); } /** * Initially up half time. Shut down for 2 days, run for 1 day. * New uptime: 3/7*1/3+4/7*0.5=3/7 */ public void testFractionalUpdate() { //Test calculate without property update ApplicationSettings.FRACTIONAL_UPTIME.setValue(0.5f); TestStatistics.now=2*MSECS_PER_DAY; TestStatistics stats=new TestStatistics(); TestStatistics.now+=MSECS_PER_DAY; assertEquals(3.0f/7.0f, stats.calculateFractionalUptime(), DELTA); assertEquals(0, ApplicationSettings.LAST_SHUTDOWN_TIME.getValue()); assertEquals(0.5f, ApplicationSettings.FRACTIONAL_UPTIME.getValue(), DELTA); //Test shutdown method too. stats.shutdown(); assertEquals(TestStatistics.now, ApplicationSettings.LAST_SHUTDOWN_TIME.getValue()); assertEquals(3.0f/7.0f, ApplicationSettings.FRACTIONAL_UPTIME.getValue(), DELTA); } /** Test one hour down, two hours up. It takes a long time to * converge on this value. */ public void testConvergence() { for (int i=0; i<200; i++) { TestStatistics.now+=MSECS_PER_HOUR; TestStatistics stats=new TestStatistics(); //start TestStatistics.now+=2*MSECS_PER_HOUR; stats.shutdown(); //stop } assertEquals(2.0f/3.0f, ApplicationSettings.FRACTIONAL_UPTIME.getValue(), 0.05); } /** * Run for a huge period of time. */ public void testUpFullTime() { TestStatistics.now=MSECS_PER_DAY; //optional TestStatistics stats=new TestStatistics(); TestStatistics.now+=MSECS_PER_DAY*8; assertEquals(1.0f, stats.calculateFractionalUptime(), DELTA); assertEquals(24*60*60., (float)stats.calculateDailyUptime(), DELTA); } /** * Tests clocks running backwards, e.g., from daylight savings. * (Session should be ignored) */ public void testUptimeBackwards() { ApplicationSettings.FRACTIONAL_UPTIME.setValue(0.5f); //Test calculate without property update TestStatistics.now=MSECS_PER_DAY; TestStatistics stats=new TestStatistics(); TestStatistics.now-=MSECS_PER_HOUR; //backwards! assertEquals(0.5f, ApplicationSettings.FRACTIONAL_UPTIME.getValue(), 0.0f); //Test shutdown method too. stats.shutdown(); assertEquals(TestStatistics.now, ApplicationSettings.LAST_SHUTDOWN_TIME.getValue()); assertEquals(0.5f, ApplicationSettings.FRACTIONAL_UPTIME.getValue(), 0.0f); } /** * Tests clocks running backwards, e.g., from daylight savings. * (Session should be ignored) */ public void testShutdownBackwards() { ApplicationSettings.LAST_SHUTDOWN_TIME.setValue(MSECS_PER_DAY); ApplicationSettings.FRACTIONAL_UPTIME.setValue(0.5f); //Test calculate without property update TestStatistics.now= ApplicationSettings.LAST_SHUTDOWN_TIME.getValue()-MSECS_PER_HOUR; TestStatistics stats=new TestStatistics(); TestStatistics.now+=MSECS_PER_DAY; assertEquals(0.5f, ApplicationSettings.FRACTIONAL_UPTIME.getValue(), 0.0f); //Test shutdown method too. stats.shutdown(); assertEquals(TestStatistics.now, ApplicationSettings.LAST_SHUTDOWN_TIME.getValue()); assertEquals(0.5f, ApplicationSettings.FRACTIONAL_UPTIME.getValue(), 0.0f); } } /** Lets you fake the system time used in fractional uptime calculations. */ class TestStatistics extends Statistics { static long now; protected long now() { //Need static variable because Statistics.startTime() is //initialized before local fields of TestStatistics. return now; } }