@Test
  public void testDoesNotCreateDriverAfterRebind() throws Exception {
    origE = app.createAndManageChild(EntitySpec.create(MyService.class));
    // the entity skips enricher initialization, do it explicitly
    origE.addEnricher(ServiceStateLogic.newEnricherForServiceStateFromProblemsAndUp());

    MyProvisioningLocation origLoc =
        mgmt.getLocationManager()
            .createLocation(
                LocationSpec.create(MyProvisioningLocation.class).displayName("mylocname"));
    app.start(ImmutableList.of(origLoc));
    assertEquals(
        origE.getAttribute(Attributes.SERVICE_STATE_EXPECTED).getState(), Lifecycle.RUNNING);
    EntityTestUtils.assertAttributeEqualsEventually(
        origE, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);

    ServiceStateLogic.setExpectedState(origE, Lifecycle.ON_FIRE);
    EntityTestUtils.assertAttributeEqualsEventually(
        origE, Attributes.SERVICE_STATE_ACTUAL, Lifecycle.ON_FIRE);

    newApp = (TestApplication) rebind();
    MyService newE = (MyService) Iterables.getOnlyElement(newApp.getChildren());
    assertNull(
        newE.getDriver(),
        "driver should not be initialized because entity is in a permanent failure");
  }
  @Test(groups = {"Integration"})
  public void testRedisClusterReplicates() throws Exception {
    final String key = "mykey";
    final String val = "1234567890";

    cluster =
        app.createAndManageChild(
            EntitySpec.create(RedisCluster.class).configure(DynamicCluster.INITIAL_SIZE, 3));
    app.start(ImmutableList.of(loc));

    EntityTestUtils.assertAttributeEqualsEventually(cluster, Startable.SERVICE_UP, true);

    RedisStore master = cluster.getMaster();
    List<RedisSlave> slaves =
        ImmutableList.<RedisSlave>copyOf((Collection) cluster.getSlaves().getMembers());

    assertEquals(slaves.size(), 3);

    JedisSupport viaMaster = new JedisSupport(master);
    viaMaster.writeData(key, val);
    assertEquals(viaMaster.readData(key), val);

    for (RedisSlave slave : slaves) {
      final JedisSupport viaSlave = new JedisSupport(slave);
      Asserts.succeedsEventually(
          new Callable<Void>() {
            @Override
            public Void call() throws Exception {
              assertEquals(viaSlave.readData(key), val);
              return null;
            }
          });
    }

    // Check that stopping slave will not stop anything else
    // (it used to stop master because wasn't supplying port!)
    slaves.get(0).stop();
    EntityTestUtils.assertAttributeEqualsEventually(slaves.get(0), Startable.SERVICE_UP, false);

    assertEquals(master.getAttribute(Startable.SERVICE_UP), Boolean.TRUE);
    for (RedisSlave slave : slaves.subList(1, slaves.size())) {
      assertEquals(slave.getAttribute(Startable.SERVICE_UP), Boolean.TRUE);
    }

    // Check that stopping cluster will stop everything
    cluster.stop();

    EntityTestUtils.assertAttributeEqualsEventually(cluster, Startable.SERVICE_UP, false);
    assertEquals(master.getAttribute(Startable.SERVICE_UP), Boolean.FALSE);
    for (RedisSlave slave : slaves) {
      assertEquals(slave.getAttribute(Startable.SERVICE_UP), Boolean.FALSE);
    }
  }
  @Test
  public void testAggregatingMembersEnricher() throws Exception {
    origApp.start(ImmutableList.of(origLoc));
    origCluster.resize(2);

    origApp.addEnricher(
        Enrichers.builder()
            .aggregating(METRIC1)
            .from(origCluster)
            .fromMembers()
            .computing(StringFunctions.joiner(","))
            .publishing(METRIC2)
            .build());

    TestApplication newApp = rebind();
    DynamicCluster newCluster =
        (DynamicCluster)
            Iterables.find(newApp.getChildren(), Predicates.instanceOf(DynamicCluster.class));

    int i = 1;
    for (Entity member : newCluster.getMembers()) {
      ((EntityInternal) member).setAttribute(METRIC1, "myval" + (i++));
    }
    EntityTestUtils.assertAttributeEventually(
        newApp,
        METRIC2,
        Predicates.or(Predicates.equalTo("myval1,myval2"), Predicates.equalTo("myval2,myval1")));
  }
  /** Test that an AMQP client can connect to and use the broker. */
  @Test(groups = {"Integration", "WIP"})
  public void testClientConnection() throws Exception {
    rabbit = app.createAndManageChild(EntitySpec.create(RabbitBroker.class));
    rabbit.start(ImmutableList.of(testLocation));
    EntityTestUtils.assertAttributeEqualsEventually(rabbit, Startable.SERVICE_UP, true);

    byte[] content = "MessageBody".getBytes(Charsets.UTF_8);
    String queue = "queueName";
    Channel producer = null;
    Channel consumer = null;
    try {
      producer = getAmqpChannel(rabbit);
      consumer = getAmqpChannel(rabbit);

      producer.queueDeclare(queue, true, false, false, ImmutableMap.<String, Object>of());
      producer.queueBind(queue, AmqpExchange.DIRECT, queue);
      producer.basicPublish(AmqpExchange.DIRECT, queue, null, content);

      QueueingConsumer queueConsumer = new QueueingConsumer(consumer);
      consumer.basicConsume(queue, true, queueConsumer);

      QueueingConsumer.Delivery delivery =
          queueConsumer.nextDelivery(60 * 1000l); // one minute timeout
      assertEquals(delivery.getBody(), content);
    } finally {
      closeSafely(producer, 10 * 1000);
      closeSafely(consumer, 10 * 1000);
    }
  }
 /** Test that the broker starts up and sets SERVICE_UP correctly. */
 @Test(groups = {"Integration", "WIP"})
 public void canStartupAndShutdown() throws Exception {
   rabbit = app.createAndManageChild(EntitySpec.create(RabbitBroker.class));
   rabbit.start(ImmutableList.of(testLocation));
   EntityTestUtils.assertAttributeEqualsEventually(rabbit, Startable.SERVICE_UP, true);
   rabbit.stop();
   assertFalse(rabbit.getAttribute(Startable.SERVICE_UP));
 }
  @Override
  protected void doTest(Location loc) throws Exception {
    RiakNode entity =
        app.createAndManageChild(
            EntitySpec.create(RiakNode.class).configure(RiakNode.SUGGESTED_VERSION, "2.1.1"));
    app.start(ImmutableList.of(loc));

    EntityTestUtils.assertAttributeEqualsEventually(entity, RiakNode.SERVICE_UP, true);
  }
  @Test
  public void testPropagatingEnricher() throws Exception {
    origApp.addEnricher(Enrichers.builder().propagating(METRIC1).from(origEntity).build());

    TestApplication newApp = rebind();
    TestEntity newEntity =
        (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));

    newEntity.setAttribute(METRIC1, "myval");
    EntityTestUtils.assertAttributeEqualsEventually(newApp, METRIC1, "myval");
  }
  @Test(groups = {"Integration"})
  public void testRebindMongoDb() throws Exception {
    MongoDBServer origEntity =
        origApp.createAndManageChild(
            EntitySpec.create(MongoDBServer.class)
                .configure("mongodbConfTemplateUrl", "classpath:///test-mongodb.conf"));
    origApp.start(ImmutableList.of(loc));
    EntityTestUtils.assertAttributeEventuallyNonNull(origEntity, MongoDBServer.STATUS_BSON);

    // rebind
    rebind();
    final MongoDBServer newEntity =
        (MongoDBServer)
            Iterables.find(newApp.getChildren(), Predicates.instanceOf(MongoDBServer.class));

    // confirm effectors still work on entity
    EntityTestUtils.assertAttributeEqualsEventually(newEntity, MongoDBServer.SERVICE_UP, true);
    newEntity.stop();
    EntityTestUtils.assertAttributeEqualsEventually(newEntity, MongoDBServer.SERVICE_UP, false);
  }
  @SuppressWarnings("unchecked")
  @Test
  public void testCombiningEnricher() throws Exception {
    origApp.addEnricher(
        Enrichers.builder()
            .combining(METRIC1, METRIC2)
            .from(origEntity)
            .computing(StringFunctions.joiner(","))
            .publishing(METRIC2)
            .build());

    TestApplication newApp = rebind();
    TestEntity newEntity =
        (TestEntity) Iterables.find(newApp.getChildren(), Predicates.instanceOf(TestEntity.class));

    newEntity.setAttribute(METRIC1, "myval");
    newEntity.setAttribute(METRIC2, "myval2");
    EntityTestUtils.assertAttributeEventually(
        newApp,
        METRIC2,
        Predicates.or(Predicates.equalTo("myval,myval2"), Predicates.equalTo("myval2,myval")));
  }
  protected void runStopProcessAndRestart(Effector<?> restartEffector, Map<String, ?> args)
      throws Exception {
    LocalhostMachineProvisioningLocation loc = app.newLocalhostProvisioningLocation();
    SoftwareProcess entity = app.createAndManageChild(newEntitySpec());

    // Start the app
    app.start(ImmutableList.of(loc));
    EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_UP, true);
    EntityTestUtils.assertAttributeEqualsEventually(app, SoftwareProcess.SERVICE_UP, true);

    // Stop the process
    Entities.invokeEffector(
            app,
            entity,
            SoftwareProcess.STOP,
            ImmutableMap.of(
                StopSoftwareParameters.STOP_MACHINE_MODE.getName(),
                StopSoftwareParameters.StopMode.NEVER))
        .get();
    EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_UP, false);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, SoftwareProcess.SERVICE_STATE_ACTUAL, Lifecycle.STOPPED);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, SoftwareProcess.SERVICE_PROCESS_IS_RUNNING, false);
    EntityTestUtils.assertAttributeEventually(
        entity,
        ServiceStateLogic.SERVICE_NOT_UP_INDICATORS,
        CollectionFunctionals.<String>mapSizeEquals(1));

    // Restart the process
    Entities.invokeEffector(app, entity, restartEffector, args).get();
    EntityTestUtils.assertAttributeEqualsEventually(entity, SoftwareProcess.SERVICE_UP, true);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, SoftwareProcess.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, SoftwareProcess.SERVICE_PROCESS_IS_RUNNING, true);
    EntityTestUtils.assertAttributeEqualsEventually(
        entity, ServiceStateLogic.SERVICE_NOT_UP_INDICATORS, ImmutableMap.<String, Object>of());

    EntityTestUtils.assertAttributeEqualsEventually(app, SoftwareProcess.SERVICE_UP, true);
    EntityTestUtils.assertAttributeEqualsEventually(
        app, SoftwareProcess.SERVICE_STATE_ACTUAL, Lifecycle.RUNNING);
  }