This is the mail archive of the frysk@sourceware.org mailing list for the frysk project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

TestLib assertStatState()


Hi,

While testing on different machines/kernels I noticed some spurious
failures resulting from (short) busy-waiting for a /proc/tid/state
change in some tests. I added a new TestLib helper method to do the same
thing but using the normal test case timeout values and made it do a
short sleep instead of having a tight busy-wait loop.

frysk-core/frysk/testbed/ChangeLog
2007-08-15  Mark Wielaard  <mwielaard@redhat.com>

    * TestLib.java (assertStatState): New static method.
    * LegacyOffspring.java (assertSendStop): Use TestLib
    assertStatState().
    * SlaveOffspring.java (assertSendStop): Likewise.

frysk-core/frysk/proc/ChangeLog
2007-08-15  Mark Wielaard  <mwielaard@redhat.com>

    * TestTaskObserverDetach.java (assertDetach): Use TestLib
    assertStatState().

Please use this method in the future when writing tests that depend on
Stat state change detection.

Cheers,

Mark
Index: frysk-core/frysk/proc/TestTaskObserverDetach.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/proc/TestTaskObserverDetach.java,v
retrieving revision 1.22
diff -u -r1.22 TestTaskObserverDetach.java
--- frysk-core/frysk/proc/TestTaskObserverDetach.java	9 Aug 2007 18:12:09 -0000	1.22
+++ frysk-core/frysk/proc/TestTaskObserverDetach.java	15 Aug 2007 08:00:50 -0000
@@ -41,8 +41,6 @@
 
 import frysk.event.RequestStopEvent;
 import frysk.sys.Sig;
-import frysk.sys.proc.Stat;
-import java.lang.Thread;
 import java.util.Observable;
 import java.util.Observer;
 import java.util.logging.Level;
@@ -121,24 +119,7 @@
 	    if (!eventIsSignal ())
 		assertRunUntilStop ("delivering signal");
 	    
-	    // Poll until process goes into T state (indicating
-	    // pending trace event); horrible race condition here.
-	    // Can't use the event loop as that would detect, and soak
-	    // up the event that is ment to be left sitting in the
-	    // event loop.
-	    Stat stat = new Stat ();
-	    for (int i = 0; i < 100; i++) {
-		assertTrue ("stat refresh", stat.refresh (task.getTid ()));
-		if (stat.state == 'T')
-		    break;
-		try {
-		    Thread.sleep (50); // milliseconds.
-		}
-		catch (Exception e) {
-		    fail (e.toString ());
-		}
-	    }
-	    assertEquals ("stat.state", 'T', stat.state);
+	    assertStatState(task.getTid(), 'T');
 	    
 	    // Set up an ack handler to catch the process
 	    // acknowledging that it has completed the relevant task.
Index: frysk-core/frysk/testbed/LegacyOffspring.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/testbed/LegacyOffspring.java,v
retrieving revision 1.1
diff -u -r1.1 LegacyOffspring.java
--- frysk-core/frysk/testbed/LegacyOffspring.java	10 Aug 2007 02:53:17 -0000	1.1
+++ frysk-core/frysk/testbed/LegacyOffspring.java	15 Aug 2007 08:00:50 -0000
@@ -44,7 +44,6 @@
 import frysk.sys.Pid;
 import frysk.sys.Sig;
 import frysk.sys.Signal;
-import frysk.sys.proc.Stat;
 import frysk.testbed.SignalWaiter;
 import java.util.LinkedList;
 import java.util.List;
@@ -233,17 +232,7 @@
      */
     public void assertSendStop () {
 	signal(STOP_SIG);
-
-	Stat stat = new Stat();
-	stat.refresh(this.getPid());
-	for (int i = 0; i < 10; i++) {
-	    if (stat.state == 'T')
-		return;
-	    Thread.yield();
-	    stat.refresh();
-	}
-	TestCase.fail("Stop signal not handled by process, in state: "
-		      + stat.state);
+	TestLib.assertStatState(this.getPid(), 'T');
     }
 
     /**
Index: frysk-core/frysk/testbed/SlaveOffspring.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/testbed/SlaveOffspring.java,v
retrieving revision 1.11
diff -u -r1.11 SlaveOffspring.java
--- frysk-core/frysk/testbed/SlaveOffspring.java	10 Aug 2007 03:09:16 -0000	1.11
+++ frysk-core/frysk/testbed/SlaveOffspring.java	15 Aug 2007 08:00:50 -0000
@@ -44,7 +44,6 @@
 import frysk.sys.Pid;
 import frysk.sys.Sig;
 import frysk.sys.Signal;
-import frysk.sys.proc.Stat;
 import frysk.testbed.SignalWaiter;
 import java.util.LinkedList;
 import java.util.List;
@@ -236,17 +235,7 @@
      */
     public void assertSendStop () {
 	signal(STOP_SIG);
-
-	Stat stat = new Stat();
-	stat.refresh(this.getPid());
-	for (int i = 0; i < 10; i++) {
-	    if (stat.state == 'T')
-		return;
-	    Thread.yield();
-	    stat.refresh();
-	}
-	TestCase.fail("Stop signal not handled by process, in state: "
-		      + stat.state);
+	TestLib.assertStatState(this.getPid(), 'T');
     }
 
     /**
Index: frysk-core/frysk/testbed/TestLib.java
===================================================================
RCS file: /cvs/frysk/frysk-core/frysk/testbed/TestLib.java,v
retrieving revision 1.36
diff -u -r1.36 TestLib.java
--- frysk-core/frysk/testbed/TestLib.java	9 Aug 2007 18:32:44 -0000	1.36
+++ frysk-core/frysk/testbed/TestLib.java	15 Aug 2007 08:00:50 -0000
@@ -104,6 +104,42 @@
 	assertRunUntilStop(getTimeoutSeconds (), reason);
     }
 
+  /**
+   * Asserts that the State of the given tid turns to the given state,
+   * 'R' running, 'S' sleeping (interruptible), 'D' waiting/disk
+   * (uninterruptible), 'Z' zombie, 'T' traced or stopped or 'W'
+   * paging, in the current timeout.
+   */
+  public static void assertStatState(int tid, char state)
+  {
+    long timeout = getTimeoutMilliseconds();
+    Stat stat = new Stat();
+    stat.refresh(tid);
+    while (timeout > 0)
+      {
+	if (stat.state == state)
+	  return;
+	
+	long startsleep = System.currentTimeMillis();
+	try
+	  {
+	    Thread.sleep(100);
+	  }
+	catch (InterruptedException ie)
+	  {
+	    /* ignore */
+	  }
+
+	long now = System.currentTimeMillis();
+	timeout = timeout - (now - startsleep);
+
+	stat.refresh();
+      }
+
+    TestCase.fail("Stat state for tid " + tid + " expected '"
+		  + state + "' but was '" + stat.state + "'");
+  }
+
     /**
      * Process all the pending events; no polling of external events
      * is performed.  XXX: Static to avoid gcc bugs.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]