/*
*
* Copyright 2015 Netflix, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package com.netflix.genie.client;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.fge.jsonpatch.JsonPatch;
import com.google.common.collect.Lists;
import com.netflix.genie.common.dto.Application;
import com.netflix.genie.common.dto.ApplicationStatus;
import com.netflix.genie.common.dto.Cluster;
import com.netflix.genie.common.dto.Command;
import com.netflix.genie.common.dto.CommandStatus;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
/**
* Integration Tests for Command Client.
*
* @author amsharma
*/
public class CommandClientIntegrationTests extends GenieClientsIntegrationTestsBase {
private ClusterClient clusterClient;
private CommandClient commandClient;
private ApplicationClient applicationClient;
/**
* Setup for tests.
*
* @throws Exception If there is an error.
*/
@Before
public void setup() throws Exception {
clusterClient = new ClusterClient(getBaseUrl(), null, null);
commandClient = new CommandClient(getBaseUrl(), null, null);
applicationClient = new ApplicationClient(getBaseUrl(), null, null);
}
/**
* Delete all commands and applications between tests.
*
* @throws Exception If there is any problem.
*/
@After
public void cleanUp() throws Exception {
clusterClient.deleteAllClusters();
commandClient.deleteAllCommands();
applicationClient.deleteAllApplications();
}
/**
* Integration test to get all applications from Genie.
*
* @throws Exception If there is any problem.
*/
@Test
public void testCanCreateAndGetCommand() throws Exception {
final String id = UUID.randomUUID().toString();
final Command command = constructCommandDTO(id);
final String commandId = commandClient.createCommand(command);
Assert.assertEquals(commandId, id);
// Make sure Genie Not Found Exception is not thrown for this call.
final Command cmd = commandClient.getCommand(id);
// Make sure the object returned is exactly what was sent to be created
Assert.assertEquals(command.getId(), cmd.getId());
Assert.assertEquals(command.getName(), cmd.getName());
Assert.assertEquals(command.getDescription(), cmd.getDescription());
Assert.assertEquals(command.getConfigs(), cmd.getConfigs());
Assert.assertEquals(command.getSetupFile(), cmd.getSetupFile());
Assert.assertEquals(cmd.getTags().contains("foo"), true);
Assert.assertEquals(cmd.getTags().contains("bar"), true);
Assert.assertEquals(command.getStatus(), cmd.getStatus());
}
/**
* Test getting the commands using the various query parameters.
*
* @throws Exception If there is any problem.
*/
@Test
public void testGetCommandsUsingParams() throws Exception {
final String command1Id = UUID.randomUUID().toString();
final String command2Id = UUID.randomUUID().toString();
final Set<String> command1Tags = new HashSet<>();
command1Tags.add("foo");
command1Tags.add("pi");
final Set<String> command2Tags = new HashSet<>();
command2Tags.add("bar");
command2Tags.add("pi");
final Command command1 = new Command.Builder(
"command1name",
"command1user",
"1.0",
CommandStatus.ACTIVE,
"exec",
1000
)
.withId(command1Id)
.withTags(command1Tags)
.build();
final Command command2 =
new Command.Builder(
"command2name",
"command2user",
"2.0",
CommandStatus.INACTIVE,
"exec",
1000
)
.withId(command2Id)
.withTags(command2Tags)
.build();
commandClient.createCommand(command1);
commandClient.createCommand(command2);
// Test get by tags
List<Command> commandList = commandClient.getCommands(
null,
null,
null,
Lists.newArrayList("foo")
);
Assert.assertEquals(1, commandList.size());
Assert.assertEquals(command1Id, commandList.get(0).getId().orElse(UUID.randomUUID().toString()));
commandList = commandClient.getCommands(
null,
null,
null,
Lists.newArrayList("pi")
);
Assert.assertEquals(2, commandList.size());
Assert.assertEquals(command2Id, commandList.get(0).getId().orElse(UUID.randomUUID().toString()));
Assert.assertEquals(command1Id, commandList.get(1).getId().orElse(UUID.randomUUID().toString()));
// Test get by name
commandList = commandClient.getCommands(
"command1name",
null,
null,
null
);
Assert.assertEquals(1, commandList.size());
// Test get by status
commandList = commandClient.getCommands(
null,
null,
Lists.newArrayList(CommandStatus.ACTIVE.toString()),
null
);
Assert.assertEquals(1, commandList.size());
commandList = commandClient.getCommands(
null,
null,
Arrays.asList(CommandStatus.ACTIVE.toString(), CommandStatus.INACTIVE.toString()),
null
);
Assert.assertEquals(2, commandList.size());
}
/**
* Test to confirm getting an exception for non existent command.
*
* @throws Exception If there is a problem.
*/
@Test(expected = IOException.class)
public void testCommandNotExist() throws Exception {
commandClient.getCommand("foo");
}
/**
* Test get all commands.
*
* @throws Exception If there is problem.
*/
@Test
public void testGetAllAndDeleteAllCommands() throws Exception {
final List<Command> initialCommandList = commandClient.getCommands();
Assert.assertEquals(initialCommandList.size(), 0);
final Command command1 = constructCommandDTO(null);
final Command command2 = constructCommandDTO(null);
commandClient.createCommand(command1);
commandClient.createCommand(command2);
final List<Command> finalCommandList = commandClient.getCommands();
Assert.assertEquals(finalCommandList.size(), 2);
Assert.assertEquals(command1.getId(), finalCommandList.get(1).getId());
Assert.assertEquals(command2.getId(), finalCommandList.get(0).getId());
commandClient.deleteAllCommands();
Assert.assertEquals(commandClient.getCommands().size(), 0);
}
/**
* Test whether we can delete a command in Genie.
*
* @throws Exception If there is any problem.
*/
@Test(expected = IOException.class)
public void testDeleteCommand() throws Exception {
final Command command1 = constructCommandDTO(null);
commandClient.createCommand(command1);
final Command command2 = commandClient.getCommand(command1.getId().orElseThrow(IllegalArgumentException::new));
Assert.assertEquals(command2.getId(), command1.getId());
commandClient.deleteCommand(command1.getId().orElseThrow(IllegalArgumentException::new));
commandClient.getCommand(command1.getId().orElseThrow(IllegalArgumentException::new));
}
/**
* Test to verify if the update command method is working correctly.
*
* @throws Exception If there is any problem.
*/
@Test
public void testUpdateCommand() throws Exception {
final Command command1 = constructCommandDTO(null);
commandClient.createCommand(command1);
final Command command2 = commandClient.getCommand(command1.getId().orElseThrow(IllegalArgumentException::new));
Assert.assertEquals(command2.getName(), command1.getName());
final Command command3 = new
Command.Builder("newname", "newuser", "new version", CommandStatus.ACTIVE, "exec", 1000)
.withId(command1.getId().orElseThrow(IllegalArgumentException::new))
.build();
commandClient.updateCommand(command1.getId().orElseThrow(IllegalArgumentException::new), command3);
final Command command4 = commandClient.getCommand(command1.getId().orElseThrow(IllegalArgumentException::new));
Assert.assertEquals("newname", command4.getName());
Assert.assertEquals("newuser", command4.getUser());
Assert.assertEquals("new version", command4.getVersion());
Assert.assertEquals(CommandStatus.ACTIVE, command4.getStatus());
Assert.assertFalse(command4.getSetupFile().isPresent());
Assert.assertFalse(command4.getDescription().isPresent());
Assert.assertEquals(Collections.emptySet(), command4.getConfigs());
Assert.assertEquals(command4.getTags().contains("foo"), false);
}
/**
* Test all the methods that manipulate tags for a command in genie.
*
* @throws Exception If there is any problem.
*/
@Test
public void testCommandTagsMethods() throws Exception {
final Set<String> initialTags = new HashSet<>();
initialTags.add("foo");
initialTags.add("bar");
final Set<String> configList = new HashSet<>();
configList.add("config1");
configList.add("configs2");
final Command command = new Command.Builder("name", "user", "1.0", CommandStatus.ACTIVE, "exec", 1000)
.withId("command1")
.withDescription("client Test")
.withSetupFile("path to set up file")
.withTags(initialTags)
.withConfigs(configList)
.build();
commandClient.createCommand(command);
// Test getTags for command
Set<String> tags = commandClient.getTagsForCommand("command1");
Assert.assertEquals(4, tags.size());
Assert.assertEquals(tags.contains("foo"), true);
Assert.assertEquals(tags.contains("bar"), true);
// Test adding a tag for command
final Set<String> moreTags = new HashSet<>();
moreTags.add("pi");
commandClient.addTagsToCommand("command1", moreTags);
tags = commandClient.getTagsForCommand("command1");
Assert.assertEquals(5, tags.size());
Assert.assertEquals(tags.contains("foo"), true);
Assert.assertEquals(tags.contains("bar"), true);
Assert.assertEquals(tags.contains("pi"), true);
// Test removing a tag for command
commandClient.removeTagFromCommand("command1", "bar");
tags = commandClient.getTagsForCommand("command1");
Assert.assertEquals(4, tags.size());
Assert.assertEquals(tags.contains("foo"), true);
Assert.assertEquals(tags.contains("pi"), true);
// Test update tags for a command
commandClient.updateTagsForCommand("command1", initialTags);
tags = commandClient.getTagsForCommand("command1");
Assert.assertEquals(4, tags.size());
Assert.assertEquals(tags.contains("foo"), true);
Assert.assertEquals(tags.contains("bar"), true);
// Test delete all tags in a command
commandClient.removeAllTagsForCommand("command1");
tags = commandClient.getTagsForCommand("command1");
Assert.assertEquals(2, tags.size());
}
/**
* Test all the methods that manipulate configs for a command in genie.
*
* @throws Exception If there is any problem.
*/
@Test
public void testCommandConfigsMethods() throws Exception {
final Set<String> initialConfigs = new HashSet<>();
initialConfigs.add("foo");
initialConfigs.add("bar");
final Command command = new Command.Builder("name", "user", "1.0", CommandStatus.ACTIVE, "exec", 1000)
.withId("command1")
.withDescription("client Test")
.withSetupFile("path to set up file")
.withConfigs(initialConfigs)
.build();
commandClient.createCommand(command);
// Test getConfigs for command
Set<String> configs = commandClient.getConfigsForCommand("command1");
Assert.assertEquals(2, configs.size());
Assert.assertEquals(configs.contains("foo"), true);
Assert.assertEquals(configs.contains("bar"), true);
// Test adding a config for command
final Set<String> moreConfigs = new HashSet<>();
moreConfigs.add("pi");
commandClient.addConfigsToCommand("command1", moreConfigs);
configs = commandClient.getConfigsForCommand("command1");
Assert.assertEquals(3, configs.size());
Assert.assertEquals(configs.contains("foo"), true);
Assert.assertEquals(configs.contains("bar"), true);
Assert.assertEquals(configs.contains("pi"), true);
// Test update configs for a command
commandClient.updateConfigsForCommand("command1", initialConfigs);
configs = commandClient.getConfigsForCommand("command1");
Assert.assertEquals(2, configs.size());
Assert.assertEquals(configs.contains("foo"), true);
Assert.assertEquals(configs.contains("bar"), true);
// Test delete all configs in a command
commandClient.removeAllConfigsForCommand("command1");
configs = commandClient.getConfigsForCommand("command1");
Assert.assertEquals(0, configs.size());
}
/**
* Test all the methods that manipulate applications for a command in genie.
*
* @throws Exception If there is any problem.
*/
@Test
public void testCommandApplicationsMethods() throws Exception {
final Application foo = new Application.Builder(
"name",
"user",
"version",
ApplicationStatus.ACTIVE
).withId("foo")
.build();
applicationClient.createApplication(foo);
final Application bar = new Application.Builder(
"name",
"user",
"version",
ApplicationStatus.ACTIVE
).withId("bar")
.build();
applicationClient.createApplication(bar);
final Application pi = new Application.Builder(
"name",
"user",
"version",
ApplicationStatus.ACTIVE
).withId("pi")
.build();
applicationClient.createApplication(pi);
final Command command = constructCommandDTO("command1");
commandClient.createCommand(command);
// Test add Applications to command
final List<String> initialApplications = new ArrayList<>();
initialApplications.add("foo");
initialApplications.add("bar");
initialApplications.add("pi");
commandClient.addApplicationsToCommand("command1", initialApplications);
List<Application> applications = commandClient.getApplicationsForCommand("command1");
Assert.assertEquals(3, applications.size());
Assert.assertEquals("foo", applications.get(0).getId().orElseThrow(IllegalArgumentException::new));
Assert.assertEquals("bar", applications.get(1).getId().orElseThrow(IllegalArgumentException::new));
Assert.assertEquals("pi", applications.get(2).getId().orElseThrow(IllegalArgumentException::new));
// Test removing a application for command
commandClient.removeApplicationFromCommand("command1", "pi");
applications = commandClient.getApplicationsForCommand("command1");
Assert.assertEquals(2, applications.size());
Assert.assertEquals("foo", applications.get(0).getId().orElseThrow(IllegalArgumentException::new));
Assert.assertEquals("bar", applications.get(1).getId().orElseThrow(IllegalArgumentException::new));
final List<String> updatedApplications = new ArrayList<>();
updatedApplications.add("foo");
updatedApplications.add("pi");
// Test update applications for a command
commandClient.updateApplicationsForCommand("command1", updatedApplications);
applications = commandClient.getApplicationsForCommand("command1");
Assert.assertEquals(2, applications.size());
Assert.assertEquals("foo", applications.get(0).getId().orElseThrow(IllegalArgumentException::new));
Assert.assertEquals("pi", applications.get(1).getId().orElseThrow(IllegalArgumentException::new));
// Test delete all applications in a command
commandClient.removeAllApplicationsForCommand("command1");
applications = commandClient.getApplicationsForCommand("command1");
Assert.assertEquals(0, applications.size());
}
/**
* Test the command patch method.
*
* @throws Exception If there is any error.
*/
@Test
public void testCommandPatchMethod() throws Exception {
final ObjectMapper mapper = new ObjectMapper();
final String newName = UUID.randomUUID().toString();
final String patchString = "[{ \"op\": \"replace\", \"path\": \"/name\", \"value\": \"" + newName + "\" }]";
final JsonPatch patch = JsonPatch.fromJson(mapper.readTree(patchString));
final Command command = constructCommandDTO("command1");
commandClient.createCommand(command);
commandClient.patchCommand("command1", patch);
Assert.assertEquals(newName, commandClient.getCommand("command1").getName());
}
/**
* Test to fetch the clusters to which a command is linked.
*
* @throws Exception If there is any problem.
*/
@Test
public void testCanGetClustersForCommand() throws Exception {
final Cluster cluster1 = constructClusterDTO(null);
final Cluster cluster2 = constructClusterDTO(null);
final Command command = constructCommandDTO(null);
commandClient.createCommand(command);
clusterClient.createCluster(cluster1);
clusterClient.createCluster(cluster2);
clusterClient.addCommandsToCluster(
cluster1.getId().orElseThrow(IllegalArgumentException::new),
Lists.newArrayList(command.getId().orElseThrow(IllegalArgumentException::new))
);
clusterClient.addCommandsToCluster(
cluster2.getId().orElseThrow(IllegalArgumentException::new),
Lists.newArrayList(command.getId().orElseThrow(IllegalArgumentException::new))
);
final List<Cluster> clusterList
= commandClient.getClustersForCommand(command.getId().orElseThrow(IllegalArgumentException::new));
Assert.assertEquals(2, clusterList.size());
}
}