de.undercouch.gradle.tasks.download.TestBase.java Source code

Java tutorial

Introduction

Here is the source code for de.undercouch.gradle.tasks.download.TestBase.java

Source

// Copyright 2013-2016 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 java.io.File;
import java.io.IOException;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.gradle.api.Project;
import org.gradle.testfixtures.ProjectBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.rules.TemporaryFolder;
import org.mortbay.jetty.Handler;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.handler.DefaultHandler;
import org.mortbay.jetty.handler.HandlerList;
import org.mortbay.jetty.handler.ResourceHandler;
import org.mortbay.resource.Resource;

/**
 * Base class for unit tests
 * @author Michel Kraemer
 */
public abstract class TestBase {
    /**
     * File name of the first test file
     */
    protected final static String TEST_FILE_NAME = "test.txt";

    /**
     * File name of the second test file
     */
    protected final static String TEST_FILE_NAME2 = "test2.txt";

    /**
     * Host name of the local machine
     */
    protected static String localHostName;

    /**
     * Parent directory of {@link #projectDir}
     */
    private File parentDir;

    /**
     * A temporary directory where a virtual test project is stored
     */
    protected File projectDir;

    /**
     * A folder for temporary files
     */
    @Rule
    public TemporaryFolder folder = new TemporaryFolder();

    /**
     * The HTTP server to test against
     */
    private Server server;

    /**
     * Contents of the first test file with the name {@link #TEST_FILE_NAME}
     */
    protected byte[] contents;

    /**
     * Contents of the second test file with the name {@link #TEST_FILE_NAME2}
     */
    protected byte[] contents2;

    /**
     * @return the HTTP server used for testing
     */
    protected Server createServer() {
        //run server on any free port
        return new Server(0);
    }

    /**
     * Runs an embedded HTTP server and creates test files to serve
     * @throws Exception if the server could not be started
     */
    @Before
    public void setUp() throws Exception {
        server = createServer();

        HandlerList handlers = new HandlerList();
        handlers.setHandlers(makeHandlers());
        server.setHandler(handlers);
        server.start();

        //create temporary files
        contents = new byte[4096];
        contents2 = new byte[4096];
        for (int i = 0; i < contents.length; ++i) {
            contents[i] = (byte) (Math.random() * 255);
            contents2[i] = (byte) (Math.random() * 255);
        }

        parentDir = folder.newFolder("test");
        projectDir = new File(parentDir, "project");

        File testFile = folder.newFile(TEST_FILE_NAME);
        FileUtils.writeByteArrayToFile(testFile, contents);
        File testFile2 = folder.newFile(TEST_FILE_NAME2);
        FileUtils.writeByteArrayToFile(testFile2, contents2);
    }

    /**
     * Gets the local host name to use for the tests
     * @throws UnknownHostException if the local host name could not be
     * resolved into an address
     * @throws SocketException if an I/O error occurs
     */
    @BeforeClass
    public static void setUpClass() throws UnknownHostException, SocketException {
        try {
            InetAddress.getByName("localhost.localdomain");
            localHostName = "localhost.localdomain";
        } catch (UnknownHostException e) {
            localHostName = findSiteLocal();
            if (localHostName == null) {
                localHostName = InetAddress.getLocalHost().getCanonicalHostName();
            }
        }
    }

    /**
     * Get a site local IP4 address from the current node's interfaces
     * @return the IP address or <code>null</code> if the address
     * could not be obtained
     * @throws SocketException if an I/O error occurs
     */
    private static String findSiteLocal() throws SocketException {
        Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
        while (interfaces.hasMoreElements()) {
            NetworkInterface n = interfaces.nextElement();
            Enumeration<InetAddress> addresses = n.getInetAddresses();
            while (addresses.hasMoreElements()) {
                InetAddress i = addresses.nextElement();
                if (i.isSiteLocalAddress() && i instanceof Inet4Address) {
                    return i.getHostAddress();
                }
            }
        }
        return null;
    }

    /**
     * Make the handlers for the HTTP server to test against
     * @return the handlers
     * @throws IOException if the handlers could not be created
     */
    protected Handler[] makeHandlers() throws IOException {
        //serve resources from temporary folder
        ResourceHandler resourceHandler = new ResourceHandler();
        resourceHandler.setBaseResource(Resource.newResource(folder.getRoot().getAbsolutePath()));
        return new Handler[] { resourceHandler, new DefaultHandler() };
    }

    /**
     * Stops the embedded HTTP server
     * @throws Exception if the server could not be stopped
     */
    @After
    public void tearDown() throws Exception {
        server.stop();
    }

    /**
     * Find a free socket port
     * @return the number of the free port
     * @throws IOException if an IO error occurred
     */
    protected static int findPort() throws IOException {
        ServerSocket socket = null;
        try {
            socket = new ServerSocket(0);
            return socket.getLocalPort();
        } finally {
            if (socket != null) {
                socket.close();
            }
        }
    }

    /**
     * Makes a Gradle project and creates a download task
     * @return the unconfigured download task
     */
    protected Download makeProjectAndTask() {
        Project parent = ProjectBuilder.builder().withProjectDir(parentDir).build();
        Project project = ProjectBuilder.builder().withParent(parent).withProjectDir(projectDir).build();

        Map<String, Object> applyParams = new HashMap<String, Object>();
        applyParams.put("plugin", "de.undercouch.download");
        project.apply(applyParams);

        Map<String, Object> taskParams = new HashMap<String, Object>();
        taskParams.put("type", Download.class);
        Download t = (Download) project.task(taskParams, "downloadFile");
        return t;
    }

    /**
     * @return the port the embedded HTTP server is listening to
     */
    protected int getServerPort() {
        return server.getConnectors()[0].getLocalPort();
    }

    /**
     * Makes a URL for a file provided by the embedded HTTP server
     * @param fileName the file's name
     * @return the URL
     */
    protected String makeSrc(String fileName) {
        return "http://" + localHostName + ":" + getServerPort() + "/" + fileName;
    }
}