tikhomirov@474: /* tikhomirov@628: * Copyright (c) 2012-2013 TMate Software Ltd tikhomirov@474: * tikhomirov@474: * This program is free software; you can redistribute it and/or modify tikhomirov@474: * it under the terms of the GNU General Public License as published by tikhomirov@474: * the Free Software Foundation; version 2 of the License. tikhomirov@474: * tikhomirov@474: * This program is distributed in the hope that it will be useful, tikhomirov@474: * but WITHOUT ANY WARRANTY; without even the implied warranty of tikhomirov@474: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the tikhomirov@474: * GNU General Public License for more details. tikhomirov@474: * tikhomirov@474: * For information on how to redistribute this software under tikhomirov@474: * the terms of a license other than GNU General Public License tikhomirov@474: * contact TMate Software at support@hg4j.com tikhomirov@474: */ tikhomirov@474: package org.tmatesoft.hg.test; tikhomirov@474: tikhomirov@474: import static org.junit.Assert.*; tikhomirov@474: tikhomirov@648: import java.util.ArrayList; tikhomirov@474: import java.util.regex.Matcher; tikhomirov@474: import java.util.regex.Pattern; tikhomirov@474: tikhomirov@474: import org.junit.Rule; tikhomirov@474: import org.junit.Test; tikhomirov@648: import org.tmatesoft.hg.core.Nodeid; tikhomirov@648: import org.tmatesoft.hg.internal.Internals; tikhomirov@474: import org.tmatesoft.hg.internal.PhasesHelper; tikhomirov@648: import org.tmatesoft.hg.internal.RevisionSet; tikhomirov@474: import org.tmatesoft.hg.repo.HgChangelog; tikhomirov@493: import org.tmatesoft.hg.repo.HgInternals; tikhomirov@474: import org.tmatesoft.hg.repo.HgLookup; tikhomirov@474: import org.tmatesoft.hg.repo.HgParentChildMap; tikhomirov@474: import org.tmatesoft.hg.repo.HgPhase; tikhomirov@474: import org.tmatesoft.hg.repo.HgRepository; tikhomirov@628: import org.tmatesoft.hg.repo.HgRuntimeException; tikhomirov@474: tikhomirov@474: /** tikhomirov@474: * {hg4j.tests.repos}/test-phases/ tikhomirov@474: * @author Artem Tikhomirov tikhomirov@474: * @author TMate Software Ltd. tikhomirov@474: */ tikhomirov@474: public class TestPhases { tikhomirov@474: tikhomirov@474: @Rule tikhomirov@474: public ErrorCollectorExt errorCollector = new ErrorCollectorExt(); tikhomirov@474: tikhomirov@474: @Test tikhomirov@474: public void testHelperNoParentChildMap() throws Exception { tikhomirov@474: HgRepository repo = Configuration.get().find("test-phases"); tikhomirov@474: HgPhase[] expected = readPhases(repo); tikhomirov@474: final long start = System.nanoTime(); tikhomirov@493: PhasesHelper ph = new PhasesHelper(HgInternals.getImplementationRepo(repo), null); tikhomirov@474: initAndCheck(ph, expected); tikhomirov@474: final long end = System.nanoTime(); tikhomirov@477: // μ == \u03bc tikhomirov@477: System.out.printf("Without ParentWalker (simulates log command for single file): %,d μs\n", (end - start)/1000); tikhomirov@474: } tikhomirov@474: tikhomirov@474: @Test tikhomirov@474: public void testHelperWithParentChildMap() throws Exception { tikhomirov@474: HgRepository repo = Configuration.get().find("test-phases"); tikhomirov@474: HgPhase[] expected = readPhases(repo); tikhomirov@474: final long start1 = System.nanoTime(); tikhomirov@474: HgParentChildMap pw = new HgParentChildMap(repo.getChangelog()); tikhomirov@474: pw.init(); tikhomirov@474: final long start2 = System.nanoTime(); tikhomirov@493: PhasesHelper ph = new PhasesHelper(HgInternals.getImplementationRepo(repo), pw); tikhomirov@474: initAndCheck(ph, expected); tikhomirov@474: final long end = System.nanoTime(); tikhomirov@477: System.out.printf("With ParentWalker(simulates log command for whole repo): %,d μs (pw init: %,d ns)\n", (end - start1)/1000, start2 - start1); tikhomirov@474: } tikhomirov@648: tikhomirov@648: @Test tikhomirov@648: public void testAllSecretAndDraft() throws Exception { tikhomirov@648: HgRepository repo = Configuration.get().find("test-phases"); tikhomirov@648: Internals implRepo = HgInternals.getImplementationRepo(repo); tikhomirov@648: HgPhase[] expected = readPhases(repo); tikhomirov@648: ArrayList secret = new ArrayList(); tikhomirov@648: ArrayList draft = new ArrayList(); tikhomirov@648: ArrayList pub = new ArrayList(); tikhomirov@648: for (int i = 0; i < expected.length; i++) { tikhomirov@648: Nodeid n = repo.getChangelog().getRevision(i); tikhomirov@648: switch (expected[i]) { tikhomirov@648: case Secret : secret.add(n); break; tikhomirov@648: case Draft : draft.add(n); break; tikhomirov@648: case Public : pub.add(n); break; tikhomirov@648: default : throw new IllegalStateException(); tikhomirov@648: } tikhomirov@648: } tikhomirov@648: final RevisionSet rsSecret = new RevisionSet(secret); tikhomirov@648: final RevisionSet rsDraft = new RevisionSet(draft); tikhomirov@648: assertFalse("[sanity]", rsSecret.isEmpty()); tikhomirov@648: assertFalse("[sanity]", rsDraft.isEmpty()); tikhomirov@648: HgParentChildMap pw = new HgParentChildMap(repo.getChangelog()); tikhomirov@648: pw.init(); tikhomirov@648: PhasesHelper ph1 = new PhasesHelper(implRepo, null); tikhomirov@648: PhasesHelper ph2 = new PhasesHelper(implRepo, pw); tikhomirov@648: RevisionSet s1 = ph1.allSecret().symmetricDifference(rsSecret); tikhomirov@648: RevisionSet s2 = ph2.allSecret().symmetricDifference(rsSecret); tikhomirov@648: errorCollector.assertTrue("Secret,no ParentChildMap:" + s1.toString(), s1.isEmpty()); tikhomirov@648: errorCollector.assertTrue("Secret, with ParentChildMap:" + s2.toString(), s2.isEmpty()); tikhomirov@648: RevisionSet s3 = ph1.allDraft().symmetricDifference(rsDraft); tikhomirov@648: RevisionSet s4 = ph2.allDraft().symmetricDifference(rsDraft); tikhomirov@648: errorCollector.assertTrue("Draft,no ParentChildMap:" + s3.toString(), s3.isEmpty()); tikhomirov@648: errorCollector.assertTrue("Draft, with ParentChildMap:" + s4.toString(), s4.isEmpty()); tikhomirov@648: } tikhomirov@474: tikhomirov@628: private HgPhase[] initAndCheck(PhasesHelper ph, HgPhase[] expected) throws HgRuntimeException { tikhomirov@474: HgChangelog clog = ph.getRepo().getChangelog(); tikhomirov@474: HgPhase[] result = new HgPhase[clog.getRevisionCount()]; tikhomirov@474: for (int i = 0, l = clog.getLastRevision(); i <= l; i++) { tikhomirov@474: result[i] = ph.getPhase(i, null); tikhomirov@474: } tikhomirov@474: assertEquals(expected.length, result.length); tikhomirov@474: for (int i = 0; i < result.length; i++) { tikhomirov@474: errorCollector.assertTrue(result[i] == expected[i]); tikhomirov@474: } tikhomirov@474: return result; tikhomirov@474: } tikhomirov@474: tikhomirov@474: private static HgPhase[] readPhases(HgRepository repo) throws Exception { tikhomirov@474: HgPhase[] result = new HgPhase[repo.getChangelog().getRevisionCount()]; tikhomirov@474: OutputParser.Stub output = new OutputParser.Stub(); tikhomirov@474: ExecHelper eh = new ExecHelper(output, repo.getWorkingDir()); tikhomirov@474: eh.run("hg", "phase", "-r", "0:-1"); tikhomirov@623: assertEquals("Perhaps, older Mercurial version, with no hg phase command support?", 0, eh.getExitValue()); tikhomirov@474: Matcher m = Pattern.compile("(\\d+): (\\w+)$", Pattern.MULTILINE).matcher(output.result()); tikhomirov@474: int i = 0; tikhomirov@474: while (m.find()) { tikhomirov@474: int x = Integer.parseInt(m.group(1)); tikhomirov@474: assert x == i; tikhomirov@474: HgPhase v = HgPhase.parse(m.group(2)); tikhomirov@474: result[x] = v; tikhomirov@474: i++; tikhomirov@474: } tikhomirov@474: return result; tikhomirov@474: } tikhomirov@474: tikhomirov@474: public static void main(String[] args) throws Exception { tikhomirov@474: HgRepository repo = new HgLookup().detect(System.getProperty("user.home") + "/hg/test-phases/"); tikhomirov@474: HgPhase[] v = readPhases(repo); tikhomirov@474: printPhases(v); tikhomirov@474: } tikhomirov@474: tikhomirov@474: private static void printPhases(HgPhase[] phase) { tikhomirov@474: for (int i = 0; i < phase.length; i++) { tikhomirov@474: System.out.printf("rev:%3d, phase:%s\n", i, phase[i]); tikhomirov@474: } tikhomirov@474: } tikhomirov@474: tikhomirov@474: }