/*
* The MIT License
*
* Copyright (c) 2014 Ericsson
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.sonyericsson.hudson.plugins.gerrit.trigger.playback;
import com.github.tomakehurst.wiremock.http.Fault;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.sonyericsson.hudson.plugins.gerrit.trigger.GerritServer;
import com.sonyericsson.hudson.plugins.gerrit.trigger.PluginImpl;
import com.sonyericsson.hudson.plugins.gerrit.trigger.config.IGerritHudsonTriggerConfig;
import com.sonyericsson.hudson.plugins.gerrit.trigger.mock.Setup;
import com.sonyericsson.hudson.plugins.gerrit.trigger.utils.GerritPluginChecker;
import com.sonyericsson.hudson.plugins.gerrit.trigger.utils.MockPluginCheckerConfig;
import com.sonymobile.tools.gerrit.gerritevents.GerritHandler;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.GerritTriggeredEvent;
import com.sonymobile.tools.gerrit.gerritevents.dto.events.PatchsetCreated;
import hudson.XmlFile;
import jenkins.model.Jenkins;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyObject;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.when;
import static org.powermock.api.mockito.PowerMockito.mock;
/**
*
* missed events tests for events-log plugin interaction.
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Jenkins.class, PluginImpl.class, GerritMissedEventsPlaybackManager.class, GerritPluginChecker.class })
@PowerMockIgnore("javax.net.ssl.*")
public class GerritMissedEventsPlaybackManagerTest {
/**
* regexp for change events plugin.
*/
public static final String EVENTS_LOG_CHANGE_EVENTS_URL_REGEXP = ".+plugins/events-log/events/.+";
/**
* instance of WireMockRule.
*/
// CS IGNORE VisibilityModifier FOR NEXT 2 LINES. REASON: WireMockRule.
@Rule
public final WireMockRule wireMockRule = new WireMockRule(0); // No-args constructor defaults to port 8089
private XmlFile xmlFile;
private static final int SLEEPTIME = 500;
private static final int HTTPOK = 200;
/**
* Default constructor.
*/
public GerritMissedEventsPlaybackManagerTest() {
}
/**
* Create ReplicationQueueTaskDispatcher with a mocked GerritHandler.
* @throws IOException if it occurs.
*/
@Before
public void setUp() throws IOException {
Jenkins jenkinsMock = mock(Jenkins.class);
PowerMockito.mockStatic(Jenkins.class);
when(Jenkins.getInstance()).thenReturn(jenkinsMock);
PluginImpl plugin = PowerMockito.mock(PluginImpl.class);
GerritServer server = mock(GerritServer.class);
MockPluginCheckerConfig config = new MockPluginCheckerConfig();
config.setGerritFrontEndURL("http://localhost:" + wireMockRule.port());
config.setUseRestApi(true);
config.setGerritHttpUserName("user");
config.setGerritHttpPassword("passwd");
when(plugin.getServer(any(String.class))).thenReturn(server);
GerritHandler handler = mock(GerritHandler.class);
when(plugin.getHandler()).thenReturn(handler);
when(server.getConfig()).thenReturn(config);
PowerMockito.when(PluginImpl.getInstance()).thenReturn(plugin);
PowerMockito.mockStatic(GerritMissedEventsPlaybackManager.class);
File tmpFile = null;
try {
tmpFile = File.createTempFile("gerrit-server-timestamps", ".xml");
} catch (IOException e) {
fail("Failed to create Temp File");
}
tmpFile.deleteOnExit();
PrintWriter out = null;
try {
out = new PrintWriter(tmpFile);
} catch (FileNotFoundException e) {
fail("Failed to write to Temp File");
}
String text = "<?xml version='1.0' encoding='UTF-8'?>\n"
+ "<com.sonyericsson.hudson.plugins.gerrit.trigger.playback.EventTimeSlice "
+ "plugin='gerrit-trigger@2.14.0-SNAPSHOT'>"
+ "<timeSlice>1430244884000</timeSlice>"
+ "<events>"
+ "</events>"
+ "</com.sonyericsson.hudson.plugins.gerrit.trigger.playback.EventTimeSlice>";
out.println(text);
out.close();
xmlFile = new XmlFile(tmpFile);
PowerMockito.when(GerritMissedEventsPlaybackManager.getConfigXml("defaultServer")).thenReturn(xmlFile);
PowerMockito.mockStatic(GerritPluginChecker.class);
PowerMockito.when(GerritPluginChecker.isPluginEnabled((IGerritHudsonTriggerConfig)anyObject()
, anyString())).thenReturn(true);
}
/**
* returns a GerritMissedEventsPlaybackManager.
* @return GerritMissedEventsPlaybackManager.
*/
private GerritMissedEventsPlaybackManager setupManager() {
GerritMissedEventsPlaybackManager missingEventsPlaybackManager
= new GerritMissedEventsPlaybackManager("defaultServer");
try {
missingEventsPlaybackManager.load();
} catch (IOException e) {
fail(e.getMessage());
}
assertNotNull(missingEventsPlaybackManager.serverTimestamp);
assertTrue("should be true", missingEventsPlaybackManager.isSupported());
PatchsetCreated patchsetCreated = Setup.createPatchsetCreated("someGerritServer", "someProject",
"refs/heads/master");
patchsetCreated.setReceivedOn(System.currentTimeMillis());
missingEventsPlaybackManager.gerritEvent(patchsetCreated);
patchsetCreated.setReceivedOn(System.currentTimeMillis());
missingEventsPlaybackManager.gerritEvent(patchsetCreated);
try {
Thread.currentThread().sleep(SLEEPTIME);
} catch (InterruptedException e) {
fail(e.getMessage());
}
missingEventsPlaybackManager.connectionDown();
missingEventsPlaybackManager
= new GerritMissedEventsPlaybackManager("defaultServer");
try {
missingEventsPlaybackManager.load();
} catch (IOException e) {
fail(e.getMessage());
}
return missingEventsPlaybackManager;
}
/**
* Given a Gerrit Server with Events-Log plugin installed
* When we request the events from a time range
* Then we receive the response in JSON
* And we can convert to events.
*/
@Test
public void testConvertJSONToEvents() {
GerritMissedEventsPlaybackManager missingEventsPlaybackManager =
setupManager();
String json = "{\"type\":\"patchset-created\",\"change\":{\"project\":\""
+ "testProject"
+ "\",\"branch\":\"develop\","
+ "\"id\":\"Icae2322236e0e521950a0232effda08d6ffcdab7\",\"number\":\"392335\",\"subject\":\""
+ "IPSEC: Small test code fixes due to Sonar warnings\",\"owner\":{\"name\":\"Szymon L\","
+ "\"email\":\"szymon.l@abc.com\",\"username\":\"eszyabc\"},\"url\":"
+ "\"https://abc.aaa.se/392335\","
+ "\"commitMessage\":\"IPSEC: Small test code fixes due to Sonar warnings\\n\\nChange-Id: "
+ "Icae2322236e0e521950a0232effda08d6ffcdab7\\nSigned-off-by:Szymon L \\u003cszymo"
+ "n.l@abc.com\\u003e\\n\",\"status\":\"NEW\"},\"patchSet\":{\"number\":\"2\",\"revision"
+ "\":\"607eea8f472235b3ee47483b630003250764dab2\",\"parents\":"
+ "[\"87c0e57d2497ab334584ec9d1a7953ebcf016e10\"],"
+ "\"ref\":\"refs/changes/35/392335/2\",\"uploader\":{\"name\":\"Szymon L\",\"email\":"
+ "\"szymon"
+ "@abc.com\",\"username\":\"eszyabc\"},\"createdOn\":1413448337,\"author\":{\"name\":\"Szy"
+ "mon L\",\"email\":\"szymon.l@abc.com\",\"username\":\"eszyabc\"},\"isDraft\""
+ ":false,\""
+ "sizeInsertions\":6,\"sizeDeletions\":-7},\"author\":{\"name\":\"Build user for \","
+ "\"email\":\"tnbuilder@"
+ "abc.se\",\"username\":\"tnabc\"},\"approvals\":[{\"type\":\"Verified\""
+ ",\"description\":"
+ "\"Verified\",\"value\":\"-1\"}],\"comment\":\"Patch Set 2: Verified-1\\n\\nBuild Failed \\n\\nhttp:"
+ "//jenkins/tn/job/tn-review/22579/ : FAILURE\"}\n";
stubFor(get(urlMatching(EVENTS_LOG_CHANGE_EVENTS_URL_REGEXP))
.willReturn(aResponse()
.withStatus(HTTPOK)
.withHeader("Content-Type", "text/html")
.withBody(json)));
List<GerritTriggeredEvent> events = new ArrayList<GerritTriggeredEvent>();
try {
events = missingEventsPlaybackManager.getEventsFromDateRange(
missingEventsPlaybackManager.getDateFromTimestamp());
} catch (IOException e) {
fail(e.getMessage());
}
Assert.assertTrue("Should have 1 event", events.size() == 1);
}
/**
* Given a Gerrit Server with Events-log plugin installed
* When we request the events from a time range
* And we receive a malformed response
* Then we log an error
* And we return an empty set of events.
*/
@Test
public void testHandleMalformedConnection() {
GerritMissedEventsPlaybackManager missingEventsPlaybackManager =
setupManager();
stubFor(get(urlMatching(EVENTS_LOG_CHANGE_EVENTS_URL_REGEXP))
.willReturn(aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK)));
List<GerritTriggeredEvent> events = new ArrayList<GerritTriggeredEvent>();
try {
events = missingEventsPlaybackManager.getEventsFromDateRange(
missingEventsPlaybackManager.getDateFromTimestamp());
} catch (IOException e) {
fail(e.getMessage());
}
Assert.assertTrue("Should have 0 event", events.size() == 0);
}
/**
* Given a Gerrit Server with Events-log plugin installed
* When we request the events from a time range
* And we receive a malformed response
* Then we log an error
* And we return an empty set of events.
*/
@Test
public void testHandleEmptyResponse() {
GerritMissedEventsPlaybackManager missingEventsPlaybackManager =
setupManager();
stubFor(get(urlMatching(EVENTS_LOG_CHANGE_EVENTS_URL_REGEXP))
.willReturn(aResponse().withFault(Fault.EMPTY_RESPONSE)));
List<GerritTriggeredEvent> events = new ArrayList<GerritTriggeredEvent>();
try {
events = missingEventsPlaybackManager.getEventsFromDateRange(
missingEventsPlaybackManager.getDateFromTimestamp());
} catch (IOException e) {
fail(e.getMessage());
}
Assert.assertTrue("Should have 0 event", events.size() == 0);
}
/**
* Given a Gerrit Server with Events-log plugin installed
* When we request the events from a time range
* And we receive garbage as a response
* Then we log an error
* And we return an empty set of events.
*/
@Test
public void testHandleGarbageResponse() {
GerritMissedEventsPlaybackManager missingEventsPlaybackManager =
setupManager();
stubFor(get(urlMatching(EVENTS_LOG_CHANGE_EVENTS_URL_REGEXP))
.willReturn(aResponse().withFault(Fault.RANDOM_DATA_THEN_CLOSE)));
List<GerritTriggeredEvent> events = new ArrayList<GerritTriggeredEvent>();
try {
events = missingEventsPlaybackManager.getEventsFromDateRange(
missingEventsPlaybackManager.getDateFromTimestamp());
} catch (IOException e) {
fail(e.getMessage());
}
Assert.assertTrue("Should have 0 event", events.size() == 0);
}
}