Skip to Content.
Sympa Menu

perfsonar-dev - [pS-dev] [GEANT/SA2/ps-java-services] r5889 - in trunk/perfsonar-java-xml-ls/src: main/java/org/perfsonar/service/lookupservice/components test/java/org/perfsonar/tests/components test/java/org/perfsonar/tests/utilities

Subject: perfsonar development work

List archive

[pS-dev] [GEANT/SA2/ps-java-services] r5889 - in trunk/perfsonar-java-xml-ls/src: main/java/org/perfsonar/service/lookupservice/components test/java/org/perfsonar/tests/components test/java/org/perfsonar/tests/utilities


Chronological Thread 
  • From:
  • To:
  • Subject: [pS-dev] [GEANT/SA2/ps-java-services] r5889 - in trunk/perfsonar-java-xml-ls/src: main/java/org/perfsonar/service/lookupservice/components test/java/org/perfsonar/tests/components test/java/org/perfsonar/tests/utilities
  • Date: Tue, 24 Jan 2012 16:35:01 +0000 (GMT)

Author: dante.delvaux
Date: 2012-01-24 16:35:01 +0000 (Tue, 24 Jan 2012)
New Revision: 5889

Added:

trunk/perfsonar-java-xml-ls/src/test/java/org/perfsonar/tests/utilities/AsynchTester.java
Modified:

trunk/perfsonar-java-xml-ls/src/main/java/org/perfsonar/service/lookupservice/components/ModificationCounterComponent.java

trunk/perfsonar-java-xml-ls/src/test/java/org/perfsonar/tests/components/ModificationCounterComponentTest.java
Log:
Thread safe ModificationCounterComponent implementation, refs PSSERVICES-567
with better unit testing coverage. Adding AsynchTester class to do unit
testing in a threaded environment.

Modified:
trunk/perfsonar-java-xml-ls/src/main/java/org/perfsonar/service/lookupservice/components/ModificationCounterComponent.java
===================================================================
---
trunk/perfsonar-java-xml-ls/src/main/java/org/perfsonar/service/lookupservice/components/ModificationCounterComponent.java
2012-01-13 12:58:38 UTC (rev 5888)
+++
trunk/perfsonar-java-xml-ls/src/main/java/org/perfsonar/service/lookupservice/components/ModificationCounterComponent.java
2012-01-24 16:35:01 UTC (rev 5889)
@@ -1,25 +1,24 @@
package org.perfsonar.service.lookupservice.components;

+import java.util.concurrent.atomic.AtomicInteger;
+
import org.apache.log4j.Logger;
import org.perfsonar.base2.service.configuration.Component;
import org.perfsonar.base2.service.exceptions.PerfSONARException;
/**
*
- * Simple class which contains COUNTER which increase when something id DB
will be changed
+ * Simple class which contains COUNTER which increase when something in the
DB is changed
*
* @author Slawomir Trzaszczka
*/
public class ModificationCounterComponent extends Component{

- private int counter=0;
+ private AtomicInteger counter = new AtomicInteger();
+ // nr of changes since last GLS registration
+ private AtomicInteger diffsBetweenRegistrationCounter = new
AtomicInteger();

- /**
- * nr of changes since last GLS registration
- */
- private int diffsBetweenRegistrationCounter=0;
+ private final Logger logger =
Logger.getLogger(ModificationCounterComponent.class);

- private final Logger
logger=Logger.getLogger(ModificationCounterComponent.class);
-
@Override
public void destroy() throws PerfSONARException {
//do nothing
@@ -33,45 +32,45 @@

@Override
public void init() throws PerfSONARException {
- counter=0;
- diffsBetweenRegistrationCounter=0;
+ counter = new AtomicInteger();
+ diffsBetweenRegistrationCounter = new AtomicInteger();
}

/**
- * invoked when element wants to notify that something was changed in
db :
+ * invoked when element wants to notify that something was changed in
the db :
* - registration
* - deregistration
* - cleanup
*/
- public void incrementCounter(){
- counter++;
- diffsBetweenRegistrationCounter++;
- logger.debug("Counter increased " +counter+ " diffs "+
diffsBetweenRegistrationCounter);
+ public void incrementCounter() {
+ counter.incrementAndGet();
+ diffsBetweenRegistrationCounter.incrementAndGet();
+ logger.debug("Counter increased " + counter + " diffs " +
diffsBetweenRegistrationCounter);
}
/**
* resets counter. This method is invoked after summarization process
*
*/
- public void resetCounter(){
- counter=0;
- logger.debug("reset counter");
+ public void resetCounter() {
+ counter.set(0);
+ logger.debug("Counter reseted");
}

/**
* resets diffsBetweenRegistration counter. This method is invoked
after registration to GLS
*
*/
- public void resetDiffsBetweenRegistrationCounter(){
- logger.debug("reset diffsBetweenRegistrationCounter");
- diffsBetweenRegistrationCounter=0;
+ public void resetDiffsBetweenRegistrationCounter() {
+ diffsBetweenRegistrationCounter.set(0);
+ logger.debug("diffsBetweenRegistrationCounter reseted");
}

public int getCounter() {
- return counter;
+ return counter.get();
}

public int getDiffsBetweenRegistrationCounter() {
- return diffsBetweenRegistrationCounter;
+ return diffsBetweenRegistrationCounter.get();
}

}

Modified:
trunk/perfsonar-java-xml-ls/src/test/java/org/perfsonar/tests/components/ModificationCounterComponentTest.java
===================================================================
---
trunk/perfsonar-java-xml-ls/src/test/java/org/perfsonar/tests/components/ModificationCounterComponentTest.java
2012-01-13 12:58:38 UTC (rev 5888)
+++
trunk/perfsonar-java-xml-ls/src/test/java/org/perfsonar/tests/components/ModificationCounterComponentTest.java
2012-01-24 16:35:01 UTC (rev 5889)
@@ -1,33 +1,181 @@
package org.perfsonar.tests.components;

+import org.apache.log4j.Logger;
+import org.perfsonar.base2.service.exceptions.PerfSONARException;
import
org.perfsonar.service.lookupservice.components.ModificationCounterComponent;
+import org.perfsonar.tests.utilities.AsynchTester;

import junit.framework.TestCase;

-public class ModificationCounterComponentTest extends TestCase{
-
-
- public void testComponent(){
- ModificationCounterComponent cp=new
ModificationCounterComponent();
- cp.incrementCounter();
- assertEquals(1, cp.getCounter());
- assertEquals(1, cp.getDiffsBetweenRegistrationCounter());
- cp.incrementCounter();
- assertEquals(2, cp.getCounter());
- assertEquals(2, cp.getDiffsBetweenRegistrationCounter());
+/**
+ * Test the Modification Counter Component, thread aware
+ * @author Antoine Delvaux

+ *
+ */
+public class ModificationCounterComponentTest extends TestCase {
+ // Singleton counter shared between threads
+ private final ModificationCounterComponent cp;
+ private static final int THREADS_COUNT = 50;
+ private static final int LOOP_COUNT = 100000;
+ private static final Logger logger =
Logger.getLogger(ModificationCounterComponentTest.class);
+
+ /**
+ * Setup the shared counter
+ * @throws PerfSONARException
+ */
+ public ModificationCounterComponentTest() throws PerfSONARException {
+ super();
+ cp = new ModificationCounterComponent();
+ assertNotNull(cp);
+ }
+
+ /**
+ * Basic test of the ModificationCounterComponent (single thread)
+ */
+ public void testCounter() {
+ logger.info("•••• Testing ModificationCounterComponent");
+
+ // Incrementing and testing increment count
+ logger.debug("Counting up to " + LOOP_COUNT);
+ int last = 0;
+ for (int i = 0; i < LOOP_COUNT; i++) {
+ cp.incrementCounter();
+ int value = cp.getCounter();
+ int diffs = cp.getDiffsBetweenRegistrationCounter();
+ assertEquals(value, last + 1);
+ assertEquals(diffs, i + 1);
+ last = value;
+ }

+ assertEquals(cp.getCounter(), LOOP_COUNT);
+ assertEquals(cp.getDiffsBetweenRegistrationCounter(),
LOOP_COUNT);
+
+ // Reset Counter and test it is 0
cp.resetCounter();
assertEquals(0, cp.getCounter());
- assertEquals(2, cp.getDiffsBetweenRegistrationCounter());
+ assertEquals(cp.getDiffsBetweenRegistrationCounter(),
LOOP_COUNT);

-
+ // Reset diffs counter and test it is 0
cp.resetDiffsBetweenRegistrationCounter();
-
assertEquals(0, cp.getCounter());
assertEquals(0, cp.getDiffsBetweenRegistrationCounter());
-
-
}
-
-
+
+ /**
+ * Multi-threaded test of the ModificationCounterComponent increment
+ */
+ public void testThreadedCounterIncrement() throws
InterruptedException {
+ logger.info("•••• Testing threaded incrementation of
ModificationCounterComponent");
+ AsynchTester[] testers = new AsynchTester[THREADS_COUNT];
+ cp.resetCounter();
+ cp.resetDiffsBetweenRegistrationCounter();
+
+ for (int i = 0; i < THREADS_COUNT; i++) {
+ testers[i] = new AsynchTester(new Runnable() {
+
+ @Override
+ public void run() {
+ int last = cp.getCounter();
+
+ for (int i = 0; i < LOOP_COUNT; i++) {
+ cp.incrementCounter();
+ int value = cp.getCounter();
+ int diffs =
cp.getDiffsBetweenRegistrationCounter();
+ assertTrue(value > last);
+ assertTrue(diffs > i);
+ last = value;
+ }
+ }
+ });
+ logger.debug("Starting thread " + i + " and counting up to "
+ LOOP_COUNT);
+ testers[i].start();
+ }
+
+ for (AsynchTester tester : testers)
+ tester.test();
+
+ // At the very end, counter should be 0 and diffs counter should
be the sum of all loops
+ assertEquals(cp.getCounter(), LOOP_COUNT * THREADS_COUNT);
+ assertEquals(cp.getDiffsBetweenRegistrationCounter(), LOOP_COUNT
* THREADS_COUNT);
+ }
+
+ /**
+ * Multi-threaded test of the ModificationCounterComponent reset
+ */
+ public void testThreadedCounterReset() throws InterruptedException {
+ logger.info("•••• Testing threaded reset of
ModificationCounterComponent");
+ AsynchTester[] testers = new AsynchTester[THREADS_COUNT];
+ // We reset the diffs counter
+ cp.resetDiffsBetweenRegistrationCounter();
+
+ for (int i = 0; i < THREADS_COUNT; i++) {
+ testers[i] = new AsynchTester(new Runnable() {
+
+ @Override
+ public void run() {
+ for (int i = 0; i < LOOP_COUNT; i++) {
+ cp.incrementCounter();
+ int diffs =
cp.getDiffsBetweenRegistrationCounter();
+ assertTrue(diffs > i);
+ }
+
+ cp.resetCounter();
+ // Counter max value is all threads up to
LOOP_COUNT except this one
+ assertTrue(cp.getCounter() < (LOOP_COUNT-1) *
(THREADS_COUNT-1));
+
assertTrue(cp.getDiffsBetweenRegistrationCounter() >= LOOP_COUNT);
+ }
+ });
+ logger.debug("Starting thread " + i + " and counting up to "
+ LOOP_COUNT);
+ testers[i].start();
+ }
+
+ for (AsynchTester tester : testers)
+ tester.test();
+
+ // At the very end, counter should be 0 and diffs counter should
be the sum of all loops
+ assertEquals(cp.getCounter(), 0);
+ assertEquals(cp.getDiffsBetweenRegistrationCounter(), LOOP_COUNT
* THREADS_COUNT);
+ }
+
+ /**
+ * Multi-threaded test of the ModificationCounterComponent diffs reset
+ */
+ public void testThreadedCounterDiffsReset() throws
InterruptedException {
+ logger.info("•••• Testing threaded diffs reset of
ModificationCounterComponent");
+ AsynchTester[] testers = new AsynchTester[THREADS_COUNT];
+ // We reset the counter
+ cp.resetCounter();
+
+ for (int i = 0; i < THREADS_COUNT; i++) {
+ testers[i] = new AsynchTester(new Runnable() {
+
+ @Override
+ public void run() {
+ int last = cp.getCounter();
+
+ for (int i = 0; i < LOOP_COUNT; i++) {
+ cp.incrementCounter();
+ int value = cp.getCounter();
+ assertTrue(value > last);
+ last = value;
+ }
+
+ cp.resetDiffsBetweenRegistrationCounter();
+ // Counter max value is all threads up to
LOOP_COUNT except this one
+
assertTrue(cp.getDiffsBetweenRegistrationCounter() < (LOOP_COUNT-1) *
(THREADS_COUNT-1));
+ assertTrue(cp.getCounter() >= LOOP_COUNT);
+ }
+ });
+ logger.debug("Starting thread " + i + " and counting up to "
+ LOOP_COUNT);
+ testers[i].start();
+ }
+
+ for (AsynchTester tester : testers)
+ tester.test();
+
+ // At the very end, counter should be 0 and diffs counter should
be the sum of all loops
+ assertEquals(cp.getDiffsBetweenRegistrationCounter(), 0);
+ assertEquals(cp.getCounter(), LOOP_COUNT * THREADS_COUNT);
+ }
+
}

Added:
trunk/perfsonar-java-xml-ls/src/test/java/org/perfsonar/tests/utilities/AsynchTester.java
===================================================================
---
trunk/perfsonar-java-xml-ls/src/test/java/org/perfsonar/tests/utilities/AsynchTester.java
(rev 0)
+++
trunk/perfsonar-java-xml-ls/src/test/java/org/perfsonar/tests/utilities/AsynchTester.java
2012-01-24 16:35:01 UTC (rev 5889)
@@ -0,0 +1,45 @@
+package org.perfsonar.tests.utilities;
+
+/**
+ * Asynchronous tester class meant to be run in a threaded testing
environment
+ *
+ * Reports the errors and exceptions up to the parent thread
+ *
+ * @author Antoine Delvaux

+ */
+public class AsynchTester {
+ private Thread thread;
+ private volatile Error error;
+ private volatile RuntimeException runtimeExc;
+
+ public AsynchTester(final Runnable runnable) {
+ thread = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ runnable.run();
+ } catch (Error e) {
+ error = e;
+ } catch (RuntimeException e) {
+ runtimeExc = e;
+ }
+ }
+ });
+ }
+
+ public void start() {
+ thread.start();
+ }
+
+ /**
+ * Wait for the thread to ends before throwing the exceptions
+ * @throws InterruptedException
+ */
+ public void test() throws InterruptedException {
+ thread.join();
+ if (error != null)
+ throw error;
+ if (runtimeExc != null)
+ throw runtimeExc;
+ }
+}


Property changes on:
trunk/perfsonar-java-xml-ls/src/test/java/org/perfsonar/tests/utilities/AsynchTester.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain



  • [pS-dev] [GEANT/SA2/ps-java-services] r5889 - in trunk/perfsonar-java-xml-ls/src: main/java/org/perfsonar/service/lookupservice/components test/java/org/perfsonar/tests/components test/java/org/perfsonar/tests/utilities, svn-noreply, 01/24/2012

Archive powered by MHonArc 2.6.16.

Top of Page