/src/test/java/com/aragost/javahg/test/AbstractTestCase.java
Java | 440 lines | 257 code | 57 blank | 126 comment | 16 complexity | 2ab9b8d298dd0b11c680c97c34475788 MD5 | raw file
- /*
- * #%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();
- }
- }