// Copyright (c) 2015 Uber Technologies, Inc. // // 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.uber.jenkins.phabricator.utils; import com.cloudbees.plugins.credentials.CredentialsStore; import com.cloudbees.plugins.credentials.SystemCredentialsProvider; import com.cloudbees.plugins.credentials.domains.Domain; import com.uber.jenkins.phabricator.FakeConduit; import com.uber.jenkins.phabricator.LauncherFactory; import com.uber.jenkins.phabricator.PhabricatorPlugin; import com.uber.jenkins.phabricator.conduit.ConduitAPIClient; import com.uber.jenkins.phabricator.conduit.DifferentialClient; import com.uber.jenkins.phabricator.coverage.CodeCoverageMetrics; import com.uber.jenkins.phabricator.credentials.ConduitCredentials; import com.uber.jenkins.phabricator.credentials.ConduitCredentialsImpl; import com.uber.jenkins.phabricator.uberalls.UberallsClient; import com.uber.jenkins.phabricator.unit.UnitResult; import hudson.EnvVars; import hudson.FilePath; import hudson.Launcher; import hudson.model.AbstractBuild; import hudson.model.BuildListener; import hudson.model.FreeStyleProject; import hudson.plugins.cobertura.CoberturaPublisher; import hudson.plugins.cobertura.renderers.SourceEncoding; import hudson.slaves.EnvironmentVariablesNodeProperty; import hudson.tasks.Publisher; import hudson.tasks.junit.JUnitResultArchiver; import hudson.util.CopyOnWriteMap; import net.sf.json.JSONObject; import net.sf.json.groovy.JsonSlurper; import org.apache.http.HttpEntity; import org.apache.http.HttpEntityEnclosingRequest; import org.apache.http.HttpException; import org.apache.http.HttpRequest; import org.apache.http.HttpResponse; import org.apache.http.entity.StringEntity; import org.apache.http.localserver.LocalTestServer; import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpRequestHandler; import org.apache.http.util.EntityUtils; import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.TestBuilder; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.PrintStream; import java.util.*; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; public class TestUtils { public static final String TEST_BASE_URL = "http://uberalls.example.com"; public static final String TEST_REPOSITORY = "test-repository"; public static final String TEST_BRANCH = "test-branch"; public static final String TEST_SHA = "test-sha"; public static final String COBERTURA_XML = "cobertura.xml"; public static final String JUNIT_XML = "junit-test.xml"; public static final String TEST_DIFFERENTIAL_ID = "123"; public static final String TEST_CONDUIT_TOKEN = "notarealtoken"; public static final String TEST_PHID = "PHID-not-real"; public static final String TEST_CREDENTIALS_ID = "not-a-real-uuid-for-credentials"; public static final String TEST_CONDUIT_URL = "http://example.gophers"; public static final String TEST_CONDUIT_GATEWAY = "http://foo.bar"; public static final String TEST_DESCRIPTION = "foobar"; private static final String TEST_UNIT_NAMESPACE = "unit namespace"; private static final String TEST_UNIT_NAME = "fake test name"; public static Logger getDefaultLogger() { return new Logger(new PrintStream(new ByteArrayOutputStream())); } public static UberallsClient getUberallsClient(String baseURL, Logger logger, String repository, String branch) { return spy(new UberallsClient(baseURL, logger, repository, branch)); } public static UberallsClient getDefaultUberallsClient() { return getUberallsClient(TEST_BASE_URL, getDefaultLogger(), TEST_REPOSITORY, TEST_BRANCH); } public static DifferentialClient getDefaultDifferentialClient() { ConduitAPIClient client = mock(ConduitAPIClient.class); return spy(new DifferentialClient(TEST_DIFFERENTIAL_ID, client)); } public static EnvVars getDefaultEnvVars() { return new EnvVars(); } public static LauncherFactory createLauncherFactory(JenkinsRule j) throws Exception { return new LauncherFactory( j.createLocalLauncher(), getDefaultEnvVars(), System.err, new FilePath(j.getWebAppRoot()) ); } public static CodeCoverageMetrics getCodeCoverageMetrics(float packagesCoveragePercent, float filesCoveragePercent, float classesCoveragePercent, float methodCoveragePercent, float lineCoveragePercent, float conditionalCoveragePercent) { return spy(new CodeCoverageMetrics(packagesCoveragePercent, filesCoveragePercent, classesCoveragePercent, methodCoveragePercent, lineCoveragePercent, conditionalCoveragePercent)); } public static CodeCoverageMetrics getDefaultCodeCoverageMetrics() { return getCodeCoverageMetrics(100.0f, 100.0f, 100.0f, 100.0f, 100.0f, 100.0f); } public static CodeCoverageMetrics getCoverageResult(Float packageCoverage, Float filesCoverage, Float classesCoverage, Float methodCoverage, Float linesCoverage) { return new CodeCoverageMetrics( packageCoverage, filesCoverage, classesCoverage, methodCoverage, linesCoverage, 0.0f ); } public static CodeCoverageMetrics getEmptyCoverageMetrics() { return new CodeCoverageMetrics(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); } public static JSONObject getJSONFromFile(Class klass, String filename) throws IOException { InputStream in = klass.getResourceAsStream(String.format("%s.json", filename)); return slurpFromInputStream(in); } private static JSONObject slurpFromInputStream(InputStream in) throws IOException { return (JSONObject) new JsonSlurper().parse(in); } public static HttpRequestHandler makeHttpHandler(final int statusCode, final String body) { ArrayList<String> requestBodies = new ArrayList<String>(); return makeHttpHandler(statusCode, body, requestBodies); } public static HttpRequestHandler makeHttpHandler(final int statusCode, final String body, final List<String> requestBodies) { return new HttpRequestHandler() { @Override public void handle(HttpRequest request, HttpResponse response, HttpContext context) throws HttpException, IOException { response.setStatusCode(statusCode); response.setEntity(new StringEntity(body)); if (request instanceof HttpEntityEnclosingRequest) { HttpEntity entity = ((HttpEntityEnclosingRequest)request).getEntity(); requestBodies.add(EntityUtils.toString(entity)); } else { requestBodies.add(""); } } }; } public static void setEnvironmentVariables(JenkinsRule j, Map<String, String> params) throws IOException { EnvironmentVariablesNodeProperty prop = new EnvironmentVariablesNodeProperty(); EnvVars envVars = prop.getEnvVars(); envVars.putAll(params); j.jenkins.getGlobalNodeProperties().add(prop); } public static Map<String, String> getValidBuildEnvironment(boolean harbormaster) { Map<String, String> params = new HashMap<String, String>(); params.put(PhabricatorPlugin.DIFFERENTIAL_ID_FIELD, TEST_DIFFERENTIAL_ID); if (harbormaster) { params.put(PhabricatorPlugin.PHID_FIELD, TEST_PHID); } return params; } public static Map<String, String> getValidCommitEnvironment() { Map<String, String> params = new HashMap<String, String>(); params.put(PhabricatorPlugin.PHID_FIELD, TEST_PHID); return params; } public static void setDefaultBuildEnvironment(JenkinsRule j) throws IOException { setDefaultBuildEnvironment(j, true); } public static void setDefaultBuildEnvironment(JenkinsRule j, boolean harbormaster) throws IOException { setEnvironmentVariables(j, getValidBuildEnvironment(harbormaster)); } public static void setDefaultBuildEnvironmentForCommits(JenkinsRule j) throws IOException { setEnvironmentVariables(j, getValidCommitEnvironment()); } public static ConduitCredentials getConduitCredentials(String url, String gateway) { return new ConduitCredentialsImpl(TEST_CREDENTIALS_ID, url, gateway, TEST_DESCRIPTION, TEST_CONDUIT_TOKEN); } public static ConduitCredentials getConduitCredentials(String conduitURI) { return getConduitCredentials(conduitURI, conduitURI); } public static ConduitCredentials getDefaultConduitCredentials() { return getConduitCredentials(TEST_CONDUIT_URL); } private static void addCredentials(ConduitCredentials credentials) throws IOException { CredentialsStore store = new SystemCredentialsProvider.UserFacingAction().getStore(); store.addCredentials(Domain.global(), credentials); } public static void addInvalidCredentials() throws IOException { addCredentials(TestUtils.getDefaultConduitCredentials()); } public static void addValidCredentials(FakeConduit conduit) throws IOException { addCredentials(TestUtils.getConduitCredentials(conduit.uri())); } public static String getTestServerAddress(LocalTestServer server) { return String.format( "http://%s:%s", server.getServiceAddress().getHostName(), server.getServiceAddress().getPort() ); } public static Map<String, List<Integer>> getDefaultLineCoverage() { Map<String, List<Integer>> coverage = new HashMap<String, List<Integer>>(); List<Integer> lineCoverage = new ArrayList<Integer>(Arrays.asList( null, 2, 0, 1 )); coverage.put("file.go", lineCoverage); return coverage; } public static CoberturaPublisher getDefaultCoberturaPublisher() { return new CoberturaPublisher( COBERTURA_XML, true, false, false, false, false, false, false, SourceEncoding.UTF_8, 1 ); } public static UnitResult getDefaultUnitResult() { return new UnitResult( TEST_UNIT_NAMESPACE, TEST_UNIT_NAME, null, 1.0f, 0, 0, 1 ); } public static Publisher getDefaultXUnitPublisher() { return new JUnitResultArchiver( JUNIT_XML ); } public static void addCopyBuildStep(FreeStyleProject p, final String fileName, final Class resourceClass, final String resourceName) { p.getBuildersList().add(new TestBuilder() { @Override public boolean perform(AbstractBuild build, Launcher launcher, BuildListener buildListener) throws InterruptedException, IOException { build.getWorkspace().child(fileName).copyFrom(resourceClass.getResourceAsStream(resourceName)); return true; } }); } }