You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ce...@apache.org on 2004/04/22 22:07:29 UTC

cvs commit: logging-log4j/src/java/org/apache/log4j LogManager.java

ceki        2004/04/22 13:07:29

  Modified:    tests/src/java/org/apache/log4j/scheduler SchedulerTest.java
               src/java/org/apache/log4j LogManager.java
  Added:       tests/src/java/org/apache/log4j/scheduler PeriodicJob.java
                        CountingJob.java
  Log:
  - LogManager now offers a Scheduler instance (a singleton) to be shared
  by multiple watchdogs and receivers.
  -More tests cases for the Scheduler.
  
  Revision  Changes    Path
  1.4       +50 -106   logging-log4j/tests/src/java/org/apache/log4j/scheduler/SchedulerTest.java
  
  Index: SchedulerTest.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/tests/src/java/org/apache/log4j/scheduler/SchedulerTest.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SchedulerTest.java	21 Apr 2004 09:45:09 -0000	1.3
  +++ SchedulerTest.java	22 Apr 2004 20:07:29 -0000	1.4
  @@ -30,9 +30,8 @@
    *
    */
   public class SchedulerTest extends TestCase {
  -  static final long TOLERATED_GAP = 1000;
  +  static final long TOLERATED_GAP = 2000;
     Random random = new Random(480361007);
  -  final long START_TIME = System.currentTimeMillis();
   
     public SchedulerTest(String arg0) {
       super(arg0);
  @@ -96,6 +95,7 @@
       scheduler.schedule(cj0, expected0);
       scheduler.schedule(cj1, expected1);
       scheduler.delete(cj0);
  +    cj0.markAsDeleted();
       sleep(100 + (3 * 200));
       assertEquals(0, cj0.count);
       assertEquals(1, cj1.count);
  @@ -112,10 +112,10 @@
       Vector deletedVector = new Vector();
   
       // the approximative duration of this test in millisecs
  -    final int TEST_DURATION = 50000;
  +    final int TEST_DURATION = 15000;
   
       // the frequncy of operations in millisecs
  -    final int OP_FREQUENCY = 10;
  +    final int OP_FREQUENCY = 25;
   
       // The number of times we will perform an operation on the scheduler
       final int MAX_OPS = TEST_DURATION / OP_FREQUENCY;
  @@ -127,25 +127,34 @@
           int indexToDelete = getRandomIndexToDelete(jobVector.size());
           CountingJob j = (CountingJob) jobVector.remove(indexToDelete);
   
  -        if (j.count == 0) {
  -          scheduler.delete(j);
  -          deletedVector.add(j);
  -
  -          if (j.count == 1) {
  -            fail("Error in the test code itself.");
  -          }
  -        }
  +        scheduler.delete(j);
  +        deletedVector.add(j);
  +        j.markAsDeleted();
         } else {
           long expected = start + random.nextInt(TEST_DURATION);
  -        CountingJob cj = new CountingJob((int) i, expected);
  -        jobVector.add(cj);
  -        scheduler.schedule(cj, expected);
  +        CountingJob cj;
  +        
  +        if (shouldBePeriodic()) {
  +          System.out.println(i+ " is periodic");
  +          // the period should be at least 50 millis
  +          int period = random.nextInt(500)+50;
  +          cj = new PeriodicJob((int) i, expected, period);
  +          jobVector.add(cj);
  +          scheduler.schedule(cj, expected, period);
  +        } else {
  +          cj = new CountingJob((int) i, expected);
  +          jobVector.add(cj);
  +          scheduler.schedule(cj, expected);
  +        }
  +        
         }
       }
   
       long loopEnd = System.currentTimeMillis();
       sleep(TEST_DURATION - (loopEnd - start) + 2000);
   
  +    long endOfExecution = System.currentTimeMillis();
  +
       if (deletedVector.size() > (MAX_OPS / 2)) {
         fail("too many deleted jobs: " + deletedVector.size());
       }
  @@ -156,12 +165,12 @@
   
       for (Iterator i = jobVector.iterator(); i.hasNext();) {
         CountingJob cj = (CountingJob) i.next();
  -      assertEquals(1, cj.count);
  +      cj.sanityCheck(endOfExecution);
       }
   
       for (Iterator i = deletedVector.iterator(); i.hasNext();) {
         CountingJob cj = (CountingJob) i.next();
  -      assertEquals(0, cj.count);
  +      cj.sanityCheck(endOfExecution);
       }
     }
   
  @@ -180,12 +189,14 @@
   
       scheduler.shutdown();
   
  +    long endOfExecution = System.currentTimeMillis();
  +
       if (pj.count < 10) {
         fail(
  -        "Periodic job executed only " + pj.count
  -        + " times. Expected at least"+NUM_PERIODS);
  +        "Periodic job executed only " + pj.count + " times. Expected at least"
  +        + NUM_PERIODS);
       }
  -    pj.checkPeriods();
  +    pj.sanityCheck(endOfExecution);
     }
   
     public void testMultiplePeriodic() {
  @@ -208,14 +219,17 @@
       sleep(period * NUM_PERIODS);
       scheduler.shutdown();
   
  +    long endOfExecution = System.currentTimeMillis();
  +
       for (int i = 0; i < runLen; i++) {
         PeriodicJob pj = (PeriodicJob) jobs.get(i);
  +
         if (pj.count < NUM_PERIODS) {
           fail(
             "Periodic job executed only " + pj.count
  -          + " times. Expected at least "+NUM_PERIODS);
  +          + " times. Expected at least " + NUM_PERIODS);
         }
  -      pj.checkPeriods();
  +      pj.sanityCheck(endOfExecution);
       }
     }
   
  @@ -229,6 +243,17 @@
       }
     }
   
  +  // One in every 10 tests should be periodic
  +  boolean shouldBePeriodic() {
  +    int r = random.nextInt(10);
  +
  +    if (r == 0) {
  +      return true;
  +    } else {
  +      return false;
  +    }
  +  }
  +
     // On average, make the index of 1 out of 5 deletes zero
     int getRandomIndexToDelete(int range) {
       int r = random.nextInt(5);
  @@ -247,93 +272,12 @@
       }
     }
   
  -  public static Test suite() {
  +  public static Test xsuite() {
       TestSuite suite = new TestSuite();
   
  -    //suite.addTest(new SchedulerTest("testRandom"));
  +    suite.addTest(new SchedulerTest("testRandom"));
       //suite.addTest(new SchedulerTest("testPeriodic"));
  -    suite.addTest(new SchedulerTest("testMultiplePeriodic"));
  +    //suite.addTest(new SchedulerTest("testMultiplePeriodic"));
       return suite;
  -  }
  -
  -  class CountingJob implements Job {
  -    int count = 0;
  -    int id;
  -    long scheduledTime;
  -
  -    CountingJob(int id, long scheduledTime) {
  -      this.id = id;
  -      this.scheduledTime = scheduledTime;
  -    }
  -
  -    public void execute() {
  -      long now = System.currentTimeMillis();
  -      count++;
  -
  -      if (now < scheduledTime) {
  -        throw new IllegalStateException("Job executed too early.");
  -      } else if ((now - scheduledTime) > SchedulerTest.TOLERATED_GAP) {
  -        String msg =
  -          "Job id " + id + " executed " + (now - scheduledTime) + " too late "
  -          + "diff " + (scheduledTime - SchedulerTest.this.START_TIME);
  -        System.out.println(msg);
  -        throw new IllegalStateException(msg);
  -      }
  -    }
  -  }
  -
  -
  -  class PeriodicJob implements Job {
  -    int count = 0;
  -    int id;
  -    long period;
  -    Vector desiredTimeVector;
  -    Vector actualExecutionTime;
  -
  -    PeriodicJob(int id, long desiredExecutionTime, long period) {
  -      this.id = id;
  -      this.period = period;
  -      actualExecutionTime = new Vector();
  -      desiredTimeVector = new Vector();
  -      desiredTimeVector.add(new Long(desiredExecutionTime));
  -    }
  -
  -    public void execute() {
  -      long now = System.currentTimeMillis();
  -      count++;
  -      System.out.println(id+" - execute called: count" + count + ", now=" + now);
  -
  -      long lastDesiredTime =
  -        ((Long) desiredTimeVector.lastElement()).longValue();
  -      desiredTimeVector.add(new Long(lastDesiredTime + period));
  -      actualExecutionTime.add(new Long(now));
  -
  -      if (now < lastDesiredTime) {
  -        throw new IllegalStateException("Job executed too early.");
  -      } else if ((now - lastDesiredTime) > SchedulerTest.TOLERATED_GAP) {
  -        String msg =
  -          "Job id " + id + " executed " + (now - lastDesiredTime)
  -          + " too late ";
  -        System.out.println(msg);
  -        throw new IllegalStateException(msg);
  -      }
  -    }
  -
  -    void checkPeriods() {
  -      for (int i = 0; i < actualExecutionTime.size(); i++) {
  -        long actual = ((Long) actualExecutionTime.get(i)).longValue();
  -        long desired = ((Long) desiredTimeVector.get(i)).longValue();
  -
  -        if (actual < desired) {
  -          throw new IllegalStateException("Job executed too early.");
  -        } else if (
  -          (actual - desired) > (SchedulerTest.TOLERATED_GAP * (i + 1))) {
  -          String msg =
  -            "Job id " + id + " executed " + (actual - desired) + " too late ";
  -          System.out.println(msg);
  -          throw new IllegalStateException(msg);
  -        }
  -      }
  -    }
     }
   }
  
  
  
  1.1                  logging-log4j/tests/src/java/org/apache/log4j/scheduler/PeriodicJob.java
  
  Index: PeriodicJob.java
  ===================================================================
  /*
   * Copyright 1999,2004 The Apache Software Foundation.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  package org.apache.log4j.scheduler;
  
  import java.util.Vector;
  
  
  class PeriodicJob extends CountingJob {
    long period;
    Vector desiredTimeVector;
    Vector actualExecutionTime;
  
    PeriodicJob(int id, long desiredExecutionTime, long period) {
      super(id, desiredExecutionTime);
      this.period = period;
      actualExecutionTime = new Vector();
      desiredTimeVector = new Vector();
      desiredTimeVector.add(new Long(desiredExecutionTime));
    }
  
    public void execute() {
      if (deleted) {
        throw new IllegalStateException(id + "has already been deleted");
      }
  
      long now = System.currentTimeMillis();
      count++;
  
  
      //System.out.println(
      //id + " - execute called: count" + count + ", now=" + now);
      long lastDesiredTime =
        ((Long) desiredTimeVector.lastElement()).longValue();
      desiredTimeVector.add(new Long(lastDesiredTime + period));
      actualExecutionTime.add(new Long(now));
  
      if (now < lastDesiredTime) {
        throw new IllegalStateException("Job executed too early.");
      } else if ((now - lastDesiredTime) > SchedulerTest.TOLERATED_GAP) {
        String msg =
          "Job id " + id + " executed " + (now - lastDesiredTime) + " too late ";
        System.out.println(msg);
        throw new IllegalStateException(msg);
      }
    }
  
    void sanityCheck(long currentTime) {
      System.out.println("sanity check on " + id);
  
  
      if (!deleted) {
        int expectedNumberOfExecutions =
          (int) ((currentTime - desiredTime) / period);
  
        // allow for 10% error margin
        if ((actualExecutionTime.size()*1.1) < expectedNumberOfExecutions) {
          throw new IllegalStateException(
            "Too few executions. Was " + actualExecutionTime.size()
            + " expected " + expectedNumberOfExecutions + " period="+period);
        }
      }
  
      for (int i = 0; i < actualExecutionTime.size(); i++) {
        long actual = ((Long) actualExecutionTime.get(i)).longValue();
        long desired = ((Long) desiredTimeVector.get(i)).longValue();
  
        if (actual < desired) {
          throw new IllegalStateException("Job executed too early.");
        } else if ((actual - desired) > (SchedulerTest.TOLERATED_GAP * (i + 1))) {
          String msg =
            "Job id " + id + " executed " + (actual - desired) + " too late ";
          System.out.println(msg);
          throw new IllegalStateException(msg);
        }
      }
    }
  }
  
  
  
  1.1                  logging-log4j/tests/src/java/org/apache/log4j/scheduler/CountingJob.java
  
  Index: CountingJob.java
  ===================================================================
  package org.apache.log4j.scheduler;
  
  class CountingJob implements Job {
    int count = 0;
    int id;
    long desiredTime;
    boolean deleted;
  
    CountingJob(int id, long scheduledTime) {
      this.id = id;
      this.desiredTime = scheduledTime;
    }
  
    public void execute() {
      if (deleted) {
        throw new IllegalStateException(id + "has already been deleted");
      }
  
      long now = System.currentTimeMillis();
      count++;
  
      if (now < desiredTime) {
        throw new IllegalStateException("Job executed too early.");
      } else if ((now - desiredTime) > SchedulerTest.TOLERATED_GAP) {
        String msg =
          "Job id " + id + " executed " + (now - desiredTime) + " too late ";
        System.out.println(msg);
        throw new IllegalStateException(msg);
      }
    }
  
    void markAsDeleted() {
      deleted = true;
    }
    void sanityCheck(long currentTime) {
    }
  }
  
  
  
  
  1.21      +18 -1     logging-log4j/src/java/org/apache/log4j/LogManager.java
  
  Index: LogManager.java
  ===================================================================
  RCS file: /home/cvs/logging-log4j/src/java/org/apache/log4j/LogManager.java,v
  retrieving revision 1.20
  retrieving revision 1.21
  diff -u -r1.20 -r1.21
  --- LogManager.java	30 Mar 2004 10:45:21 -0000	1.20
  +++ LogManager.java	22 Apr 2004 20:07:29 -0000	1.21
  @@ -20,6 +20,7 @@
   import org.apache.log4j.helpers.IntializationUtil;
   import org.apache.log4j.helpers.Loader;
   import org.apache.log4j.helpers.OptionConverter;
  +import org.apache.log4j.scheduler.Scheduler;
   import org.apache.log4j.selector.ContextJNDISelector;
   import org.apache.log4j.spi.DefaultRepositorySelector;
   import org.apache.log4j.spi.LoggerFactory;
  @@ -42,7 +43,8 @@
   public class LogManager {
     private static Object guard = null;
     private static RepositorySelector repositorySelector;
  -
  +  private static Scheduler schedulerInstance = null;
  +  
     static {
       System.out.println("**Start of LogManager static initializer");
       Hierarchy defaultHierarchy = new Hierarchy(new RootCategory(Level.DEBUG));
  @@ -204,5 +206,20 @@
   
     public static void resetConfiguration() {
       repositorySelector.getLoggerRepository().resetConfiguration();
  +  }
  +  
  +  /**
  +   * 
  +   * Return a singleton {@link Scheduler} instance to be shared by multiple
  +   * receivers and watchdogs. 
  +   * 
  +   * @since 1.3
  +   */
  +  public static Scheduler getSchedulerInstance() {
  +    if(schedulerInstance == null) {
  +      schedulerInstance = new Scheduler();
  +      schedulerInstance.start();
  +    }
  +    return schedulerInstance;
     }
   }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org