// Copyright 2013-2019 Michel Kraemer // // 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 de.undercouch.gradle.tasks.download; import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.http.trafficlistener.DoNothingWiremockNetworkTrafficListener; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Test; import java.io.File; import java.io.FileOutputStream; import java.io.FilenameFilter; import java.io.OutputStream; import java.net.Socket; import java.nio.ByteBuffer; import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; import static com.github.tomakehurst.wiremock.client.WireMock.get; import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.options; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; /** * Tests if a file can be downloaded to a temporary location and then * moved to the final location * @author Michel Kraemer */ public class TempAndMoveTest extends TestBase { private static final String TEMPANDMOVE = "tempandmove"; private static final String CONTENTS = "Hello world"; private File dst; private File downloadTaskDir; private boolean checkDstDoesNotExist; /** * Run a mock HTTP server with a network listener */ public WireMockServer tempAndMoveWireMock; @Override public void setUp() throws Exception { super.setUp(); tempAndMoveWireMock = new WireMockServer(options() .dynamicPort() .networkTrafficListener(new TempAndMoveNetworkTrafficListener()) .jettyStopTimeout(10000L)); tempAndMoveWireMock.start(); } @After public void tearDown() { tempAndMoveWireMock.stop(); } private class TempAndMoveNetworkTrafficListener extends DoNothingWiremockNetworkTrafficListener { @Override public void opened(Socket socket) { // at the beginning there should be no dest file and no temp file if (checkDstDoesNotExist) { assertFalse(dst.exists()); } assertNull(getTempFile()); } @Override public void outgoing(Socket socket, ByteBuffer bytes) { // wait for temporary file (max. 10 seconds) File tempFile = null; for (int i = 0; i < 100; ++i) { tempFile = getTempFile(); if (tempFile != null) { break; } try { Thread.sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } } // temp file should now exist, but dest file not if (checkDstDoesNotExist) { assertFalse(dst.exists()); } assertNotNull(tempFile); } } private File getTempFile() { File[] files = downloadTaskDir.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.startsWith(dst.getName()) && name.endsWith(".part"); } }); if (files == null) { // downloadTaskDir does not exist return null; } if (files.length > 1) { fail("Multiple temp files in " + downloadTaskDir); } return files.length == 1 ? files[0] : null; } private void testTempAndMove(boolean createDst) throws Exception { tempAndMoveWireMock.stubFor(get(urlEqualTo("/" + TEMPANDMOVE)) .willReturn(aResponse() .withBody(CONTENTS))); Download t = makeProjectAndTask(); downloadTaskDir = t.getDownloadTaskDir(); String src = tempAndMoveWireMock.url(TEMPANDMOVE); t.src(src); dst = folder.newFile(); checkDstDoesNotExist = !createDst; if (createDst) { dst = folder.newFile(); OutputStream os = new FileOutputStream(dst); os.close(); } else { // make sure dest does not exist, so we can verify correctly assertTrue(dst.delete()); } t.dest(dst); t.tempAndMove(true); t.execute(); assertTrue(dst.exists()); assertNull(getTempFile()); String dstContents = FileUtils.readFileToString(dst); assertEquals(CONTENTS, dstContents); } /** * Tests if a file can be downloaded to a temporary location and then * moved to the final location * @throws Exception if anything else goes wrong */ @Test public void tempAndMove() throws Exception { testTempAndMove(false); } /** * Tests if a file can be downloaded to a temporary location and then * moved to the final location overwriting existing file * @throws Exception if anything else goes wrong */ @Test public void tempAndMoveOverwrite() throws Exception { testTempAndMove(true); } }