/* * Copyright (C) 2015 Orange * * This software is distributed under the terms and conditions of the 'GNU GENERAL PUBLIC LICENSE * Version 2' license which can be found in the file 'LICENSE.txt' in this package distribution or * at 'http://www.gnu.org/licenses/gpl-2.0-standalone.html'. */ package com.orange.cepheus.cep.controller; import com.orange.cepheus.cep.Application; import com.orange.cepheus.cep.ComplexEventProcessor; import com.orange.cepheus.cep.EventMapper; import com.orange.cepheus.cep.exception.ConfigurationException; import com.orange.cepheus.cep.exception.PersistenceException; import com.orange.cepheus.cep.model.Configuration; import com.orange.cepheus.cep.model.Statement; import com.orange.cepheus.cep.persistence.Persistence; import com.orange.cepheus.cep.tenant.TenantFilter; import org.junit.*; import org.junit.runner.RunWith; import org.mockito.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.SpringApplicationConfiguration; import org.springframework.http.MediaType; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.result.MockMvcResultHandlers; import org.springframework.web.context.WebApplicationContext; import java.util.LinkedList; import java.util.List; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*; import static org.junit.Assert.assertEquals; import static com.orange.cepheus.cep.Util.*; /** * Test the Admin controller */ @RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = {Application.class}) @WebAppConfiguration public class AdminControllerTest { private MockMvc mockMvc; @Autowired private MappingJackson2HttpMessageConverter mapping; @Autowired private WebApplicationContext webApplicationContext; @Mock private ComplexEventProcessor complexEventProcessor; @Mock private Persistence persistence; @Mock private EventMapper eventMapper; @Autowired @InjectMocks AdminController adminController; @Before public void setup() throws Exception { MockitoAnnotations.initMocks(this); this.mockMvc = webAppContextSetup(webApplicationContext).build(); } @After public void resetMocks() { reset(complexEventProcessor); reset(persistence); reset(eventMapper); } @Test public void checkConfigurationNotFound() throws Exception { when(complexEventProcessor.getConfiguration()).thenReturn(null); mockMvc.perform(get("/v1/admin/config") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); } @Test public void postConfOK() throws Exception { Configuration configuration = getBasicConf(); mockMvc.perform(post("/v1/admin/config").content(json(mapping, configuration)).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isCreated()); ArgumentCaptor<Configuration> configurationArg = ArgumentCaptor.forClass(Configuration.class); verify(complexEventProcessor).setConfiguration(configurationArg.capture()); Configuration capturedConfiguration = configurationArg.getValue(); assertEquals(1, capturedConfiguration.getEventTypeIns().size()); assertEquals("S.*", capturedConfiguration.getEventTypeIns().get(0).getId()); assertEquals(1, capturedConfiguration.getEventTypeOuts().size()); assertEquals("OUT1", capturedConfiguration.getEventTypeOuts().get(0).getId()); verify(persistence).saveConfiguration(eq(TenantFilter.DEFAULT_TENANTID), eq(capturedConfiguration)); } @Test public void getConfiguration() throws Exception { Configuration configuration = getBasicConf(); when(complexEventProcessor.getConfiguration()).thenReturn(configuration); mockMvc.perform(get("/v1/admin/config") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.in[0].id").value(configuration.getEventTypeIns().get(0).getId())) .andExpect(jsonPath("$.out[0].id").value(configuration.getEventTypeOuts().get(0).getId())) .andExpect(jsonPath("$.statements[0]").value(configuration.getStatements().get(0))); } @Test public void deleteConfiguration() throws Exception { mockMvc.perform(delete("/v1/admin/config")).andExpect(status().isOk()); verify(complexEventProcessor).reset(); verify(persistence).deleteConfiguration(eq(TenantFilter.DEFAULT_TENANTID)); } @Test public void checkNoStatement() throws Exception { List<Statement> noStatement = new LinkedList<>(); when(complexEventProcessor.getStatements()).thenReturn(noStatement); mockMvc.perform(get("/v1/admin/statements") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isNotFound()); } @Test public void getStatements() throws Exception { List<Statement> statements = new LinkedList<>(); Statement statement1 = new Statement("statement1", "insert into TempSensorAvg select \"OUT1\" as id, avg(temp) as avgTemp, temp_unit as avgTemp_unit from TempSensor.win:time(2 seconds) where TempSensor.id=\"S1\""); statements.add(statement1); Statement statement2 = new Statement("statement2", "ON FenceCross fc MERGE TrackerState ts WHERE fc.id = ts.id WHEN NOT MATCHED THEN INSERT SELECT id, time, location, inside WHEN MATCHED AND fc.inside != ts.inside THEN UPDATE SET inside = fc.inside"); statements.add(statement2); when(complexEventProcessor.getStatements()).thenReturn(statements); mockMvc.perform(get("/v1/admin/statements") .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andDo(MockMvcResultHandlers.print()) .andExpect(jsonPath("$.[0].name").value("statement1")) .andExpect(jsonPath("$.[1].name").value("statement2")); } @Test public void configurationErrorHandling() throws Exception { Configuration configuration = getBasicConf(); doThrow(new ConfigurationException("ERROR", new Exception("DETAIL ERROR"))).when(complexEventProcessor).setConfiguration(any(Configuration.class)); mockMvc.perform(post("/v1/admin/config").content(json(mapping, configuration)).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.code").value("400")) .andExpect(jsonPath("$.reasonPhrase").value("ERROR")) .andExpect(jsonPath("$.details").value("DETAIL ERROR")); } @Test public void eventMapperErrorHandling() throws Exception { Configuration configuration = getBasicConf(); doThrow(new ConfigurationException("ERROR", new Exception("DETAIL ERROR"))).when(eventMapper).setConfiguration(any(Configuration.class)); mockMvc.perform(post("/v1/admin/config").content(json(mapping, configuration)).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isBadRequest()) .andExpect(jsonPath("$.code").value("400")) .andExpect(jsonPath("$.reasonPhrase").value("ERROR")) .andExpect(jsonPath("$.details").value("DETAIL ERROR")); } @Test public void persistenceErrorHandling() throws Exception { doThrow(new PersistenceException("ERROR")).when(persistence).saveConfiguration(any(), any(Configuration.class)); Configuration configuration = getBasicConf(); mockMvc.perform(post("/v1/admin/config").content(json(mapping, configuration)).contentType(MediaType.APPLICATION_JSON)) .andExpect(status().isInternalServerError()) .andExpect(jsonPath("$.code").value("500")) .andExpect(jsonPath("$.reasonPhrase").value("ERROR")); } }