/* * Sakuli - Testing and Monitoring-Tool for Websites and common UIs. * * Copyright 2013 - 2015 the original author or authors. * * 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 org.sakuli.services.forwarder.gearman; import org.apache.commons.codec.binary.Base64; import org.apache.commons.lang.time.DateUtils; import org.gearman.client.*; import org.gearman.common.GearmanJobServerConnection; import org.mockito.*; import org.sakuli.BaseTest; import org.sakuli.builder.TestCaseExampleBuilder; import org.sakuli.builder.TestCaseStepExampleBuilder; import org.sakuli.builder.TestSuiteExampleBuilder; import org.sakuli.datamodel.TestSuite; import org.sakuli.exceptions.SakuliActionException; import org.sakuli.exceptions.SakuliExceptionHandler; import org.sakuli.exceptions.SakuliForwarderException; import org.sakuli.exceptions.SakuliRuntimeException; import org.sakuli.services.forwarder.gearman.crypt.Aes; import org.sakuli.services.forwarder.gearman.model.NagiosCachedCheckResult; import org.sakuli.services.forwarder.gearman.model.NagiosCheckResult; import org.sakuli.services.forwarder.gearman.model.builder.NagiosCheckResultBuilder; import org.springframework.test.util.ReflectionTestUtils; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.nio.channels.UnresolvedAddressException; import java.util.*; import java.util.concurrent.Future; import static org.mockito.Mockito.*; import static org.testng.Assert.assertEquals; public class GearmanResultServiceImplTest extends BaseTest { @Spy @InjectMocks private GearmanResultServiceImpl testling; @Mock private GearmanCacheService gearmanCacheService; @Mock private GearmanProperties properties; @Mock private SakuliExceptionHandler exceptionHandler; @Mock private NagiosCheckResultBuilder checkResultBuilder; private String testResult = "type=passive\n" + "host_name=win7sakuli\n" + "start_time=1425729540.000\n" + "finish_time=1425729600.000\n" + "return_code=2\n" + "service_description=sakuli_demo22\n" + "output=CRITICAL - CRITICAL - [CRIT] Sakuli suite \"sakuli_demo22\" ran in 60.00 seconds - EXCEPTION: \" - CASE 'error_case': exception test message\". (Last suite run: 07.03 13:00:00)" + "\\\\n<table style=\"border-collapse: collapse;\">" + "<tr valign=\"top\"><td class=\"serviceCRITICAL\">[CRIT] Sakuli suite \"sakuli_demo22\" ran in 60.00 seconds - EXCEPTION: \" - CASE 'error_case': exception test message\". (Last suite run: 07.03 13:00:00)</td></tr>" + "<tr valign=\"top\"><td class=\"serviceOK\">[OK] case \"ok_case\" ran in 12.00s - ok</td></tr>" + "<tr valign=\"top\"><td class=\"serviceWARNING\">[WARN] case \"warn_case\" over runtime (30.00s /warning at 20s) </td></tr>" + "<tr valign=\"top\"><td class=\"serviceWARNING\">[WARN] case \"warn_in_step\" over runtime (30.00s /warning in step at 40s) step \"warn_step_1\" (9.00s /warn at 5s), step \"warn_step_2\" (9.00s /warn at 5s)</td></tr>" + "<tr valign=\"top\"><td class=\"serviceCRITICAL\">[CRIT] case \"crit_case\" over runtime (14.00s /critical at 13s) </td></tr>" + "<tr valign=\"top\"><td class=\"serviceCRITICAL\">[CRIT] case \"error_case\" EXCEPTION: exception test message</td></tr></table>" + "|" + "suite__state=2;;;; " + "suite_sakuli_demo22=60.00s;;;; " + "c_1__state_ok_case=0;;;; " + "c_1_ok_case=12.00s;13;20;; " + "s_1_1_step_for_unit_test=1.00s;2;;; " + "c_2__state_warn_case=1;;;; " + "c_2_warn_case=30.00s;20;40;; " + "s_2_1_step_for_unit_test=1.00s;2;;; " + "c_3__state_warn_in_step=1;;;; " + "c_3_warn_in_step=30.00s;40;50;; " + "s_3_1_warn_step_1=9.00s;5;;; " + "s_3_2_warn_step_2=9.00s;5;;; " + "c_4__state_crit_case=2;;;; " + "c_4_crit_case=14.00s;10;13;; " + "s_4_1_step_for_unit_test=1.00s;2;;; " + "c_5__state_error_case=2;;;; " + "c_5_error_case=-1.00s;4;5;; " + "s_5_1_step_for_unit_test=1.00s;2;;; " + "[check_sakuli]"; @BeforeMethod public void setUp() throws Exception { MockitoAnnotations.initMocks(this); } @BeforeClass public void setKeyLength() { //set key length to 16 byte in unit tests, so default Java JRE security policy applies Aes.keyLength = 16; } @AfterClass(alwaysRun = true) public void restoreKeyLength() { //restore default key length Aes.keyLength = Aes.DEFAULT_KEY_LENGTH; } @Test public void testSaveAllResults() throws Exception { when(properties.getServiceType()).thenReturn("passive"); final String queueName = "check_results"; when(properties.getServerQueue()).thenReturn(queueName); final String host = "99.99.99.20"; when(properties.getServerHost()).thenReturn(host); final int port = 4730; when(properties.getServerPort()).thenReturn(port); when(properties.getNagiosHost()).thenReturn("win7sakuli"); when(checkResultBuilder.build()).thenReturn(new NagiosCachedCheckResult(queueName, "sakuli_demo22__2015_03_07_12_59_00_00", testResult)); GearmanClient gearmanClient = mock(GearmanClientImpl.class); doReturn(gearmanClient).when(testling).getGearmanClient(); GearmanJobServerConnection connection = mock(GearmanJobServerConnection.class); doReturn(connection).when(testling).getGearmanConnection(host, port); GearmanJob job = mock(GearmanJob.class); doReturn(job).when(testling).creatJob(any(NagiosCheckResult.class)); Future future = mock(Future.class); when(gearmanClient.addJobServer(connection)).thenReturn(true); when(gearmanClient.submit(job)).thenReturn(future); GearmanJobResult jobResult = mock(GearmanJobResult.class); when(future.get()).thenReturn(jobResult); when(jobResult.jobSucceeded()).thenReturn(true); GearmanJobStatus jobStatus = mock(GearmanJobStatus.class); when(jobStatus.isRunning()).thenReturn(false); when(gearmanClient.getJobStatus(job)).thenReturn(jobStatus); Date stopDate = new GregorianCalendar(2014, 14, 7, 13, 0).getTime(); TestSuite testSuite = new TestSuiteExampleBuilder() .withHost("win7sakuli") .withId("sakuli_demo22") .withStopDate(stopDate) .withStartDate(DateUtils.addSeconds(stopDate, -60)) .withTestCases(Collections.singletonList( new TestCaseExampleBuilder() .withId("ok_case") .withStartDate(DateUtils.addSeconds(stopDate, -12)) .withStopDate(stopDate) .withWarningTime(13) .withCriticalTime(20) .buildExample())) .buildExample(); stopDate = DateUtils.addSeconds(stopDate, 300); testSuite.addTestCase(new TestCaseExampleBuilder() .withId("warn_case") .withStartDate(DateUtils.addSeconds(stopDate, -30)) .withStopDate(stopDate) .withWarningTime(20) .withCriticalTime(40) .buildExample()); stopDate = DateUtils.addSeconds(stopDate, 300); testSuite.addTestCase(new TestCaseExampleBuilder() .withId("warn_in_step") .withStartDate(DateUtils.addSeconds(stopDate, -30)) .withStopDate(stopDate) .withWarningTime(40) .withCriticalTime(50) .withTestCaseSteps(Arrays.asList(new TestCaseStepExampleBuilder() .withName("warn_step_1") .withStartDate(DateUtils.addSeconds(stopDate, -29)) .withStopDate(DateUtils.addSeconds(stopDate, -20)) .withWarningTime(5) .buildExample(), new TestCaseStepExampleBuilder() .withName("warn_step_2") .withStartDate(DateUtils.addSeconds(stopDate, -19)) .withStopDate(DateUtils.addSeconds(stopDate, -10)) .withWarningTime(5) .buildExample())) .buildExample()); stopDate = DateUtils.addSeconds(stopDate, 300); testSuite.addTestCase(new TestCaseExampleBuilder() .withId("crit_case") .withStartDate(DateUtils.addSeconds(stopDate, -14)) .withStopDate(stopDate) .withWarningTime(10) .withCriticalTime(13) .buildExample()); stopDate = DateUtils.addSeconds(stopDate, 300); testSuite.addTestCase(new TestCaseExampleBuilder() .withId("error_case") .withStartDate(DateUtils.addSeconds(stopDate, -14)) .withException(new SakuliActionException("exception test message")) .buildExample()); ReflectionTestUtils.setField(testling, "testSuite", testSuite); testling.saveAllResults(); //checks verify(gearmanCacheService, never()).cacheResults(anyList()); verify(gearmanCacheService, never()).getCachedResults(); verify(exceptionHandler, never()).handleException(any(Throwable.class)); verify(exceptionHandler, never()).handleException(any(Throwable.class), anyBoolean()); verify(testling).getGearmanClient(); verify(testling).getGearmanConnection(host, port); verify(gearmanClient).addJobServer(connection); verify(gearmanClient).submit(job); verify(future).get(); verify(gearmanClient).shutdown(); ArgumentCaptor<NagiosCheckResult> checkresult = ArgumentCaptor.forClass(NagiosCheckResult.class); verify(testling).creatJob(checkresult.capture()); assertEquals(checkresult.getValue().getQueueName(), queueName); assertEquals(checkresult.getValue().getUuid(), testSuite.getGuid()); assertEquals(checkresult.getValue().getPayloadString(), testResult); } @Test public void testCreateJobEncryptionDisabled() throws Exception { when(properties.getServiceType()).thenReturn("passive"); final String queueName = "check_results"; when(properties.getServerQueue()).thenReturn(queueName); final String host = "99.99.99.20"; when(properties.getServerHost()).thenReturn(host); final int port = 4730; when(properties.getServerPort()).thenReturn(port); when(properties.getNagiosHost()).thenReturn("win7sakuli"); when(properties.isEncryption()).thenReturn(false); GearmanJob gearmanJob = testling.creatJob(new NagiosCachedCheckResult(queueName, "sakuli_demo22__2015_03_07_12_59_00_00", testResult)); assertEquals(new String(Base64.decodeBase64(gearmanJob.getData())), testResult); } @Test public void testCreateJobEncryptionEnabled() throws Exception { when(properties.getServiceType()).thenReturn("passive"); final String queueName = "check_results"; when(properties.getServerQueue()).thenReturn(queueName); final String host = "99.99.99.20"; when(properties.getServerHost()).thenReturn(host); final int port = 4730; when(properties.getServerPort()).thenReturn(port); when(properties.getNagiosHost()).thenReturn("win7sakuli"); when(properties.isEncryption()).thenReturn(true); final String secretKey = "abcdefghijklmnopqrstuvwxyz"; when(properties.getSecretKey()).thenReturn(secretKey); GearmanJob gearmanJob = testling.creatJob(new NagiosCachedCheckResult(queueName, "sakuli_demo22__2015_03_07_12_59_00_00", testResult)); assertEquals(Aes.decrypt(gearmanJob.getData(), secretKey), testResult); } @Test public void testSaveAllResultsConnectionFailed() throws Exception { when(properties.getServiceType()).thenReturn("passive"); final String queueName = "check_results"; when(properties.getServerQueue()).thenReturn(queueName); final String host = "99.99.99.20"; when(properties.getServerHost()).thenReturn(host); final int port = 4730; when(properties.getServerPort()).thenReturn(port); when(properties.getNagiosHost()).thenReturn("win7sakuli"); when(checkResultBuilder.build()).thenReturn(new NagiosCachedCheckResult(queueName, "sakuli_demo22__2015_03_07_12_59_00_00", testResult)); GearmanClient gearmanClient = mock(GearmanClientImpl.class); doReturn(gearmanClient).when(testling).getGearmanClient(); GearmanJobServerConnection connection = mock(GearmanJobServerConnection.class); doReturn(connection).when(testling).getGearmanConnection(host, port); when(gearmanClient.addJobServer(connection)).thenReturn(false); testling.saveAllResults(); //checks verify(gearmanCacheService, never()).cacheResults(anyList()); verify(gearmanCacheService, never()).getCachedResults(); verify(exceptionHandler).handleException(any(Throwable.class), eq(true)); verify(testling).getGearmanClient(); verify(testling).getGearmanConnection(host, port); verify(gearmanClient).addJobServer(connection); verify(gearmanClient).shutdown(); } @Test public void testSaveAllResultsConnectionFailedCacheResults() throws Exception { when(properties.getServiceType()).thenReturn("passive"); final String queueName = "check_results"; when(properties.getServerQueue()).thenReturn(queueName); final String host = "99.99.99.20"; when(properties.getServerHost()).thenReturn(host); final int port = 4730; when(properties.getServerPort()).thenReturn(port); when(properties.getNagiosHost()).thenReturn("win7sakuli"); when(properties.isCacheEnabled()).thenReturn(true); when(checkResultBuilder.build()).thenReturn(new NagiosCachedCheckResult(queueName, "sakuli_demo22__2015_03_07_12_59_00_00", testResult)); GearmanClient gearmanClient = mock(GearmanClientImpl.class); doReturn(gearmanClient).when(testling).getGearmanClient(); GearmanJobServerConnection connection = mock(GearmanJobServerConnection.class); doReturn(connection).when(testling).getGearmanConnection(host, port); when(gearmanClient.addJobServer(connection)).thenReturn(false); when(gearmanCacheService.getCachedResults()).thenReturn(Collections.emptyList()); doAnswer(invocationOnMock -> { assertEquals(((List) invocationOnMock.getArguments()[0]).size(), 1L); return null; }).when(gearmanCacheService).cacheResults(anyList()); testling.saveAllResults(); //checks verify(gearmanCacheService).cacheResults(anyList()); verify(gearmanCacheService).getCachedResults(); verify(exceptionHandler).handleException(any(Throwable.class), eq(true)); verify(testling).getGearmanClient(); verify(testling).getGearmanConnection(host, port); verify(gearmanClient).addJobServer(connection); verify(gearmanClient).shutdown(); } @Test public void testSaveAllResultsJobSubmitFailedAddCacheResults() throws Exception { when(properties.getServiceType()).thenReturn("passive"); final String queueName = "check_results"; when(properties.getServerQueue()).thenReturn(queueName); final String host = "99.99.99.20"; when(properties.getServerHost()).thenReturn(host); final int port = 4730; when(properties.getServerPort()).thenReturn(port); when(properties.getNagiosHost()).thenReturn("win7sakuli"); when(properties.isCacheEnabled()).thenReturn(true); GearmanClient gearmanClient = mock(GearmanClientImpl.class); doReturn(gearmanClient).when(testling).getGearmanClient(); GearmanJobServerConnection connection = mock(GearmanJobServerConnection.class); doReturn(connection).when(testling).getGearmanConnection(host, port); GearmanJob job = mock(GearmanJob.class); doReturn(job).when(testling).creatJob(any(NagiosCheckResult.class)); when(gearmanClient.addJobServer(connection)).thenReturn(true); when(gearmanClient.submit(job)).thenThrow(new SakuliRuntimeException("Something went wrong!")); NagiosCheckResult mockedResult1 = Mockito.mock(NagiosCheckResult.class); NagiosCheckResult mockedResult2 = Mockito.mock(NagiosCheckResult.class); when(gearmanCacheService.getCachedResults()).thenReturn(Arrays.asList(mockedResult1, mockedResult2)); NagiosCheckResult newResult = new NagiosCachedCheckResult(queueName, "sakuli_demo22__2015_03_07_12_59_00_00", testResult); when(checkResultBuilder.build()).thenReturn(newResult); doAnswer(invocationOnMock -> { List<NagiosCheckResult> results = ((List) invocationOnMock.getArguments()[0]); assertEquals(results.size(), 3L); assertEquals(results.get(0), newResult); assertEquals(results.get(1), mockedResult1); assertEquals(results.get(2), mockedResult2); return null; }).when(gearmanCacheService).cacheResults(anyList()); StringBuilder sendOrder = new StringBuilder(); doAnswer(invocationOnMock -> { Object result = invocationOnMock.getArguments()[1]; Assert.assertTrue(result instanceof NagiosCheckResult); sendOrder.append(result.hashCode()); return invocationOnMock.callRealMethod(); }).when(testling).sendResult(any(), any()); testling.saveAllResults(); //checks assertEquals(sendOrder.toString(), "" + mockedResult2.hashCode() + mockedResult1.hashCode() + newResult.hashCode()); verify(gearmanCacheService).cacheResults(anyList()); verify(gearmanCacheService).getCachedResults(); verify(exceptionHandler, times(3)).handleException(any(Throwable.class), eq(true)); verify(testling).getGearmanClient(); verify(testling).getGearmanConnection(host, port); verify(gearmanClient).addJobServer(connection); verify(gearmanClient).shutdown(); } @Test public void testSaveAllResultsConnectionFailedAddCacheResults() throws Exception { when(properties.getServiceType()).thenReturn("passive"); final String queueName = "check_results"; when(properties.getServerQueue()).thenReturn(queueName); final String host = "99.99.99.20"; when(properties.getServerHost()).thenReturn(host); final int port = 4730; when(properties.getServerPort()).thenReturn(port); when(properties.getNagiosHost()).thenReturn("win7sakuli"); when(properties.isCacheEnabled()).thenReturn(true); GearmanClient gearmanClient = mock(GearmanClientImpl.class); doReturn(gearmanClient).when(testling).getGearmanClient(); GearmanJobServerConnection connection = mock(GearmanJobServerConnection.class); doReturn(connection).when(testling).getGearmanConnection(host, port); GearmanJob job = mock(GearmanJob.class); doReturn(job).when(testling).creatJob(any(NagiosCheckResult.class)); when(gearmanClient.addJobServer(connection)).thenReturn(false); NagiosCheckResult mockedResult1 = Mockito.mock(NagiosCheckResult.class); when(gearmanCacheService.getCachedResults()).thenReturn(Collections.singletonList(mockedResult1)); NagiosCheckResult newResult = new NagiosCachedCheckResult(queueName, "sakuli_demo22__2015_03_07_12_59_00_00", testResult); when(checkResultBuilder.build()).thenReturn(newResult); doAnswer(invocationOnMock -> { List<NagiosCheckResult> results = ((List) invocationOnMock.getArguments()[0]); assertEquals(results.size(), 2L); assertEquals(results.get(0), newResult); assertEquals(results.get(1), mockedResult1); return null; }).when(gearmanCacheService).cacheResults(anyList()); testling.saveAllResults(); //checks verify(gearmanCacheService).cacheResults(anyList()); verify(gearmanCacheService).getCachedResults(); verify(exceptionHandler).handleException(any(Throwable.class), eq(true)); verify(testling).getGearmanClient(); verify(testling).getGearmanConnection(host, port); verify(gearmanClient).addJobServer(connection); verify(gearmanClient).shutdown(); } @Test public void testSaveAllResultsWrongConnectionCacheResults() throws Exception { when(properties.getServiceType()).thenReturn("passive"); final String queueName = "check_results"; when(properties.getServerQueue()).thenReturn(queueName); final String host = "not-resolveable-host.de"; when(properties.getServerHost()).thenReturn(host); final int port = 4730; when(properties.getServerPort()).thenReturn(port); when(properties.getNagiosHost()).thenReturn("win7sakuli"); when(properties.isCacheEnabled()).thenReturn(true); when(checkResultBuilder.build()).thenReturn(new NagiosCachedCheckResult(queueName, "sakuli_demo22__2015_03_07_12_59_00_00", testResult)); GearmanClient gearmanClient = mock(GearmanClientImpl.class); doReturn(gearmanClient).when(testling).getGearmanClient(); GearmanJobServerConnection connection = mock(GearmanJobServerConnection.class); doReturn(connection).when(testling).getGearmanConnection(host, port); when(gearmanClient.addJobServer(connection)).thenThrow(new UnresolvedAddressException()); when(gearmanCacheService.getCachedResults()).thenReturn(Collections.emptyList()); doAnswer(invocationOnMock -> { assertEquals(((List) invocationOnMock.getArguments()[0]).size(), 1L); return null; }).when(gearmanCacheService).cacheResults(anyList()); doAnswer(invocationOnMock -> { Exception exception = (Exception) invocationOnMock.getArguments()[0]; assertRegExMatch(exception.getMessage(), "Could not transfer Sakuli results to the Gearman server.*"); assertEquals(exception.getSuppressed()[0].getClass(), UnresolvedAddressException.class); return null; }).when(exceptionHandler).handleException(any(Throwable.class), anyBoolean()); testling.saveAllResults(); //checks verify(gearmanCacheService).cacheResults(anyList()); verify(gearmanCacheService).getCachedResults(); verify(exceptionHandler).handleException(any(SakuliForwarderException.class), anyBoolean()); verify(testling).getGearmanClient(); verify(testling).getGearmanConnection(host, port); verify(gearmanClient).addJobServer(connection); verify(gearmanClient).shutdown(); } }