Package com.aragost.javahg.test

Source Code of com.aragost.javahg.test.AbstractTestCase$ServeState

/*
* #%L
* JavaHg
* %%
* Copyright (C) 2011 aragost Trifork ag
* %%
* 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.
* #L%
*/
package com.aragost.javahg.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.Charset;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.runner.RunWith;

import com.aragost.javahg.BaseRepository;
import com.aragost.javahg.Changeset;
import com.aragost.javahg.HgVersion;
import com.aragost.javahg.Repository;
import com.aragost.javahg.RepositoryConfiguration;
import com.aragost.javahg.RepositoryConfiguration.CachePolicy;
import com.aragost.javahg.commands.AddCommand;
import com.aragost.javahg.commands.CommitCommand;
import com.aragost.javahg.commands.UpdateCommand;
import com.aragost.javahg.commands.VersionCommand;
import com.aragost.javahg.internals.AbstractCommand;
import com.aragost.javahg.internals.GenericCommand;
import com.aragost.javahg.internals.HgInputStream;
import com.aragost.javahg.internals.RuntimeIOException;
import com.aragost.javahg.internals.Server;
import com.aragost.javahg.internals.Utils;
import com.google.common.collect.ObjectArrays;
import com.google.common.io.Files;

/**
* Base class for test cases.
*/
@RunWith(org.junit.runners.BlockJUnit4ClassRunner.class)
public abstract class AbstractTestCase {

    // The jul root logger is changed in the initialization of this
    // class. A strong reference must be maintained to the logger. See
    // LG_LOST_LOGGER_DUE_TO_WEAK_REFERENCE on
    // http://findbugs.sourceforge.net/bugDescriptions.html
    private static final Logger JUL_ROOT_LOGGER = Logger.getLogger("");

    private static int count = 0;

    private BaseRepository testRepository;

    private BaseRepository testRepository2;

    protected static final RepositoryConfiguration REPO_CONF;

    static {
        REPO_CONF = makeRepoConf();

        JUL_ROOT_LOGGER.setLevel(Level.WARNING);

        File dir = Files.createTempDir();
        BaseRepository repo = Repository.create(REPO_CONF, dir);
        HgVersion version = VersionCommand.on(repo).execute();
        repo.close();
        try {
            deleteTempDir(dir);
        } catch (IOException e) {
            System.err.println("JavaHg: Failed to remove temp dir: " + dir.getAbsolutePath());
        }

        System.err.println("JavaHg test using Mercurial version: " + version + ", binary: " + REPO_CONF.getHgBin());
    }

    public File createMercurialRepository() {
        File dir = Files.createTempDir();
        Server server = new Server(RepositoryConfiguration.DEFAULT.getHgBin(),
                                   RepositoryConfiguration.DEFAULT.getEncoding());
        server.initMecurialRepository(dir);
        return dir;
    }

    protected static RepositoryConfiguration makeRepoConf() {
        RepositoryConfiguration conf = new RepositoryConfiguration();
        conf.setCachePolicy(CachePolicy.WEAK);
        conf.addExtension(JavaHgTestExtension.class);

        return conf;
    }

    public Charset utf8() {
        return Charset.forName("UTF-8");
    }

    public BaseRepository getTestRepository() {
        if (this.testRepository == null) {
            File dir = Files.createTempDir();
            this.testRepository = Repository.create(REPO_CONF, dir);
        }
        return this.testRepository;
    }

    public BaseRepository getTestRepository2() {
        if (this.testRepository2 == null) {
            File dir = Files.createTempDir();
            this.testRepository2 = Repository.create(REPO_CONF, dir);
        }
        return this.testRepository2;
    }

    /**
     * Write to a file in the test repository
     *
     * @param name
     * @param content
     * @throws IOException
     */
    public void writeFile(String name, String content) throws IOException {
        writeFile(getTestRepository(), name, content);
    }

    public void writeFile(BaseRepository repo, String name, String content) throws IOException {
        File file = new File(repo.getDirectory(), name);
        Files.write(content, file, utf8());
    }
   
    /**
     * Write something to the file in the test repository.
     * <p>
     * Each call to this method will write different content
     *
     * @param name
     * @throws IOException
     */
    public void writeFile(String name) throws IOException {
        writeFile(name, String.valueOf(count++) + "\n");
    }

    public void appendFile(String name) throws IOException {
        File file = new File(getTestRepository().getDirectory(), name);
        Files.append(String.valueOf(count++) + "\n", file, utf8());
    }

    /**
     * Read first line of the file
     *
     * @param name
     * @return
     * @throws IOException
     */
    public String readFile(String name) throws IOException {
        File file = new File(getTestRepository().getDirectory(), name);
        return Files.readFirstLine(file, utf8());
    }

    /**
     * Delete the specified file from the working copy of the test
     * repository.
     *
     * @param name
     */
    public void deleteFile(String name) {
        File file = new File(getTestRepository().getDirectory(), name);
        boolean deleted = file.delete();
        if (!deleted) {
            throw new RuntimeException("Could not delete: " + file);
        }
    }

    /**
     * Commit the changes in the test repository
     *
     * @throws IOException
     */
    public Changeset commit() throws IOException {
        Repository repo = getTestRepository();
        AddCommand.on(repo).execute();
        CommitCommand cmd = CommitCommand.on(repo).user("testcase").message("testcase: " + getClass().getName());
        return cmd.execute();
    }

    /**
     * Create a new changeset in the test repository.
     *
     * @return the changeset Created
     * @throws IOException
     */
    public Changeset createChangeset() throws IOException {
        writeFile("dummyFileForCreatingChangesets", String.valueOf(count++));
        return commit();
    }

    /**
     * Update the test repository to the specified changeset
     *
     * @param cs
     * @throws IOException
     */
    public void update(Changeset cs) throws IOException {
        UpdateCommand.on(getTestRepository()).clean().rev(cs.getNode()).execute();
    }

    @After
    public void closeTestRepository() throws IOException {
        if (this.testRepository != null) {
            this.testRepository.close();
            deleteTempDir(this.testRepository.getDirectory());
            this.testRepository = null;
        }
        if (this.testRepository2 != null) {
            this.testRepository2.close();
            deleteTempDir(this.testRepository2.getDirectory());
            this.testRepository2 = null;
        }
    }

    /**
     * Return an absolute File object referencing a file in the
     * specified repository.
     *
     * @param repo
     * @param parts
     * @return
     */
    public static File repoFile(Repository repo, String... parts) {
        File result = repo.getDirectory();
        for (String part : parts) {
            result = new File(result, part);
        }
        return result;
    }

    /**
     * The error text for missing files is different on Windows
     * compared to Linux/Mac
     *
     * @return
     */
    public static String getMissingFileErrorText() {
        String error = "No such file or directory";
        String osName = System.getProperty("os.name");
        if (osName.startsWith("Windows")) {
            error = "The system cannot find the file specified";
        }
        return error;
    }

    /**
     * Create a temp directory, and return the canonical file object
     * (i.e. no symlinks).
     *
     * @return
     * @throws IOException
     */
    protected static File createTempDir() throws IOException {
        return Files.createTempDir().getCanonicalFile();
    }

    /**
     * Delete a directory in the system temporary directory
     * (java.io.tmpdir).
     *
     * @throws IOException
     */
    public static void deleteTempDir(File file) throws IOException {
        Utils.deleteTempDir(file);
    }

    protected void assertSingleton(Object obj, Collection<?> coll) {
        Assert.assertEquals(obj, Utils.single(coll));
    }

    protected void assertFailedExecution(AbstractCommand cmd) {
        assertFailedExecution(cmd, "");
    }

    protected void assertFailedExecution(AbstractCommand cmd, String msg) {
        if (msg.length() > 0) {
            msg = " Message: " + msg;
        }
        Assert.fail("Exception expected! Return code: " + cmd.getReturnCode() + "." + msg);
    }

    /**
     * Execute a Mercurial command direcotry for a repository, with
     * out using the server
     *
     * @param repo
     * @param hgrcPath
     * @param args
     */
    protected void execHgCommand(BaseRepository repo, String... args) {
        try {
            String[] arr = Utils.arrayConcat(new String[] { REPO_CONF.getHgBin(), "--repo",
                    repo.getDirectory().getAbsolutePath() }, args);

            Process process = Runtime.getRuntime().exec(arr);
            String stderr = Utils.readStream(process.getErrorStream(), repo.newDecoder());
            Utils.consumeAll(process.getInputStream());

            if (process.waitFor() != 0) {
                throw new RuntimeException(stderr);
            }
        } catch (IOException e) {
            throw new RuntimeIOException(e);
        } catch (InterruptedException e) {
            throw Utils.asRuntime(e);
        }
    }

    /**
     * Warning: invoking commands on this server may put it in an invalid state.
     * Use AbstractCommand.launchStream(String...) instead.
     *
     * @param repo The repo
     * @return A Server from the repo
     */
    protected Server getFirstServer(Repository repo) {
        return repo.getServerPool().getServers().get(0);
    }

    protected static ServeState startServing(Repository repo,
            String... additionalConfig) {

        // On windows hg serve --port 0 doesn't print the port it's listening on
        Assume.assumeTrue(!Utils.isWindows());

        final File pidFile;

        try {
            pidFile = File.createTempFile("javahg", ".pid");

            final Process process = Runtime.getRuntime().exec(
                    ObjectArrays.concat(
                            new String[] {
                                    RepositoryConfiguration.DEFAULT.getHgBin(),
                                    "serve", "--port", "0", "-d", "--pid-file",
                                    pidFile.toString(), "-R",
                                    repo.getDirectory().toString() },
                            additionalConfig, String.class));

            HgInputStream in = new HgInputStream(process.getInputStream(),
                    repo.newDecoder());

            Assert.assertTrue(in.find("(bound to *:".getBytes()));
            final int port = in.readDecimal().intValue();
            in.close();

            return new ServeState() {

                public int getPort() {
                    return port;
                }

                public void stop() {
                    BufferedReader in = null;;
                    try {
                        // probably already dead:
                        process.destroy();

                        in = new BufferedReader(new InputStreamReader(new FileInputStream(pidFile)));
                        killProcess(Integer.parseInt(in.readLine()));

                    } catch (Exception e) {
                        throw Utils.asRuntime(e);
                    } finally {
                        try {
                            in.close();
                        } catch (IOException e) {
                            throw Utils.asRuntime(e);
                        }
                    }
                }};
        } catch (IOException e) {
            throw Utils.asRuntime(e);
        }
    }
   
    /**
     * Kill a process
     *
     * @param pid The process id
     */
    protected static void killProcess(int pid) {
        try {
            Runtime rt = Runtime.getRuntime();
            if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) {
                rt.exec("taskkill " + pid).waitFor();
            } else {
                rt.exec(new String[] { "kill", "-9", "" + pid }).waitFor();
            }
        } catch (IOException e) {
            throw Utils.asRuntime(e);
        } catch (InterruptedException e) {
            throw Utils.asRuntime(e);
        }
    }

    protected static class TestableCommand extends GenericCommand {

        public TestableCommand(Repository repository, String commandName) {
            super(repository, commandName);
        }

        public HgInputStream executeToStream(String... args) {
             return launchStream(args);
        }
    }

    protected interface ServeState
    {
        public int getPort();
        public void stop();
    }
}
TOP

Related Classes of com.aragost.javahg.test.AbstractTestCase$ServeState

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.