/**
   * Test that the executeWhileTargetAvailale interface works properly for a single operation with a
   * single step when the target is stopped.
   */
  @Test
  public void executeSingleStepSingleOpWhileTargetStopped() throws Throwable {
    // The target is currently stopped.

    // A single step that will set a breakpoint at PrintHello, which we will then make sure hits
    final Step[] steps =
        new Step[] {
          new Step() {
            @Override
            public void execute(RequestMonitor rm) {
              IBreakpointsTargetDMContext bpTargetDmc =
                  DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);

              fGDBCtrl.queueCommand(
                  fGDBCtrl
                      .getCommandFactory()
                      .createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHello", 0),
                  new DataRequestMonitor<MIBreakInsertInfo>(fGDBCtrl.getExecutor(), rm));
            }
          }
        };

    Query<Boolean> query =
        new Query<Boolean>() {
          @Override
          protected void execute(DataRequestMonitor<Boolean> rm) {
            fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
          }
        };
    try {
      fRunCtrl.getExecutor().execute(query);
      query.get(500, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    } catch (ExecutionException e) {
      fail(e.getCause().getMessage());
    } catch (TimeoutException e) {
      fail(TIMEOUT_MESSAGE);
    }

    // Now resume the target and check that we stop at the breakpoint.

    ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor =
        new ServiceEventWaitor<ISuspendedDMEvent>(
            getGDBLaunch().getSession(), ISuspendedDMEvent.class);

    SyncUtil.resume();

    // Wait up to 3 second for the target to suspend. Should happen within 2 second.
    suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
  }
Exemple #2
0
  @Test
  public void compareRegisterForMultipleExecutionContexts() throws Throwable {

    // Run past the line that creates a thread and past the sleep that
    // follows it. This is a bit tricky because the code that creates the
    // thread is conditional depending on environment. Run to the printf
    // before it (which is common), then do step operations over the
    // non-common code (but same number of lines)
    SyncUtil.runToLine(SRC_NAME, Integer.toString(MIRunControlTest.LINE_MAIN_PRINTF));
    SyncUtil.step(StepType.STEP_OVER); // over the printf
    SyncUtil.step(StepType.STEP_OVER); // over the create-thread call
    MIStoppedEvent stoppedEvent =
        SyncUtil.step(
            StepType.STEP_OVER, TestsPlugin.massageTimeout(2000)); // over the one second sleep

    // Get the thread IDs
    final IContainerDMContext containerDmc =
        DMContexts.getAncestorOfType(stoppedEvent.getDMContext(), IContainerDMContext.class);

    final AsyncCompletionWaitor wait = new AsyncCompletionWaitor();
    final DataRequestMonitor<IExecutionDMContext[]> drm =
        new DataRequestMonitor<IExecutionDMContext[]>(fRegService.getExecutor(), null) {
          @Override
          protected void handleCompleted() {
            if (isSuccess()) {
              wait.setReturnInfo(getData());
            }
            wait.waitFinished(getStatus());
          }
        };

    fRegService
        .getExecutor()
        .submit(
            new Runnable() {
              public void run() {
                fRunControl.getExecutionContexts(containerDmc, drm);
              }
            });
    wait.waitUntilDone(TestsPlugin.massageTimeout(5000));
    Assert.assertTrue(wait.getMessage(), wait.isOK());

    IExecutionDMContext[] ctxts = (IExecutionDMContext[]) wait.getReturnInfo();
    wait.waitReset();

    Assert.assertNotNull(ctxts);
    Assert.assertTrue(ctxts.length > 1);

    int tid1 = ((IMIExecutionDMContext) ctxts[0]).getThreadId();
    int tid2 = ((IMIExecutionDMContext) ctxts[1]).getThreadId();

    // Get execution context to thread 2
    IExecutionDMContext execDmc = SyncUtil.createExecutionContext(containerDmc, tid2);
    IFrameDMContext frameDmc2 = SyncUtil.getStackFrame(execDmc, 0);

    String thread2RegVal0 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 0);
    String thread2RegVal1 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 1);
    String thread2RegVal2 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 2);
    String thread2RegVal3 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 3);
    String thread2RegVal4 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 4);
    String thread2RegVal5 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 5);

    // Get execution context to thread 1
    execDmc = SyncUtil.createExecutionContext(containerDmc, tid1);
    IFrameDMContext frameDmc1 = SyncUtil.getStackFrame(execDmc, 0);
    getModelDataForRegisterDataValue(frameDmc1, IFormattedValues.NATURAL_FORMAT, 0);

    // Re-set the execution context to 2 and Fetch from the Cache
    String dupliThread2RegVal0 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 0);
    String dupliThread2RegVal1 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 1);
    String dupliThread2RegVal2 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 2);
    String dupliThread2RegVal3 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 3);
    String dupliThread2RegVal4 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 4);
    String dupliThread2RegVal5 =
        getModelDataForRegisterDataValue(frameDmc2, IFormattedValues.NATURAL_FORMAT, 5);

    // If Values not equal , then context haven't been re-set properly
    assertTrue(
        "Multiple context not working. Execution Context is not reset to 2",
        thread2RegVal0.equals(dupliThread2RegVal0));
    assertTrue(
        "Multiple context not working. Execution Context is not reset to 2",
        thread2RegVal1.equals(dupliThread2RegVal1));
    assertTrue(
        "Multiple context not working. Execution Context is not reset to 2",
        thread2RegVal2.equals(dupliThread2RegVal2));
    assertTrue(
        "Multiple context not working. Execution Context is not reset to 2",
        thread2RegVal3.equals(dupliThread2RegVal3));
    assertTrue(
        "Multiple context not working. Execution Context is not reset to 2",
        thread2RegVal4.equals(dupliThread2RegVal4));
    assertTrue(
        "Multiple context not working. Execution Context is not reset to 2",
        thread2RegVal5.equals(dupliThread2RegVal5));
  }
  /**
   * Test that the executeWhileTargetAvailale interface works properly for concurrent operations
   * with a single step when the target is running.
   */
  @Test
  public void executeSingleStepConcurrentOpWhileTargetRunning() throws Throwable {
    final int NUM_CONCURRENT = 3;

    String[] locations = {"PrintHello", "PrintHi", "PrintBonjour"};
    final Step[][] steps = new Step[NUM_CONCURRENT][1]; // one step for each concurrent operation
    for (int i = 0; i < steps.length; i++) {
      final String location = locations[i];
      steps[i] =
          new Step[] {
            new Step() {
              @Override
              public void execute(RequestMonitor rm) {
                IBreakpointsTargetDMContext bpTargetDmc =
                    DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);

                fGDBCtrl.queueCommand(
                    fGDBCtrl
                        .getCommandFactory()
                        .createMIBreakInsert(bpTargetDmc, true, false, null, 0, location, 0),
                    new DataRequestMonitor<MIBreakInsertInfo>(fGDBCtrl.getExecutor(), rm));
              }
            }
          };
    }

    // The target is currently stopped so we resume it
    ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor =
        new ServiceEventWaitor<ISuspendedDMEvent>(
            getGDBLaunch().getSession(), ISuspendedDMEvent.class);

    SyncUtil.resume();

    Query<Boolean> query =
        new Query<Boolean>() {
          @Override
          protected void execute(final DataRequestMonitor<Boolean> rm) {
            CountingRequestMonitor crm =
                new CountingRequestMonitor(fGDBCtrl.getExecutor(), null) {
                  @Override
                  protected void handleCompleted() {
                    rm.done();
                  };
                };

            int index;
            for (index = 0; index < steps.length; index++) {
              fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps[index], crm);
            }

            crm.setDoneCount(index);
          }
        };
    try {
      fRunCtrl.getExecutor().execute(query);
      query.get(500, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    } catch (ExecutionException e) {
      fail(e.getCause().getMessage());
    } catch (TimeoutException e) {
      fail(TIMEOUT_MESSAGE);
    }

    for (int i = 0; i < steps.length; i++) {
      // Wait up to 3 second for the target to suspend. Should happen within 2 seconds.
      suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));

      // Now resume the target and check that we stop at all the breakpoints.
      suspendedEventWaitor =
          new ServiceEventWaitor<ISuspendedDMEvent>(
              getGDBLaunch().getSession(), ISuspendedDMEvent.class);

      SyncUtil.resume();
    }
  }
  /**
   * Test that the executeWhileTargetAvailale interface works properly for concurrent operations
   * with a single step when the target is running. This tests verifies that we properly handle
   * concurrent operations that are dependent on each other; this means that the second operation
   * needs to complete for the second one to complete.
   */
  @Test
  public void executeSingleStepConcurrentAndDependentOpWhileTargetRunning() throws Throwable {
    final String location = "PrintHello";
    final String location2 = "PrintHi";
    final Step[] steps =
        new Step[] {
          new Step() {
            @Override
            public void execute(final RequestMonitor rm) {
              final IBreakpointsTargetDMContext bpTargetDmc =
                  DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);

              fGDBCtrl.queueCommand(
                  fGDBCtrl
                      .getCommandFactory()
                      .createMIBreakInsert(bpTargetDmc, true, false, null, 0, location, 0),
                  new DataRequestMonitor<MIBreakInsertInfo>(fGDBCtrl.getExecutor(), rm) {
                    @Override
                    protected void handleSuccess() {
                      // Send another such operation and wait for it to complete to mark the
                      // original one as completed
                      fRunCtrl.executeWithTargetAvailable(
                          fContainerDmc,
                          new Step[] {
                            new Step() {
                              @Override
                              public void execute(final RequestMonitor otherRm) {
                                fGDBCtrl.queueCommand(
                                    fGDBCtrl
                                        .getCommandFactory()
                                        .createMIBreakInsert(
                                            bpTargetDmc, true, false, null, 0, location2, 0),
                                    new DataRequestMonitor<MIBreakInsertInfo>(
                                        fGDBCtrl.getExecutor(), otherRm));
                              }
                            }
                          },
                          rm);
                    }
                  });
            }
          }
        };

    // The target is currently stopped so we resume it
    ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor =
        new ServiceEventWaitor<ISuspendedDMEvent>(
            getGDBLaunch().getSession(), ISuspendedDMEvent.class);

    SyncUtil.resume();

    Query<Boolean> query =
        new Query<Boolean>() {
          @Override
          protected void execute(final DataRequestMonitor<Boolean> rm) {
            fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
          }
        };
    try {
      fRunCtrl.getExecutor().execute(query);
      query.get(500, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    } catch (ExecutionException e) {
      fail(e.getCause().getMessage());
    } catch (TimeoutException e) {
      fail(TIMEOUT_MESSAGE);
    }

    for (int i = 0; i < 2; i++) {
      // Wait up to 3 second for the target to suspend. Should happen within 2 seconds.
      suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));

      // Now resume the target and check that we stop at all the breakpoints.
      suspendedEventWaitor =
          new ServiceEventWaitor<ISuspendedDMEvent>(
              getGDBLaunch().getSession(), ISuspendedDMEvent.class);

      SyncUtil.resume();
    }
  }
  /**
   * Test that the executeWhileTargetAvailale interface works properly for a single operation with
   * multiple steps when the target is running and one of the steps fails.
   */
  @Test
  public void executeMultiStepSingleOpWhileTargetRunningWithError() throws Throwable {
    // Multiple steps that will set three temp breakpoints at three different lines
    // We then check that the target will stop three times
    final Step[] steps =
        new Step[] {
          new Step() {
            @Override
            public void execute(RequestMonitor rm) {
              IBreakpointsTargetDMContext bpTargetDmc =
                  DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);

              fGDBCtrl.queueCommand(
                  fGDBCtrl
                      .getCommandFactory()
                      .createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintHello", 0),
                  new DataRequestMonitor<MIBreakInsertInfo>(fGDBCtrl.getExecutor(), rm));
            }
          },
          new Step() {
            @Override
            public void execute(RequestMonitor rm) {
              IBreakpointsTargetDMContext bpTargetDmc =
                  DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);

              fGDBCtrl.queueCommand(
                  fGDBCtrl
                      .getCommandFactory()
                      .createMIBreakInsert(
                          bpTargetDmc, true, false, "invalid condition", 0, "PrintHi", 0),
                  new DataRequestMonitor<MIBreakInsertInfo>(fGDBCtrl.getExecutor(), rm));
            }
          },
          new Step() {
            @Override
            public void execute(RequestMonitor rm) {
              IBreakpointsTargetDMContext bpTargetDmc =
                  DMContexts.getAncestorOfType(fContainerDmc, IBreakpointsTargetDMContext.class);

              fGDBCtrl.queueCommand(
                  fGDBCtrl
                      .getCommandFactory()
                      .createMIBreakInsert(bpTargetDmc, true, false, null, 0, "PrintBonjour", 0),
                  new DataRequestMonitor<MIBreakInsertInfo>(fGDBCtrl.getExecutor(), rm));
            }
          }
        };

    // The target is currently stopped so we resume it
    ServiceEventWaitor<ISuspendedDMEvent> suspendedEventWaitor =
        new ServiceEventWaitor<ISuspendedDMEvent>(
            getGDBLaunch().getSession(), ISuspendedDMEvent.class);

    SyncUtil.resume();

    Query<Boolean> query =
        new Query<Boolean>() {
          @Override
          protected void execute(DataRequestMonitor<Boolean> rm) {
            fRunCtrl.executeWithTargetAvailable(fContainerDmc, steps, rm);
          }
        };

    boolean caughtError = false;
    try {
      fRunCtrl.getExecutor().execute(query);
      query.get(500, TimeUnit.MILLISECONDS);
    } catch (InterruptedException e) {
      fail(e.getMessage());
    } catch (ExecutionException e) {
      caughtError = true;
    } catch (TimeoutException e) {
      fail(TIMEOUT_MESSAGE);
    }

    Assert.assertTrue("Did not catch the error of the step", caughtError);

    // Now make sure the target stop of the first breakpoint
    // Wait up to 3 second for the target to suspend. Should happen within two seconds.
    suspendedEventWaitor.waitForEvent(TestsPlugin.massageTimeout(3000));
  }