/* * Copyright 2017 ThoughtWorks, Inc. * * 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 com.thoughtworks.go.domain.builder; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.zip.Deflater; import com.thoughtworks.go.domain.*; import com.thoughtworks.go.util.HttpService; import com.thoughtworks.go.util.TestFileUtil; import com.thoughtworks.go.util.TestingClock; import com.thoughtworks.go.util.URLService; import com.thoughtworks.go.util.ZipUtil; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.Mockito; import static javax.servlet.http.HttpServletResponse.SC_OK; import static org.hamcrest.core.Is.is; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.Mockito.when; public class FetchArtifactBuilderTest { private File zip; private List<File> toClean = new ArrayList<>(); private static final String URL = "http://10.18.7.51:8153/go/remoting/files/cruise/1.0.2341/dev/1/windows-3/cruise-output/console.log"; private File dest; private TestingClock clock; private StubGoPublisher publisher; private ChecksumFileHandler checksumFileHandler; private URLService urlService; private DownloadAction downloadAction; @Before public void setUp() throws Exception { File folder = TestFileUtil.createTempFolder("log"); File consolelog = new File(folder, "console.log"); folder.mkdirs(); consolelog.createNewFile(); zip = new ZipUtil().zip(folder, TestFileUtil.createUniqueTempFile(folder.getName()), Deflater.NO_COMPRESSION); toClean.add(folder); toClean.add(zip); dest = new File("dest"); dest.mkdirs(); toClean.add(dest); clock = new TestingClock(); publisher = new StubGoPublisher(); checksumFileHandler = mock(ChecksumFileHandler.class); urlService = mock(URLService.class); downloadAction = mock(DownloadAction.class); } @After public void tearDown() throws Exception { for (File fileToClean : toClean) { FileUtils.deleteQuietly(fileToClean); } } @Test public void shouldUnzipWhenFetchingFolder() throws Exception { ChecksumFileHandler checksumFileHandler = mock(ChecksumFileHandler.class); when(checksumFileHandler.handleResult(SC_OK, publisher)).thenReturn(true); File destOnAgent = new File("pipelines/cruise/", dest.getPath()); FetchArtifactBuilder builder = getBuilder(new JobIdentifier("cruise", -10, "1", "dev", "1", "windows", 1L), "log", dest.getPath(), new DirHandler("log",destOnAgent), checksumFileHandler); builder.fetch(new DownloadAction(new StubFetchZipHttpService(), publisher, clock), new StubURLService()); assertDownloaded(destOnAgent); } @Test public void shouldSaveFileWhenFetchingFile() throws Exception { ChecksumFileHandler checksumFileHandler = mock(ChecksumFileHandler.class); when(checksumFileHandler.handleResult(SC_OK, publisher)).thenReturn(true); File artifactOnAgent = new File("pipelines/cruise/a.jar"); toClean.add(artifactOnAgent); FetchArtifactBuilder builder = getBuilder(new JobIdentifier("cruise", -1, "1", "dev", "1", "windows", 1L), "log", "some where do download", new FileHandler(artifactOnAgent, getSrc()), checksumFileHandler); builder.fetch(new DownloadAction(new StubFetchZipHttpService(), publisher, clock), new StubURLService()); assertThat(artifactOnAgent.isFile(), is(true)); } private String getSrc() { return ""; } @Test public void shouldReturnURLWithoutSHA1WhenFileDoesNotExist() throws Exception { String src = "cruise-output/console.log"; File destOnAgent = new File("pipelines" + '/' + "cruise" + '/' + dest); File consolelog = new File(destOnAgent, "console.log"); consolelog.delete(); FetchArtifactBuilder builder = getBuilder(new JobIdentifier("foo", -1, "label-1", "dev", "1", "linux", 1L), src, "lib/a.jar", new FileHandler(consolelog, getSrc()), checksumFileHandler); when(urlService.baseRemoteURL()).thenReturn("http://foo.bar:8153/go"); when(checksumFileHandler.url("http://foo.bar:8153/go", "foo/label-1/dev/1/linux")).thenReturn("http://foo.bar:8153/go/files/foo/label-1/dev/1/linux/cruise-output/md5.checksum"); java.util.Properties properties = new java.util.Properties(); when(checksumFileHandler.getArtifactMd5Checksums()).thenReturn(new ArtifactMd5Checksums(properties)); builder.fetch(downloadAction, urlService); verify(downloadAction).perform(Mockito.eq("http://foo.bar:8153/go/files/foo/label-1/dev/1/linux/cruise-output/md5.checksum"), any(FetchHandler.class)); verify(downloadAction).perform(Mockito.eq("http://foo.bar:8153/go/remoting/files/foo/label-1/dev/1/linux/cruise-output/console.log"), any(ChecksumFileHandler.class)); verifyNoMoreInteractions(downloadAction); } @Test public void shouldReturnURLWithSHA1WhenFileExists() throws Exception { String src = "cruise-output/console.log"; File destOnAgent = new File("pipelines" + '/' + "cruise" + '/' + dest); File consolelog = new File(destOnAgent, "console.log"); consolelog.getParentFile().mkdirs(); consolelog.createNewFile(); toClean.add(destOnAgent); FetchArtifactBuilder builder = getBuilder(new JobIdentifier("foo", -1, "label-1", "dev", "1", "linux", 1L), src, "lib/a.jar", new FileHandler(consolelog, getSrc()), checksumFileHandler); when(urlService.baseRemoteURL()).thenReturn("http://foo.bar:8153/go"); when(checksumFileHandler.url("http://foo.bar:8153/go", "foo/label-1/dev/1/linux")).thenReturn("http://foo.bar:8153/go/files/foo/label-1/dev/1/linux/cruise-output/md5.checksum"); java.util.Properties properties = new java.util.Properties(); when(checksumFileHandler.getArtifactMd5Checksums()).thenReturn(new ArtifactMd5Checksums(properties)); builder.fetch(downloadAction, urlService); verify(downloadAction).perform(Mockito.eq("http://foo.bar:8153/go/files/foo/label-1/dev/1/linux/cruise-output/md5.checksum"), any(FetchHandler.class)); verify(downloadAction).perform(Mockito.eq("http://foo.bar:8153/go/remoting/files/foo/label-1/dev/1/linux/cruise-output/console.log?sha1=2jmj7l5rSw0yVb%2FvlWAYkK%2FYBwk%3D"), any(ChecksumFileHandler.class)); verifyNoMoreInteractions(downloadAction); } @Test public void shouldReturnURLEndsWithDotZipWhenRequestingFolder() throws Exception { String src = "cruise-output"; File destOnAgent = new File("pipelines/cruise/", dest.getPath()); FetchArtifactBuilder builder = getBuilder(new JobIdentifier("foo", -1, "label-1", "dev", "1", "linux", 1L), src, "lib/a.jar", new DirHandler(src, destOnAgent), checksumFileHandler); when(urlService.baseRemoteURL()).thenReturn("http://foo.bar:8153/go"); when(checksumFileHandler.url("http://foo.bar:8153/go", "foo/label-1/dev/1/linux")).thenReturn("http://foo.bar:8153/go/files/foo/label-1/dev/1/linux/cruise-output/md5.checksum"); java.util.Properties properties = new java.util.Properties(); when(checksumFileHandler.getArtifactMd5Checksums()).thenReturn(new ArtifactMd5Checksums(properties)); builder.fetch(downloadAction, urlService); verify(downloadAction).perform(Mockito.eq("http://foo.bar:8153/go/files/foo/label-1/dev/1/linux/cruise-output/md5.checksum"), any(FetchHandler.class)); verify(downloadAction).perform(Mockito.eq("http://foo.bar:8153/go/remoting/files/foo/label-1/dev/1/linux/cruise-output.zip"), any(ChecksumFileHandler.class)); verifyNoMoreInteractions(downloadAction); } @Test public void shouldValidateChecksumOnArtifact() throws Exception { when(urlService.baseRemoteURL()).thenReturn("http://10.10.1.1/go/files"); when(checksumFileHandler.url("http://10.10.1.1/go/files", "cruise/10/dev/1/windows")).thenReturn("http://10.10.1.1/go/files/cruise/10/dev/1/windows/cruise-output/md5.checksum"); FetchArtifactBuilder builder = getBuilder(new JobIdentifier("cruise", 10, "1", "dev", "1", "windows", 1L), "log", dest.getPath(), mock(FetchHandler.class), checksumFileHandler); builder.fetch(downloadAction, urlService); verify(downloadAction).perform("http://10.10.1.1/go/files/cruise/10/dev/1/windows/cruise-output/md5.checksum", checksumFileHandler); } @Test public void shouldMakeTheFetchHandlerUseTheArtifactMd5Checksum() throws Exception { ArtifactMd5Checksums artifactMd5Checksums = mock(ArtifactMd5Checksums.class); when(urlService.baseRemoteURL()).thenReturn("http://10.10.1.1/go/files"); when(checksumFileHandler.url("http://10.10.1.1/go/files", "cruise/10/dev/1/windows")).thenReturn("http://10.10.1.1/go/files/cruise/10/dev/1/windows/cruise-output/md5.checksum"); when(checksumFileHandler.getArtifactMd5Checksums()).thenReturn(artifactMd5Checksums); FetchHandler fetchHandler = mock(FetchHandler.class); FetchArtifactBuilder builder = getBuilder(new JobIdentifier("cruise", 10, "1", "dev", "1", "windows", 1L), "log", dest.getPath(), fetchHandler, checksumFileHandler); builder.fetch(downloadAction, urlService); verify(fetchHandler).useArtifactMd5Checksums(artifactMd5Checksums); } private FetchArtifactBuilder getBuilder(JobIdentifier jobLocator, String srcdir, String dest, FetchHandler handler, final ChecksumFileHandler checksumFileHandler) { return new FetchArtifactBuilder(new RunIfConfigs(), new NullBuilder(), "", jobLocator, srcdir, dest, handler, checksumFileHandler); } private class StubFetchZipHttpService extends HttpService { public int download(String url, FetchHandler handler) throws IOException { handler.handle(new FileInputStream(zip)); return SC_OK; } } private static class StubURLService extends URLService { public String baseRemoteURL() { return ""; } } private void assertDownloaded(File destOnAgent) { File logFolder = new File(destOnAgent, "log"); assertThat(logFolder.exists(), is(true)); assertThat(logFolder.isDirectory(), is(true)); assertThat(new File(logFolder, "console.log").exists(), is(true)); assertThat(destOnAgent.listFiles(), is(new File[]{logFolder})); } }