import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
private TracingProcessContext ctx2;
+ private final static String DEV_1 = "DEV_1";
+
+ /**
+ * Whitebox constant from {@link ProcessManager#TRACING_PROCESS_STOP_TIMEOUT}.
+ */
+ private final static long BASE_TIMEOUT_MS = 2000;
+
@Before
public void setUp() {
args1 = new TracingArguments().
- setDevice("DEV_1").
+ setDevice(DEV_1).
setApplication("APP_1").
setTemplate(Template.TEMPLATE_BOTTLENECK).
setDuration(0);
},
pm.getTracedDevices());
}
+
+ /**
+ * Variable used in next multiple test cases.
+ */
+ volatile int call_counter;
+
+ /**
+ * Check manager ability to stop tracing process.
+ */
+ @Test
+ public void stopTracing_success() throws Exception {
+ // firstly start process
+ startTracing_success();
+
+ call_counter = 0;
+
+ // setup answer on stop signal that finalizes tracing context
+ Answer<Boolean> finalizeContext = new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ call_counter++;
+ ctx1.finishContext(100500);
+ return true;
+ }
+ };
+
+ // set answer on any of stop tracing API calls
+ // because in blackbox we don't know exactly which API method will be used
+ doAnswer(finalizeContext).when(mgr1).stopTracing();
+ doAnswer(finalizeContext).when(mgr1).stopTracing(Mockito.anyLong());
+
+ // ask to stop
+ DAResult result = pm.stopTracing(DEV_1);
+
+ // check result
+ assertEquals(ErrorCode.SUCCESS.getErrorNumber(), result.getErrorNumber());
+ assertEquals(1, call_counter);
+ }
+
+ /**
+ * Check manager returns valid code when process is not running.
+ */
+ @Test
+ public void stopTracing_not_running() throws Exception {
+ // firstly start process
+ startTracing_success();
+
+ ctx1.finishContext(100500);
+ when(mgr1.isFinished()).thenReturn(true);
+
+ DAResult result = pm.stopTracing(DEV_1);
+
+ // check result
+ assertEquals(ErrorCode.ERR_TRACING_NOT_RUNNING.getErrorNumber(), result.getErrorNumber());
+
+ verify(mgr1, never()).stopTracing();
+ verify(mgr1, never()).stopTracing(Mockito.anyLong());
+ }
+
+ /**
+ * Whitebox test of manager ability to forcibly stop tracing process.
+ * Test checks that process manager doesn't allow situation when stop tracing request
+ * entails blocking of some threads for an indefinite time.
+ * This test relies on {@link ProcessManager#TRACING_PROCESS_STOP_TIMEOUT} value.
+ */
+ @Test(timeout = 2*BASE_TIMEOUT_MS)
+ public void whitebox_stopTracing_timeout() throws Exception {
+ // firstly start process
+ startTracing_success();
+
+ call_counter = 0;
+
+ // answer that will return stop failure signal (false)
+ Answer<Boolean> failAnswer = new Answer<Boolean>() {
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ assertEquals(BASE_TIMEOUT_MS, invocation.getArgumentAt(0, Long.class).longValue());
+ Thread.sleep(BASE_TIMEOUT_MS);
+ call_counter++;
+ return false;
+ }
+ };
+
+ // answer that cause test termination by timeout
+ Answer<Object> timeoutAnswer = new Answer<Object>() {
+ @Override
+ public Object answer(InvocationOnMock invocation) throws Throwable {
+ call_counter++;
+ Thread.sleep(3*BASE_TIMEOUT_MS);
+ return null;
+ }
+ };
+
+ /**
+ * We don't know exactly which API method will be used, therefore:
+ * 1) we can check case if manager will use blocking stopTracing() method
+ * and filter it out by forcibly cause timeout for whole test case
+ * 2) fail stopTracing(long) method in order to imply forceStopTracing() usage.
+ */
+ doAnswer(failAnswer).when(mgr1).stopTracing(Mockito.anyLong());
+ doAnswer(timeoutAnswer).when(mgr1).stopTracing();
+
+ // ask to stop...
+ DAResult result = pm.stopTracing(DEV_1);
+
+ // check result
+ assertEquals(ErrorCode.ERR_EXCEPTION_OCCURRED.getErrorNumber(), result.getErrorNumber());
+
+ // check that only one stop call was used
+ assertEquals(1, call_counter);
+
+ // check that force stop tracing was requested
+ verify(mgr1).forceStopTracing();
+ }
}