/**
   * @throws RunScriptOnNodesException
   * @throws IllegalStateException If do not find exactly one matching node
   * @deprecated since 0.7
   */
  @Deprecated
  public static ExecResponse runScriptOnNode(
      ComputeService computeService, NodeMetadata node, Statement statement, String scriptName)
      throws RunScriptOnNodesException {
    // TODO Includes workaround for NodeMetadata's equals/hashcode method being wrong.

    Map<? extends NodeMetadata, ExecResponse> scriptResults =
        computeService.runScriptOnNodesMatching(
            JcloudsUtil.predicateMatchingById(node),
            statement,
            new RunScriptOptions().nameTask(scriptName));
    if (scriptResults.isEmpty()) {
      throw new IllegalStateException(
          "No matching node found when executing script " + scriptName + ": expected=" + node);
    } else if (scriptResults.size() > 1) {
      throw new IllegalStateException(
          "Multiple nodes matched predicate: id="
              + node.getId()
              + "; expected="
              + node
              + "; actual="
              + scriptResults.keySet());
    } else {
      return Iterables.getOnlyElement(scriptResults.values());
    }
  }
 protected Map<? extends NodeMetadata, ExecResponse> runScriptWithCreds(
     final String group, OperatingSystem os, LoginCredentials creds)
     throws RunScriptOnNodesException {
   return client.runScriptOnNodesMatching(
       runningInGroup(group),
       InstallJDK.fromOpenJDK(),
       overrideLoginCredentials(creds).nameTask("runScriptWithCreds"));
 }
 @Test(enabled = false)
 protected void tryBadPassword(String group, Credentials good) throws AssertionError {
   try {
     Map<? extends NodeMetadata, ExecResponse> responses =
         client.runScriptOnNodesMatching(
             runningInGroup(group),
             "echo I put a bad password",
             wrapInInitScript(false)
                 .runAsRoot(false)
                 .overrideLoginCredentials(
                     LoginCredentials.builder()
                         .user(good.identity)
                         .noPrivateKey()
                         .password("romeo")
                         .build()));
     assert responses.size() == 0 : "shouldn't pass with a bad password\n" + responses;
   } catch (AssertionError e) {
     throw e;
   } catch (RunScriptOnNodesException e) {
     assert Iterables.any(
             e.getNodeErrors().values(), Predicates.instanceOf(AuthorizationException.class))
         : e + " not authexception!";
   }
 }
  // 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 group = this.group + "r";
    try {
      client.destroyNodesMatching(inGroup(group));
    } catch (Exception e) {

    }
    template = buildTemplate(client.templateBuilder());
    template.getOptions().blockOnPort(22, 120);
    try {
      Set<? extends NodeMetadata> nodes = client.createNodesInGroup(group, 1, template);
      NodeMetadata node = get(nodes, 0);
      LoginCredentials good = node.getCredentials();
      assert good.identity != null : nodes;

      for (Entry<? extends NodeMetadata, ExecResponse> response :
          client
              .runScriptOnNodesMatching(
                  runningInGroup(group),
                  "hostname",
                  wrapInInitScript(false).runAsRoot(false).overrideLoginCredentials(good))
              .entrySet()) {
        checkResponseEqualsHostname(response.getValue(), response.getKey());
      }

      // test single-node execution
      ExecResponse response =
          client.runScriptOnNode(
              node.getId(), "hostname", wrapInInitScript(false).runAsRoot(false));
      checkResponseEqualsHostname(response, node);
      OperatingSystem os = node.getOperatingSystem();

      // test bad password
      tryBadPassword(group, good);

      runScriptWithCreds(group, os, good);

      checkNodes(nodes, group, "runScriptWithCreds");

      // test adding AdminAccess later changes the default boot user, in this
      // case to foo, with home dir /over/ridden/foo
      ListenableFuture<ExecResponse> future =
          client.submitScriptOnNode(
              node.getId(),
              AdminAccess.builder().adminUsername("foo").adminHome("/over/ridden/foo").build(),
              nameTask("adminUpdate"));

      response = future.get(3, TimeUnit.MINUTES);

      assert response.getExitStatus() == 0 : node.getId() + ": " + response;

      node = client.getNodeMetadata(node.getId());
      // test that the node updated to the correct admin user!
      assertEquals(node.getCredentials().identity, "foo");
      assert node.getCredentials().credential != null : nodes;

      weCanCancelTasks(node);

      assert response.getExitStatus() == 0 : node.getId() + ": " + response;

      response =
          client.runScriptOnNode(
              node.getId(), "echo $USER", wrapInInitScript(false).runAsRoot(false));

      assert response.getOutput().trim().equals("foo") : node.getId() + ": " + response;

    } finally {
      client.destroyNodesMatching(inGroup(group));
    }
  }
 @Test(enabled = true, expectedExceptions = NoSuchElementException.class)
 public void testCorrectExceptionRunningNodesNotFound() throws Exception {
   client.runScriptOnNodesMatching(runningInGroup("zebras-are-awesome"), InstallJDK.fromOpenJDK());
 }