@Test(groups = {"Integration", "Acceptance"})
  public void testInvokeEffector() {
    int numIterations = numIterations();
    double minRatePerSec = 1000 * PERFORMANCE_EXPECTATION;

    measure(
        PerformanceTestDescriptor.create()
            .summary("EntityPerformanceTest.testInvokeEffector")
            .iterations(numIterations)
            .minAcceptablePerSecond(minRatePerSec)
            .job(
                new Runnable() {
                  public void run() {
                    entity.myEffector();
                  }
                }));
  }
  @Test(groups = {"Integration", "Acceptance"})
  public void testUpdateAttributeWhenNoListeners() {
    int numIterations = numIterations();
    double minRatePerSec = 1000 * PERFORMANCE_EXPECTATION;
    final AtomicInteger i = new AtomicInteger();

    measure(
        PerformanceTestDescriptor.create()
            .summary("EntityPerformanceTest.testUpdateAttributeWhenNoListeners")
            .iterations(numIterations)
            .minAcceptablePerSecond(minRatePerSec)
            .job(
                new Runnable() {
                  public void run() {
                    entity.sensors().set(TestEntity.SEQUENCE, i.getAndIncrement());
                  }
                }));
  }
  @Test(groups = {"Integration", "Acceptance"})
  public void testUpdateAttributeWithNoopListeners() {
    final int numIterations = numIterations();
    double minRatePerSec = 1000 * PERFORMANCE_EXPECTATION;
    final AtomicInteger i = new AtomicInteger();
    final AtomicInteger lastVal = new AtomicInteger();

    app.subscriptions()
        .subscribe(
            entity,
            TestEntity.SEQUENCE,
            new SensorEventListener<Integer>() {
              @Override
              public void onEvent(SensorEvent<Integer> event) {
                lastVal.set(event.getValue());
              }
            });

    measure(
        PerformanceTestDescriptor.create()
            .summary("EntityPerformanceTest.testUpdateAttributeWithNoopListeners")
            .iterations(numIterations)
            .minAcceptablePerSecond(minRatePerSec)
            .job(
                new Runnable() {
                  public void run() {
                    entity.sensors().set(TestEntity.SEQUENCE, (i.getAndIncrement()));
                  }
                }));

    Asserts.succeedsEventually(
        MutableMap.of("timeout", TIMEOUT_MS),
        new Runnable() {
          public void run() {
            assertTrue(
                lastVal.get() >= numIterations,
                "lastVal=" + lastVal + "; numIterations=" + numIterations);
          }
        });
  }
  @Test(groups = {"Integration", "Acceptance"})
  public void testMultiEntityConcurrentEffectorInvocation() {
    int numIterations = numIterations();
    double minRatePerSec =
        100 * PERFORMANCE_EXPECTATION; // i.e. 1000 invocations (because 10 entities per time)

    measure(
        PerformanceTestDescriptor.create()
            .summary("EntityPerformanceTest.testMultiEntityConcurrentEffectorInvocation")
            .iterations(numIterations)
            .minAcceptablePerSecond(minRatePerSec)
            .job(
                new Runnable() {
                  public void run() {
                    Task<?> task = Entities.invokeEffector(app, entities, TestEntity.MY_EFFECTOR);
                    try {
                      task.get();
                    } catch (Exception e) {
                      throw Exceptions.propagate(e);
                    }
                  }
                }));
  }
  @Test(groups = {"Integration", "Acceptance"})
  public void testAsyncEffectorInvocation() {
    int numIterations = numIterations();
    double minRatePerSec = 1000 * PERFORMANCE_EXPECTATION;

    measure(
        PerformanceTestDescriptor.create()
            .summary("EntityPerformanceTest.testAsyncEffectorInvocation")
            .iterations(numIterations)
            .minAcceptablePerSecond(minRatePerSec)
            .job(
                new Runnable() {
                  public void run() {
                    Task<?> task =
                        entity.invoke(TestEntity.MY_EFFECTOR, MutableMap.<String, Object>of());
                    try {
                      task.get();
                    } catch (Exception e) {
                      throw Exceptions.propagate(e);
                    }
                  }
                }));
  }