@Test(enabled = true, dependsOnMethods = "testTemplateMatch")
  public void testCreateTwoNodesWithRunScript() throws Exception {
    try {
      client.destroyNodesMatching(NodePredicates.withTag(tag));
    } catch (HttpResponseException e) {
      // TODO hosting.com throws 400 when we try to delete a vApp
    } catch (NoSuchElementException e) {

    }
    template = buildTemplate(client.templateBuilder());

    template
        .getOptions()
        .installPrivateKey(keyPair.get("private"))
        .authorizePublicKey(keyPair.get("public"))
        .runScript(buildScript(template.getImage().getOsFamily()).getBytes());
    try {
      nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 2, template));
    } catch (RunNodesException e) {
      nodes = Sets.newTreeSet(Iterables.concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet()));
      throw e;
    }
    assertEquals(nodes.size(), 2);
    checkNodes(nodes, tag);
    NodeMetadata node1 = nodes.first();
    NodeMetadata node2 = nodes.last();
    // credentials aren't always the same
    // assertEquals(node1.getCredentials(), node2.getCredentials());

    assertLocationSameOrChild(node1.getLocation(), template.getLocation());
    assertLocationSameOrChild(node2.getLocation(), template.getLocation());

    assertEquals(node1.getImage(), template.getImage());
    assertEquals(node2.getImage(), template.getImage());
  }
  // since surefire and eclipse don't otherwise guarantee the order, we are
  // starting this one alphabetically before create2nodes..
  @Test(enabled = true, dependsOnMethods = "testImagesCache")
  public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
    String tag = this.tag + "run";
    try {
      client.destroyNodesMatching(NodePredicates.withTag(tag));
    } catch (Exception e) {

    }

    TemplateOptions options = client.templateOptions().blockOnPort(22, 120);
    try {
      Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
      Credentials good = nodes.iterator().next().getCredentials();
      assert good.account != null;
      assert good.key != null;

      Image image = Iterables.get(nodes, 0).getImage();
      try {
        Map<? extends NodeMetadata, ExecResponse> responses =
            runScriptWithCreds(tag, image.getOsFamily(), new Credentials(good.account, "romeo"));
        assert false : "shouldn't pass with a bad password\n" + responses;
      } catch (RunScriptOnNodesException e) {
        assert Throwables.getRootCause(e).getMessage().contains("Auth fail") : e;
      }

      runScriptWithCreds(tag, image.getOsFamily(), good);

      checkNodes(nodes, tag);

    } finally {
      client.destroyNodesMatching(NodePredicates.withTag(tag));
    }
  }
  @Test(enabled = true)
  public void testCreateAndRunAService() throws Exception {

    String tag = this.tag + "service";
    try {
      client.destroyNodesMatching(withTag(tag));
    } catch (Exception e) {

    }

    template =
        client
            .templateBuilder()
            .options(blockOnComplete(false).blockOnPort(8080, 600).inboundPorts(22, 8080))
            .build();
    // note this is a dependency on the template resolution
    template
        .getOptions()
        .runScript(
            RunScriptData.createScriptInstallAndStartJBoss(
                keyPair.get("public"), template.getImage().getOperatingSystem()));
    try {
      NodeMetadata node = getOnlyElement(client.runNodesWithTag(tag, 1, template));

      checkHttpGet(node);
    } finally {
      client.destroyNodesMatching(withTag(tag));
    }
  }
  @Test(enabled = true, dependsOnMethods = "testCompareSizes")
  public void testCreateTwoNodesWithRunScript() throws Exception {
    try {
      client.destroyNodesMatching(withTag(tag));
    } catch (NoSuchElementException e) {

    }
    refreshTemplate();
    try {
      nodes = newTreeSet(client.runNodesWithTag(tag, 2, template));
    } catch (RunNodesException e) {
      nodes = newTreeSet(concat(e.getSuccessfulNodes(), e.getNodeErrors().keySet()));
      throw e;
    }
    assertEquals(nodes.size(), 2);
    checkNodes(nodes, tag);
    NodeMetadata node1 = nodes.first();
    NodeMetadata node2 = nodes.last();
    // credentials aren't always the same
    // assertEquals(node1.getCredentials(), node2.getCredentials());

    assertLocationSameOrChild(node1.getLocation(), template.getLocation());
    assertLocationSameOrChild(node2.getLocation(), template.getLocation());
    checkImageIdMatchesTemplate(node1);
    checkImageIdMatchesTemplate(node2);
    checkOsMatchesTemplate(node1);
    checkOsMatchesTemplate(node2);
  }
  // since surefire and eclipse don't otherwise guarantee the order, we are
  // starting this one alphabetically before create2nodes..
  @Test(
      enabled = true,
      dependsOnMethods = {"testCompareSizes"})
  public void testAScriptExecutionAfterBootWithBasicTemplate() throws Exception {
    String tag = this.tag + "run";
    try {
      client.destroyNodesMatching(withTag(tag));
    } catch (Exception e) {

    }

    TemplateOptions options = client.templateOptions().blockOnPort(22, 120);
    try {
      Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
      Credentials good = nodes.iterator().next().getCredentials();
      assert good.identity != null : nodes;
      assert good.credential != null : nodes;

      OperatingSystem os = get(nodes, 0).getOperatingSystem();
      try {
        Map<? extends NodeMetadata, ExecResponse> responses =
            runScriptWithCreds(tag, os, new Credentials(good.identity, "romeo"));
        assert false : "shouldn't pass with a bad password\n" + responses;
      } catch (RunScriptOnNodesException e) {
        assert getRootCause(e).getMessage().contains("Auth fail") : e;
      }

      runScriptWithCreds(tag, os, good);

      checkNodes(nodes, tag);

    } finally {
      client.destroyNodesMatching(withTag(tag));
    }
  }
 @Test(enabled = true, dependsOnMethods = "testCreateTwoNodesWithRunScript")
 public void testCreateAnotherNodeWithANewContextToEnsureSharedMemIsntRequired() throws Exception {
   initializeContextAndClient();
   TreeSet<NodeMetadata> nodes = Sets.newTreeSet(client.runNodesWithTag(tag, 1, template));
   checkNodes(nodes, tag);
   NodeMetadata node = nodes.first();
   this.nodes.add(node);
   assertEquals(nodes.size(), 1);
   assertLocationSameOrChild(node.getLocation(), template.getLocation());
   assertEquals(node.getImage(), template.getImage());
 }
  public void testOptionToNotBlock() throws Exception {
    String tag = this.tag + "block";
    try {
      client.destroyNodesMatching(withTag(tag));
    } catch (Exception e) {

    }
    // no inbound ports
    TemplateOptions options = client.templateOptions().blockUntilRunning(false).inboundPorts();
    try {
      long time = System.currentTimeMillis();
      Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
      NodeMetadata node = getOnlyElement(nodes);
      assert node.getState() != NodeState.RUNNING;
      long duration = System.currentTimeMillis() - time;
      assert duration < 30 * 1000 : "duration longer than 30 seconds!:  " + duration / 1000;
    } finally {
      client.destroyNodesMatching(withTag(tag));
    }
  }
  @Test(enabled = true, dependsOnMethods = "testGet")
  public void testOptionToNotBlock() throws Exception {
    String tag = this.tag + "block";
    try {
      client.destroyNodesMatching(NodePredicates.withTag(tag));
    } catch (Exception e) {

    }
    // no inbound ports
    TemplateOptions options = client.templateOptions().blockUntilRunning(false).inboundPorts();
    try {
      long time = System.currentTimeMillis();
      Set<? extends NodeMetadata> nodes = client.runNodesWithTag(tag, 1, options);
      NodeMetadata node = Iterables.getOnlyElement(nodes);
      assertEquals(node.getState(), NodeState.PENDING);

      long duration = System.currentTimeMillis() - time;
      assert duration < 30 * 1000 : "duration longer than 30 seconds!:  " + duration / 1000;
    } finally {
      client.destroyNodesMatching(NodePredicates.withTag(tag));
    }
  }