SRADA-395: added new unit test for TracingProcessManager
authorVladislav Eliseev <v.eliseev@samsung.com>
Mon, 23 May 2016 18:21:23 +0000 (21:21 +0300)
committerMaria Guseva <m.guseva@samsung.com>
Fri, 1 Jul 2016 03:58:24 +0000 (06:58 +0300)
This test check situation when forceStopTracing is called
from one thread while another thread is blocked by
TracingProcessManager#stopTracing(long) call.

Change-Id: I4755a007ea271fdaf9d165a5df5910061defed89

org.tizen.dynamicanalyzer.cli/test/src/org/tizen/dynamicanalyzer/cli/manager/TracingProcessManagerTest.java

index c054c4c..90da018 100644 (file)
@@ -11,6 +11,8 @@ import static org.mockito.Mockito.when;
 import java.io.OutputStream;
 import java.lang.reflect.Constructor;
 import java.util.Date;
+import java.util.concurrent.Callable;
+import java.util.concurrent.FutureTask;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -326,4 +328,87 @@ public class TracingProcessManagerTest {
                // verify that manager didn't try to stop process in that case (stopped already)
                verifyNoMoreInteractions(oStream);
        }
+
+       /**
+        * Guarded variable used in {@link #forceStopTracing_async()} test.
+        */
+       volatile boolean pass;
+       final Object passLock = new Object();
+
+       /**
+        * Whitebox test of manager ability to correctly send destroy signal to
+        * the underlying process and correctly process case where there are another
+        * completion waiters at the moment.
+        */
+       @Test(timeout=2*TIMEOUT_MS)
+       public void forceStopTracing_async() throws Exception {
+               // setup guarded variable
+               pass = false;
+
+               // setup mocks
+               // btw, we should ignore normal stopTracing signal
+               doAnswer(new Answer<Integer>() {
+                       @Override
+                       public Integer answer(InvocationOnMock invocation) throws Throwable {
+                               // block while pass != true or interruption occurred
+                               if (!pass) {
+                                       synchronized (passLock) {
+                                               while (!pass && !Thread.currentThread().isInterrupted())
+                                                       passLock.wait();
+
+                                       }
+
+                                       // emulate waitFor behavior
+                                       if (Thread.currentThread().isInterrupted())
+                                               throw new InterruptedException();
+                               }
+                               return 100500;
+                       }
+               }).when(process).waitFor();
+
+               doAnswer(new Answer<Object>() {
+                       @Override
+                       public Object answer(InvocationOnMock invocation) throws Throwable {
+                               // unlock waiters
+                               synchronized (passLock) {
+                                       pass = true;
+                                       passLock.notifyAll();
+                               }
+                               return null;
+                       }
+               }).when(process).destroy();
+
+               // create class under test
+               manager = managerConstructor.newInstance(args, process);
+
+               // call stopTracing in separate thread
+               FutureTask<Boolean> stopTask = new FutureTask<>(new Callable<Boolean>() {
+                       @Override
+                       public Boolean call() throws Exception {
+                               // this call should block until timeout passed or forceStop will be called
+                               try {
+                                       return manager.stopTracing(3*TIMEOUT_MS);
+                               } catch (InterruptedException e) {
+                                       return null;
+                               }
+                       }
+               });
+
+               Thread stopThread = new Thread(stopTask);
+               stopThread.start();
+
+               // to ensure that stopTracing(timeout) was called
+               Thread.sleep(TIMEOUT_MS);
+
+               // while stop thread still running send force stop tracing signal
+               assertTrue(stopThread.isAlive());
+               manager.forceStopTracing();
+
+               // assert that stopTracing(timeout) correctly processed
+               //  asynchronous forceStopTracing signal
+               Boolean stopTaskResult = stopTask.get();
+
+               // result of stopTracing(timeout) should be true if process stopped during this period
+               assertTrue(stopTaskResult);
+       }
 }