Mercurial > hg4j
diff test/org/tmatesoft/hg/test/TestPush.java @ 652:cd77bf51b562
Push: tests. Commit respects phases.new-commit setting. Fix outgoing when changes are not children of common (Issue 47)
author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
---|---|
date | Tue, 02 Jul 2013 23:21:16 +0200 |
parents | 6e98d34eaca8 |
children | 629a7370554c |
line wrap: on
line diff
--- a/test/org/tmatesoft/hg/test/TestPush.java Mon Jul 01 21:19:53 2013 +0200 +++ b/test/org/tmatesoft/hg/test/TestPush.java Tue Jul 02 23:21:16 2013 +0200 @@ -26,7 +26,6 @@ import java.util.ArrayList; import java.util.List; -import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.tmatesoft.hg.core.HgCheckoutCommand; @@ -36,9 +35,11 @@ import org.tmatesoft.hg.core.Nodeid; import org.tmatesoft.hg.internal.PhasesHelper; import org.tmatesoft.hg.internal.RevisionSet; +import org.tmatesoft.hg.repo.HgBookmarks; import org.tmatesoft.hg.repo.HgChangelog; import org.tmatesoft.hg.repo.HgInternals; import org.tmatesoft.hg.repo.HgLookup; +import org.tmatesoft.hg.repo.HgPhase; import org.tmatesoft.hg.repo.HgRemoteRepository; import org.tmatesoft.hg.repo.HgRepository; @@ -101,12 +102,192 @@ @Test public void testPushToNonPublishingServer() throws Exception { - Assert.fail(); + // check drafts are same as on server + // copy, not clone as latter updates phase information + File srcRepoLoc = RepoUtils.copyRepoToTempLocation("test-phases", "test-push-nopub-src"); + File dstRepoLoc = RepoUtils.initEmptyTempRepo("test-push-nopub-dst"); + File f1 = new File(srcRepoLoc, "hello.c"); + assertTrue("[sanity]", f1.canWrite()); + HgServer server = new HgServer().publishing(false).start(dstRepoLoc); + try { + final HgLookup hgLookup = new HgLookup(); + final HgRepository srcRepo = hgLookup.detect(srcRepoLoc); + final HgRemoteRepository dstRemote = hgLookup.detect(server.getURL()); + PhasesHelper phaseHelper = new PhasesHelper(HgInternals.getImplementationRepo(srcRepo)); + final RevisionSet allDraft = phaseHelper.allDraft(); + assertFalse("[sanity]", allDraft.isEmpty()); + final int publicCsetToBranchAt = 4; + assertEquals("[sanity]", HgPhase.Public, phaseHelper.getPhase(publicCsetToBranchAt, null)); + // in addition to existing draft csets, add one more draft, branching at some other public revision + new HgCheckoutCommand(srcRepo).changeset(publicCsetToBranchAt).clean(true).execute(); + RepoUtils.modifyFileAppend(f1, "// aaa"); + final HgCommitCommand commitCmd = new HgCommitCommand(srcRepo).message("Commit aaa"); + assertTrue(commitCmd.execute().isOk()); + Nodeid newCommit = commitCmd.getCommittedRevision(); + // + new HgPushCommand(srcRepo).destination(dstRemote).execute(); + HgRepository dstRepo = hgLookup.detect(dstRepoLoc); + final HgChangelog srcClog = srcRepo.getChangelog(); + final HgChangelog dstClog = dstRepo.getChangelog(); + // refresh PhasesHelper + phaseHelper = new PhasesHelper(HgInternals.getImplementationRepo(srcRepo)); + // check if phase didn't change + errorCollector.assertEquals(HgPhase.Draft, phaseHelper.getPhase(srcClog.getRevisionIndex(newCommit), newCommit)); + for (Nodeid n : allDraft) { + // check drafts from src were actually pushed to dst + errorCollector.assertTrue(dstClog.isKnown(n)); + // check drafts didn't change their phase + errorCollector.assertEquals(HgPhase.Draft, phaseHelper.getPhase(srcClog.getRevisionIndex(n), n)); + } + } finally { + server.stop(); + } } + /** + * If server lists revisions we know as drafts as public, update them locally + */ + @Test + public void testPushUpdatesPublishedDrafts() throws Exception { + /* o r9, secret + * | o r8, draft + * | | + * | o r7, draft + * o | r6, secret + * | / + * o r5, draft + * | + * o r4, public + */ + // remote: r5 -> public, r6 -> draft, r8 -> secret + // local: new draft from r4, push + File srcRepoLoc = RepoUtils.copyRepoToTempLocation("test-phases", "test-push-phase-update-1-src"); + File dstRepoLoc = RepoUtils.copyRepoToTempLocation("test-phases", "test-push-phase-update-1-dst"); + File f1 = new File(srcRepoLoc, "hello.c"); + assertTrue("[sanity]", f1.canWrite()); + final HgLookup hgLookup = new HgLookup(); + final HgRepository srcRepo = hgLookup.detect(srcRepoLoc); + final ExecHelper dstRun = new ExecHelper(new OutputParser.Stub(), dstRepoLoc); + final int publicCsetToBranchAt = 4; + final int r5 = 5, r6 = 6, r8 = 8; + PhasesHelper srcPhase = new PhasesHelper(HgInternals.getImplementationRepo(srcRepo)); + assertEquals("[sanity]", HgPhase.Draft, srcPhase.getPhase(r5, null)); + assertEquals("[sanity]", HgPhase.Secret, srcPhase.getPhase(r6, null)); + assertEquals("[sanity]", HgPhase.Draft, srcPhase.getPhase(r8, null)); + // change phases in repository of remote server: + dstRun.exec("hg", "phase", "--public", String.valueOf(r5)); + assertEquals(0, dstRun.getExitValue()); + dstRun.exec("hg", "phase", "--draft", String.valueOf(r6)); + assertEquals(0, dstRun.getExitValue()); + dstRun.exec("hg", "phase", "--secret", "--force", String.valueOf(r8)); + assertEquals(0, dstRun.getExitValue()); + HgServer server = new HgServer().publishing(false).start(dstRepoLoc); + try { + final HgRemoteRepository dstRemote = hgLookup.detect(server.getURL()); + // commit new draft head + new HgCheckoutCommand(srcRepo).changeset(publicCsetToBranchAt).clean(true).execute(); + RepoUtils.modifyFileAppend(f1, "// aaa"); + final HgCommitCommand commitCmd = new HgCommitCommand(srcRepo).message("Commit aaa"); + assertTrue(commitCmd.execute().isOk()); + final Nodeid newCommit = commitCmd.getCommittedRevision(); + // + new HgPushCommand(srcRepo).destination(dstRemote).execute(); + // refresh phase information + srcPhase = new PhasesHelper(HgInternals.getImplementationRepo(srcRepo)); + // r5 and r6 are changed to match server phases (more exposed) + errorCollector.assertEquals(HgPhase.Public, srcPhase.getPhase(r5, null)); + errorCollector.assertEquals(HgPhase.Draft, srcPhase.getPhase(r6, null)); + // r8 is secret on server, locally can't make it less exposed though + errorCollector.assertEquals(HgPhase.Draft, srcPhase.getPhase(r8, null)); + // + HgRepository dstRepo = hgLookup.detect(dstRepoLoc); + final HgChangelog dstClog = dstRepo.getChangelog(); + assertTrue(dstClog.isKnown(newCommit)); + PhasesHelper dstPhase = new PhasesHelper(HgInternals.getImplementationRepo(dstRepo)); + errorCollector.assertEquals(HgPhase.Draft, dstPhase.getPhase(dstClog.getRevisionIndex(newCommit), newCommit)); + // the one that was secret is draft now + errorCollector.assertEquals(HgPhase.Draft, srcPhase.getPhase(r8, null)); + } finally { + server.stop(); + } + } + + /** + * update phases of local revisions and push changes + */ + @Test + public void testPushPublishAndUpdates() throws Exception { + File srcRepoLoc = RepoUtils.copyRepoToTempLocation("test-phases", "test-push-phase-update-2-src"); + File dstRepoLoc = RepoUtils.initEmptyTempRepo("test-push-phase-update-1-dst"); + final int r4 = 4, r5 = 5, r6 = 6, r9 = 9; + HgServer server = new HgServer().publishing(false).start(dstRepoLoc); + try { + final HgLookup hgLookup = new HgLookup(); + final HgRepository srcRepo = hgLookup.detect(srcRepoLoc); + final HgRemoteRepository dstRemote = hgLookup.detect(server.getURL()); + new HgPushCommand(srcRepo).destination(dstRemote).execute(); + // + // make sure pushed repository got same draft root + final Nodeid r4PublicHead = srcRepo.getChangelog().getRevision(r4); + final Nodeid r5DraftRoot = srcRepo.getChangelog().getRevision(r5); + HgRepository dstRepo = hgLookup.detect(dstRepoLoc); + final HgChangelog dstClog = dstRepo.getChangelog(); + PhasesHelper dstPhase = new PhasesHelper(HgInternals.getImplementationRepo(dstRepo)); + assertEquals(HgPhase.Public, dstPhase.getPhase(dstClog.getRevisionIndex(r4PublicHead), r4PublicHead)); + assertEquals(HgPhase.Draft, dstPhase.getPhase(dstClog.getRevisionIndex(r5DraftRoot), r5DraftRoot)); + // + // now, graduate some local revisions, r5:draft->public, r6:secret->public, r9: secret->draft + final ExecHelper srcRun = new ExecHelper(new OutputParser.Stub(), srcRepoLoc); + srcRun.exec("hg", "phase", "--public", String.valueOf(r5)); + srcRun.exec("hg", "phase", "--public", String.valueOf(r6)); + srcRun.exec("hg", "phase", "--draft", String.valueOf(r9)); + // PhaseHelper shall be new for the command, and would pick up these external changes + new HgPushCommand(srcRepo).destination(dstRemote).execute(); + final Nodeid r6Nodeid = srcRepo.getChangelog().getRevision(r6); + final Nodeid r9Nodeid = srcRepo.getChangelog().getRevision(r9); + // refresh + dstPhase = new PhasesHelper(HgInternals.getImplementationRepo(dstRepo)); + // not errorCollector as subsequent code would fail if these secret revs didn't get into dst + assertTrue(dstClog.isKnown(r6Nodeid)); + assertTrue(dstClog.isKnown(r9Nodeid)); + errorCollector.assertEquals(HgPhase.Public, dstPhase.getPhase(dstClog.getRevisionIndex(r5DraftRoot), r5DraftRoot)); + errorCollector.assertEquals(HgPhase.Public, dstPhase.getPhase(dstClog.getRevisionIndex(r6Nodeid), r6Nodeid)); + errorCollector.assertEquals(HgPhase.Draft, dstPhase.getPhase(dstClog.getRevisionIndex(r9Nodeid), r9Nodeid)); + } finally { + server.stop(); + } + } + + @Test public void testPushToPublishingServer() throws Exception { - Assert.fail(); + // copy, not clone as latter updates phase information + File srcRepoLoc = RepoUtils.copyRepoToTempLocation("test-phases", "test-push-pub-src"); + File dstRepoLoc = RepoUtils.initEmptyTempRepo("test-push-pub-dst"); + HgServer server = new HgServer().publishing(true).start(dstRepoLoc); + try { + final HgLookup hgLookup = new HgLookup(); + final HgRepository srcRepo = hgLookup.detect(srcRepoLoc); + final HgRemoteRepository dstRemote = hgLookup.detect(server.getURL()); + PhasesHelper phaseHelper = new PhasesHelper(HgInternals.getImplementationRepo(srcRepo)); + final RevisionSet allDraft = phaseHelper.allDraft(); + assertFalse("[sanity]", allDraft.isEmpty()); + // push all changes + new HgPushCommand(srcRepo).destination(dstRemote).execute(); + HgRepository dstRepo = hgLookup.detect(dstRepoLoc); + final HgChangelog srcClog = srcRepo.getChangelog(); + final HgChangelog dstClog = dstRepo.getChangelog(); + // refresh PhasesHelper + phaseHelper = new PhasesHelper(HgInternals.getImplementationRepo(srcRepo)); + for (Nodeid n : allDraft) { + // check drafts from src were actually pushed to dst + errorCollector.assertTrue(dstClog.isKnown(n)); + // check drafts became public + errorCollector.assertEquals(HgPhase.Public, phaseHelper.getPhase(srcClog.getRevisionIndex(n), n)); + } + } finally { + server.stop(); + } } @Test @@ -137,7 +318,69 @@ @Test public void testUpdateBookmarkOnPush() throws Exception { - Assert.fail(); + File srcRepoLoc = RepoUtils.cloneRepoToTempLocation("test-annotate", "test-push-src", false); + File dstRepoLoc = RepoUtils.cloneRepoToTempLocation("test-annotate", "test-push-dst", false); + final ExecHelper srcRun = new ExecHelper(new OutputParser.Stub(), srcRepoLoc); + final ExecHelper dstRun = new ExecHelper(new OutputParser.Stub(), dstRepoLoc); + File f1 = new File(srcRepoLoc, "file1"); + assertTrue("[sanity]", f1.canWrite()); + // + final String bm1 = "mark1", bm2 = "mark2", bm3 = "mark3", bm4 = "mark4", bm5 = "mark5"; + final int bm2Local = 1, bm2Remote = 6, bm3Local = 7, bm3Remote = 2, bm_4_5 = 3; + // 1) bm1 - local active bookmark, check that push updates in remote + srcRun.exec("hg", "bookmark", bm1); + dstRun.exec("hg", "bookmark", "-r", "8", bm1); + // 2) bm2 - local points to ancestor of revision remote points to + srcRun.exec("hg", "bookmark", "-r", String.valueOf(bm2Local), bm2); + dstRun.exec("hg", "bookmark", "-r", String.valueOf(bm2Remote), bm2); + // 3) bm3 - remote points to ancestor of revision local one points to + srcRun.exec("hg", "bookmark", "-r", String.valueOf(bm3Local), bm3); + dstRun.exec("hg", "bookmark", "-r", String.valueOf(bm3Remote), bm3); + // 4) bm4 - remote bookmark, not known locally + dstRun.exec("hg", "bookmark", "-r", String.valueOf(bm_4_5), bm4); + // 5) bm5 - local bookmark, not known remotely + srcRun.exec("hg", "bookmark", "-r", String.valueOf(bm_4_5), bm5); + // + HgServer server = new HgServer().start(dstRepoLoc); + try { + final HgLookup hgLookup = new HgLookup(); + final HgRepository srcRepo = hgLookup.detect(srcRepoLoc); + final HgRemoteRepository dstRemote = hgLookup.detect(server.getURL()); + RepoUtils.modifyFileAppend(f1, "change1"); + final HgCommitCommand commitCmd = new HgCommitCommand(srcRepo).message("Commit 1"); + assertTrue(commitCmd.execute().isOk()); + assertEquals(bm1, srcRepo.getBookmarks().getActiveBookmarkName()); + assertEquals(commitCmd.getCommittedRevision(), srcRepo.getBookmarks().getRevision(bm1)); + // + new HgPushCommand(srcRepo).destination(dstRemote).execute(); + Thread.sleep(300); // let the server perform the update + // + HgBookmarks srcBookmarks = srcRepo.getBookmarks(); + final HgChangelog srcClog = srcRepo.getChangelog(); + // first, check local bookmarks are intact + errorCollector.assertEquals(srcClog.getRevision(bm2Local), srcBookmarks.getRevision(bm2)); + errorCollector.assertEquals(srcClog.getRevision(bm3Local), srcBookmarks.getRevision(bm3)); + errorCollector.assertEquals(null, srcBookmarks.getRevision(bm4)); + errorCollector.assertEquals(srcClog.getRevision(bm_4_5), srcBookmarks.getRevision(bm5)); + // now, check remote bookmarks were touched + HgRepository dstRepo = hgLookup.detect(dstRepoLoc); + HgBookmarks dstBookmarks = dstRepo.getBookmarks(); + final HgChangelog dstClog = dstRepo.getChangelog(); + // bm1 changed and points to newly pushed commit. + // if the test fails (bm1 points to r8), chances are server didn't manage to update + // bookmarks yet (there's Thread.sleep() above to give it a chance). + errorCollector.assertEquals(commitCmd.getCommittedRevision(), dstBookmarks.getRevision(bm1)); + // bm2 didn't change + errorCollector.assertEquals(dstClog.getRevision(bm2Remote), dstBookmarks.getRevision(bm2)); + // bm3 did change, now points to value we've got in srcRepo + errorCollector.assertEquals(srcClog.getRevision(bm3Local), dstBookmarks.getRevision(bm3)); + // bm4 is not affected + errorCollector.assertEquals(dstClog.getRevision(bm_4_5), dstBookmarks.getRevision(bm4)); + // bm5 is not known remotely + errorCollector.assertEquals(null, dstBookmarks.getRevision(bm5)); + } finally { + server.stop(); + } } @@ -149,6 +392,12 @@ static class HgServer { private Process serverProcess; + private boolean publish = true; + + public HgServer publishing(boolean pub) { + publish = pub; + return this; + } public HgServer start(File dir) throws IOException, InterruptedException { if (serverProcess != null) { @@ -164,6 +413,10 @@ cmdline.add("server.validate=True"); cmdline.add("--config"); cmdline.add(String.format("web.port=%d", port())); + if (!publish) { + cmdline.add("--config"); + cmdline.add("phases.publish=False"); + } cmdline.add("serve"); serverProcess = new ProcessBuilder(cmdline).directory(dir).start(); Thread.sleep(500);