Java tutorial
/** * Copyright 2016 CERN. This software is distributed under the terms of the Apache License Version 2.0, copied * verbatim in the file COPYING?. In applying this licence, CERN does not waive the privileges and immunities granted * to it by virtue of its status as an Intergovernmental Organization or submit itself to any jurisdiction. */ package cern.jarrace.controller.rest.controller; import cern.jarrace.commons.domain.AgentContainer; import cern.jarrace.commons.domain.Service; import cern.jarrace.controller.io.JarWriter; import cern.jarrace.controller.jvm.AgentRegistrySpawner; import cern.jarrace.controller.jvm.AgentRunnerSpawner; import cern.jarrace.controller.manager.AgentContainerManager; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectWriter; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.http.MediaType; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.util.NestedServletException; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.*; import java.util.jar.JarEntry; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; import static org.hamcrest.CoreMatchers.isA; import static org.mockito.Matchers.anyList; import static org.mockito.Matchers.anyString; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; /** * Class that tests the behaviour of the {@link AgentContainerController} * * @author tiagomr */ @RunWith(MockitoJUnitRunner.class) public class AgentContainerControllerTest { private static final String JARRACE_CONTAINER_LIST_PATH = "/jarrace/container/list"; private static final String JARRACE_CONTAINER_REGISTER_PATH = "/jarrace/container/register"; private static final String TEST_NAME = "TEST_NAME"; private static final String JARRACE_CONTAINER_TEST_NAME_START_PATH = "/jarrace/container/" + TEST_NAME + "/start"; private static final String JARRACE_CONTAINER_TEST_NAME_READ_PATH = "/jarrace/container/" + TEST_NAME + "/read"; private static final String TEST_SERVICE_NAME = "TEST_SERVICE_NAME"; private static final String TEST_ENTRY_POINT_1 = "TEST_ENTRY_POINT_1"; private static final String TEST_ENTRY_POINT_2 = "TEST_ENTRY_POINT_2"; private static final String TEST_AGENT_NAME = "TEST_AGENT_NAME"; private static final String TEST_NAME1 = "TEST_NAME"; private static final String TEST_PATH = "TEST_PATH"; private static final String SERVICE_PARAM_NAME = "service"; private static final String ENTRY_POINTS_PARAM_NAME = "entryPoints"; private static final String CLASS_ENTRY_NAME = "class"; private MockMvc mockMvc; private AgentContainerController agentContainerController; @Mock private AgentContainerManager agentContainerManager; @Mock private AgentRegistrySpawner agentRegistrySpawner; @Mock private AgentRunnerSpawner agentRunnerSpawner; @Mock private JarWriter jarWriter; @Rule public final ExpectedException expectedException = ExpectedException.none(); @Before public void setUp() throws Exception { agentContainerController = new AgentContainerController(); agentContainerController.setAgentContainerManager(agentContainerManager); agentContainerController.setAgentRegistrySpawner(agentRegistrySpawner); agentContainerController.setAgentRunnerSpawner(agentRunnerSpawner); agentContainerController.setJarWriter(jarWriter); mockMvc = MockMvcBuilders.standaloneSetup(agentContainerController) .addPlaceHolderValue("rest.basepath", "/jarrace").build(); } @Test public void testDeploy() throws Exception { when(jarWriter.writeFile("TestContainer", "TestBytes".getBytes())).thenReturn("MockedPath"); mockMvc.perform(post("/jarrace/container/deploy/TestContainer") .contentType(MediaType.APPLICATION_OCTET_STREAM).content("TestBytes".getBytes())) .andExpect(status().isOk()); verify(jarWriter).writeFile("TestContainer", "TestBytes".getBytes()); verify(agentRegistrySpawner).spawnAgentRegistry("TestContainer", "MockedPath"); } @Test public void testRegister() throws Exception { mockMvc.perform(post(JARRACE_CONTAINER_REGISTER_PATH).contentType(MediaType.APPLICATION_JSON) .content(getJson(getTestAgentContainer()))).andExpect(status().isOk()); } @Test public void testRegisterWithWrongMediaType() throws Exception { mockMvc.perform(post(JARRACE_CONTAINER_REGISTER_PATH).contentType(MediaType.APPLICATION_OCTET_STREAM)) .andExpect(status().isUnsupportedMediaType()); } @Test public void testRegisterWithWrongMethodType() throws Exception { mockMvc.perform(get(JARRACE_CONTAINER_REGISTER_PATH)).andExpect(status().isMethodNotAllowed()); } @Test public void testRegisterWithNoContent() throws Exception { mockMvc.perform(post(JARRACE_CONTAINER_REGISTER_PATH).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()); } @Test public void testListWithAgentContainers() throws Exception { Set<AgentContainer> containers = Collections.singleton(getTestAgentContainer()); when(agentContainerManager.findAllAgentContainers()).thenReturn(containers); mockMvc.perform(get(JARRACE_CONTAINER_LIST_PATH)).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(content().json(getJson(containers))); } @Test public void testListWithNoAgentContainers() throws Exception { Set<AgentContainer> containers = Collections.emptySet(); when(agentContainerManager.findAllAgentContainers()).thenReturn(containers); mockMvc.perform(get(JARRACE_CONTAINER_LIST_PATH)).andExpect(status().isOk()) .andExpect(content().contentType(MediaType.APPLICATION_JSON)) .andExpect(content().json(getJson(containers))); } @Test public void testListWithWrongRequestType() throws Exception { mockMvc.perform(post(JARRACE_CONTAINER_LIST_PATH)).andExpect(status().isMethodNotAllowed()); } @Test public void testStartWithWrongRequestType() throws Exception { mockMvc.perform(post(JARRACE_CONTAINER_TEST_NAME_START_PATH)).andExpect(status().isMethodNotAllowed()); } @Test public void testStartWithNoParameters() throws Exception { mockMvc.perform(get(JARRACE_CONTAINER_TEST_NAME_START_PATH)).andExpect(status().isBadRequest()); } @Test public void testStartWithNonExistentContainerName() throws Exception { expectedException.expect(NestedServletException.class); expectedException.expectCause(isA(IllegalArgumentException.class)); when(agentContainerManager.findAgentContainer(TEST_NAME)).thenReturn(Optional.empty()); mockMvc.perform(get(JARRACE_CONTAINER_TEST_NAME_START_PATH).param(SERVICE_PARAM_NAME, TEST_SERVICE_NAME)); } @Test public void testStartWithNoNonExistentService() throws Exception { expectedException.expect(NestedServletException.class); expectedException.expectCause(isA(IllegalArgumentException.class)); AgentContainer container = getTestAgentContainer(); when(agentContainerManager.findAgentContainer(TEST_NAME)).thenReturn(Optional.of(container)); mockMvc.perform(get(JARRACE_CONTAINER_TEST_NAME_START_PATH).param(SERVICE_PARAM_NAME, TEST_SERVICE_NAME)); } @Test public void testStartWithNonExistentEntrypoint() throws Exception { expectedException.expect(NestedServletException.class); expectedException.expectCause(isA(IllegalArgumentException.class)); AgentContainer container = getTestAgentContainer(); when(agentContainerManager.findAgentContainer(TEST_NAME)).thenReturn(Optional.of(container)); mockMvc.perform(get(JARRACE_CONTAINER_TEST_NAME_START_PATH).param(SERVICE_PARAM_NAME, TEST_SERVICE_NAME) .param(ENTRY_POINTS_PARAM_NAME, TEST_ENTRY_POINT_1 + "_NON_EXISTENT")); } @Test public void testStart() throws Exception { AgentContainer container = getTestAgentContainer(); when(agentContainerManager.findAgentContainer(TEST_NAME)).thenReturn(Optional.of(container)); mockMvc.perform(get(JARRACE_CONTAINER_TEST_NAME_START_PATH).param(SERVICE_PARAM_NAME, TEST_SERVICE_NAME) .param(ENTRY_POINTS_PARAM_NAME, TEST_ENTRY_POINT_1, TEST_ENTRY_POINT_2)).andExpect(status().isOk()); verify(agentRunnerSpawner).spawnAgentRunner(Matchers.any(Service.class), anyString(), anyList()); } @Test public void canFetchEntryInsideJar() throws Exception { final String content = "testContent\nSpanning\nLines"; final File jarFile = setupJarContainer(content, TEST_PATH); mockMvc.perform(get(JARRACE_CONTAINER_TEST_NAME_READ_PATH).param(CLASS_ENTRY_NAME, TEST_PATH)) .andExpect(content().string(content)); //noinspection ResultOfMethodCallIgnored jarFile.delete(); } @Test public void canFailToFetchEntryFromJarWhenContainerDoesNotExist() throws Exception { when(agentContainerManager.findAgentContainer(TEST_NAME)).thenReturn(Optional.empty()); mockMvc.perform(get(JARRACE_CONTAINER_TEST_NAME_READ_PATH).param(CLASS_ENTRY_NAME, TEST_NAME)) .andExpect(status().isBadRequest()); } @Test public void canFailToFetchEntryFromJarWhenEntryDoesNotExist() throws Exception { final String content = "TestContent"; final File jarFile = setupJarContainer(content, TEST_PATH); mockMvc.perform(get(JARRACE_CONTAINER_TEST_NAME_READ_PATH).param(CLASS_ENTRY_NAME, "IDoNotExist")) .andExpect(status().isBadRequest()); } private AgentContainer getTestAgentContainer() { List<String> entryPoints = new ArrayList<>(); entryPoints.add(TEST_ENTRY_POINT_1); entryPoints.add(TEST_ENTRY_POINT_2); List<Service> services = new ArrayList<>(); services.add(new Service(TEST_AGENT_NAME, TEST_SERVICE_NAME, entryPoints)); return new AgentContainer(TEST_NAME1, TEST_PATH, services); } private String getJson(Object object) throws JsonProcessingException { ObjectWriter writer = new ObjectMapper().writer(); return writer.writeValueAsString(object); } private File setupJarContainer(String content, String entry) throws IOException { final File jarFile = writeToZip(entry + AgentContainerController.JAVA_CLASS_SUFFIX, content); final AgentContainer mockedContainer = mock(AgentContainer.class); when(agentContainerManager.findAgentContainer(TEST_NAME)).thenReturn(Optional.of(mockedContainer)); when(mockedContainer.getContainerPath()).thenReturn(jarFile.toString()); return jarFile; } private File writeToZip(String entry, String data) throws IOException { File tmpFile = File.createTempFile("test", null); try (FileOutputStream fileOutput = new FileOutputStream(tmpFile); ZipOutputStream zipOutput = new ZipOutputStream(fileOutput)) { ZipEntry zipEntry = new JarEntry(entry); zipOutput.putNextEntry(zipEntry); zipOutput.write(data.getBytes()); } return tmpFile; } }