@Test(enabled = true)
  public void testShellAccess() throws IOException {
    final String nameOfServer = "Server" + String.valueOf(new Date().getTime()).substring(6);
    serversToDeleteAfterTheTests.add(nameOfServer);

    Set<Ip> availableIps = client.getIpServices().getUnassignedIpList();
    Ip availableIp = Iterables.getLast(availableIps);

    Server createdServer =
        client
            .getServerServices()
            .addServer(
                nameOfServer, "GSI-f8979644-e646-4711-ad58-d98a5fa3612c", "1", availableIp.getIp());
    assertNotNull(createdServer);
    assert serverLatestJobCompleted.apply(createdServer);

    // get server by name
    Set<Server> response = client.getServerServices().getServersByName(nameOfServer);
    assert (response.size() == 1);
    createdServer = Iterables.getOnlyElement(response);

    Map<String, Credentials> credsMap = client.getServerServices().getServerCredentialsList();
    LoginCredentials instanceCredentials =
        LoginCredentials.fromCredentials(credsMap.get(createdServer.getName()));
    assertNotNull(instanceCredentials);

    HostAndPort socket = HostAndPort.fromParts(createdServer.getIp().getIp(), 22);

    Predicate<HostAndPort> socketOpen = retry(new InetSocketAddressConnect(), 180, 5, SECONDS);

    socketOpen.apply(socket);

    SshClient sshClient =
        gocontext
            .utils()
            .injector()
            .getInstance(SshClient.Factory.class)
            .create(socket, instanceCredentials);
    sshClient.connect();
    String output = sshClient.exec("df").getOutput();
    assertTrue(
        output.contains("Filesystem"),
        "The output should've contained filesystem information, but it didn't. Output: " + output);
    sshClient.disconnect();

    // check that the get credentials call is the same as this
    assertEquals(
        client.getServerServices().getServerCredentials(createdServer.getId()),
        instanceCredentials);

    try {
      assertEquals(client.getServerServices().getServerCredentials(Long.MAX_VALUE), null);
    } catch (AssertionError e) {
      e.printStackTrace();
    }

    // delete the server
    client.getServerServices().deleteByName(nameOfServer);
  }
 @Override
 public int hashCode() {
   int result = userName != null ? userName.hashCode() : 0;
   result = 31 * result + (password != null ? password.hashCode() : 0);
   result = 31 * result + (server != null ? server.hashCode() : 0);
   return result;
 }
  @Test
  public void testPredicate() {
    final String serverName = "SERVER_NAME";
    Server server = createMock(Server.class);
    expect(server.getName()).andStubReturn(serverName);

    Job job = createMock(Job.class);
    expect(job.getCurrentState()).andReturn(JobState.SUCCEEDED);

    GridJobApi client = createMock(GridJobApi.class);
    expect(client.getJobList(latestJobForObjectByName(serverName)))
        .andReturn(ImmutableSet.<Job>of(job));

    replay(job);
    replay(client);
    replay(server);

    ServerLatestJobCompleted predicate = new ServerLatestJobCompleted(client);
    assertTrue(predicate.apply(server), "The result of the predicate should've been 'true'");
  }
    @Override
    public boolean equals(Object o) {
      if (this == o) return true;
      if (o == null || getClass() != o.getClass()) return false;

      Password password1 = (Password) o;

      if (password != null ? !password.equals(password1.password) : password1.password != null)
        return false;
      if (server != null ? !server.equals(password1.server) : password1.server != null)
        return false;
      if (userName != null ? !userName.equals(password1.userName) : password1.userName != null)
        return false;

      return true;
    }
 @Override
 public NodeMetadata createNodeWithGroupEncodedIntoName(
     String group, String name, Template template) {
   Server addedServer = null;
   boolean notStarted = true;
   int numOfRetries = 20;
   GetIpListOptions unassignedIps =
       new GetIpListOptions()
           .onlyUnassigned()
           .inDatacenter(template.getLocation().getId())
           .onlyWithType(IpType.PUBLIC);
   // lock-free consumption of a shared resource: IP address pool
   while (notStarted) { // TODO: replace with Predicate-based thread
     // collision avoidance for simplicity
     Set<Ip> availableIps = client.getIpServices().getIpList(unassignedIps);
     if (availableIps.isEmpty()) throw new RuntimeException("No IPs available on this identity.");
     int ipIndex = new SecureRandom().nextInt(availableIps.size());
     Ip availableIp = Iterables.get(availableIps, ipIndex);
     try {
       addedServer = addServer(name, template, availableIp);
       notStarted = false;
     } catch (Exception e) {
       if (--numOfRetries == 0) Throwables.propagate(e);
       notStarted = true;
     }
   }
   if (template.getOptions().shouldBlockUntilRunning()) {
     serverLatestJobCompleted.apply(addedServer);
     client.getServerServices().power(addedServer.getName(), PowerCommand.START);
     serverLatestJobCompletedShort.apply(addedServer);
     addedServer =
         Iterables.getOnlyElement(
             client.getServerServices().getServersByName(addedServer.getName()));
   }
   Credentials credentials =
       client.getServerServices().getServerCredentialsList().get(addedServer.getName());
   if (credentials != null) credentialStore.put("node#" + addedServer.getId(), credentials);
   else logger.warn("couldn't get credentials for server %s", addedServer.getName());
   return serverToNodeMetadata.apply(addedServer);
 }
 @Override
 public int compareTo(Password o) {
   return server.getName().compareTo(o.getServer().getName());
 }