#!/usr/bin/env python # Test whether the various ways that move conflicts happen are correct. # # Copyright (C) 2005 Walter Landry # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; version 2 dated June, 1991. # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA import arx import os def removeall(top): if os.path.exists(top): for root, dirs, files in os.walk(top, topdown=False): for name in files: os.remove(os.path.join(root, name)) for name in dirs: os.rmdir(os.path.join(root, name)) os.rmdir(top) # Get rid of all of the cruft that may already exist from previous # runs. removeall("foo") removeall("ac") removeall("apb") removeall("apc") removeall("db") removeall("dc") removeall("tree") arx.delete_archive_registration("foo") # Set up the problem, making the patches. arx.make_archive("foo",arx.uri("foo"),0,"") os.mkdir("tree") os.chdir("tree") os.mkdir("a") os.mkdir("d") os.mkdir("f") f=open("a/b","w") f.close() arx.init(arx.Parsed_Name("foo/tree"),arx.path("."),1) arx.commit_revision(arx.path("."),"init") arx.atomic_move(arx.path("a/b"),arx.path("a/c"),0) arx.undo(arx.path("."),arx.path("../ac")) arx.atomic_move(arx.path("a"),arx.path("ap"),0) arx.undo(arx.path("."),arx.path("../apb")) arx.atomic_move(arx.path("a"),arx.path("ap"),0) arx.atomic_move(arx.path("ap/b"),arx.path("ap/c"),0) arx.undo(arx.path("."),arx.path("../apc")) arx.atomic_move(arx.path("a/b"),arx.path("d/b"),0) arx.undo(arx.path("."),arx.path("../db")) arx.atomic_move(arx.path("a/b"),arx.path("d/c"),0) arx.undo(arx.path("."),arx.path("../dc")) os.chdir("..") removeall("tree") # This is table of the expected results of moving file that was # already moved. The original position of the file is a/b, and there # are five possible destinations: a/c, ap/b, ap/c, d/b, d/c. The p, # or "'" mark is a parent directory that has been renamed, as opposed # to a file that has been moved into a completely different parent # directory. # The places that the file may have already been moved are: a/b, a/c, # a/e, ap/b, ap/c, ap/e, app/b, app/c, app/e, d/b, d/c, d/e, dp/b, # dp/c, dp/e, f/b, f/c, f/e. The two elements are the final resting # place of the file and whether the tree is free from conflicts. So # results[7][2] == ["ap/c",False] say that moving the file to app/c # and then applying a patch that moves it to ap/c will make the file # end up at ap/c with conflicts. results=[[["a/c",True], ["ap/b",True], ["ap/c",True], ["d/b",True], ["d/c",True]], [["a/c",True], ["ap/c",True], ["ap/c",True], ["d/c",True], ["d/c",True]], [["a/c",False], ["ap/e",True], ["ap/c",False],["d/e",True], ["d/c",False]], [["ap/c",True], ["ap/b",True], ["ap/c",True], ["d/b",True], ["d/c",True]], [["ap/c",True], ["ap/c",True], ["ap/c",True], ["d/c",True], ["d/c",True]], [["ap/c",False], ["ap/e",True], ["ap/c",False],["d/e",True], ["d/c",False]], [["app/c",True], ["ap/b",False],["ap/c",False],["d/b",True], ["d/c",True]], [["app/c",True], ["ap/c",False],["ap/c",False],["d/c",True], ["d/c",True]], [["app/c",False],["ap/e",False],["ap/c",False],["d/e",True], ["d/c",False]], [["d/c",True], ["d/b",True], ["d/c",True], ["d/b",True], ["d/c",True]], [["d/c",True], ["d/c",True], ["d/c",True], ["d/c",True], ["d/c",True]], [["d/c",False], ["d/e",True], ["d/c",False], ["d/e",True], ["d/c",False]], [["dp/c",True], ["dp/b",True], ["dp/c",True], ["dp/b",True], ["dp/c",True]], [["dp/c",True], ["dp/c",True], ["dp/c",True], ["dp/c",True], ["dp/c",True]], [["dp/c",False], ["dp/e",True], ["dp/c",False],["dp/e",True], ["dp/c",False]], [["f/c",True], ["f/b",True], ["f/c",True], ["d/b",False],["d/c",False]], [["f/c",True], ["f/c",True], ["f/c",True], ["d/c",False],["d/c",False]], [["f/c",False], ["f/e",True], ["f/c",False], ["d/e",False],["d/c",False]]] # A few functions to simplify trying out all of the different patch # combinations def setup(): arx.get_revision(arx.Parsed_Name("foo/tree,0"),arx.path("tree"), arx.path("."),1) os.chdir("tree") def cleanup(): os.chdir("..") removeall("tree") patches=["ac","apb","apc","db","dc"] def apply_patches(index,results): conflicts=arx.do_patch(arx.path("../"+patches[index]),arx.path("."),0,1,1,1) if(conflicts.empty()!=results[index][1]): raise Exception("Incorrect conflicts " + patches[index] + " " + conflicts.empty() + " " + results[index][1]); if not os.path.exists(results[index][0]): raise Exception("File in wrong location " + results[index][0]) # Try out all of the 5*18=90 different combinations. Some of them are # redundant, but it is simpler this way. for i in range(5): print patches[i] setup() apply_patches(i,results[0]) cleanup() setup() arx.atomic_move(arx.path("a/b"),arx.path("a/c"),0) apply_patches(i,results[1]) cleanup() setup() arx.atomic_move(arx.path("a/b"),arx.path("a/e"),0) apply_patches(i,results[2]) cleanup() setup() arx.atomic_move(arx.path("a"),arx.path("ap"),0) apply_patches(i,results[3]) cleanup() setup() arx.atomic_move(arx.path("a"),arx.path("ap"),0) arx.atomic_move(arx.path("ap/b"),arx.path("ap/c"),0) apply_patches(i,results[4]) cleanup() setup() arx.atomic_move(arx.path("a"),arx.path("ap"),0) arx.atomic_move(arx.path("ap/b"),arx.path("ap/e"),0) apply_patches(i,results[5]) cleanup() setup() arx.atomic_move(arx.path("a"),arx.path("app"),0) apply_patches(i,results[6]) cleanup() setup() arx.atomic_move(arx.path("a"),arx.path("app"),0) arx.atomic_move(arx.path("app/b"),arx.path("app/c"),0) apply_patches(i,results[7]) cleanup() setup() arx.atomic_move(arx.path("a"),arx.path("app"),0) arx.atomic_move(arx.path("app/b"),arx.path("app/e"),0) apply_patches(i,results[8]) cleanup() setup() arx.atomic_move(arx.path("a/b"),arx.path("d/b"),0) apply_patches(i,results[9]) cleanup() setup() arx.atomic_move(arx.path("a/b"),arx.path("d/c"),0) apply_patches(i,results[10]) cleanup() setup() arx.atomic_move(arx.path("a/b"),arx.path("d/e"),0) apply_patches(i,results[11]) cleanup() setup() arx.atomic_move(arx.path("d"),arx.path("dp"),0) arx.atomic_move(arx.path("a/b"),arx.path("dp/b"),0) apply_patches(i,results[12]) cleanup() setup() arx.atomic_move(arx.path("d"),arx.path("dp"),0) arx.atomic_move(arx.path("a/b"),arx.path("dp/c"),0) apply_patches(i,results[13]) cleanup() setup() arx.atomic_move(arx.path("d"),arx.path("dp"),0) arx.atomic_move(arx.path("a/b"),arx.path("dp/e"),0) apply_patches(i,results[14]) cleanup() setup() arx.atomic_move(arx.path("a/b"),arx.path("f/b"),0) apply_patches(i,results[15]) cleanup() setup() arx.atomic_move(arx.path("a/b"),arx.path("f/c"),0) apply_patches(i,results[16]) cleanup() setup() arx.atomic_move(arx.path("a/b"),arx.path("f/e"),0) apply_patches(i,results[17]) cleanup() # Cleanup removeall("foo") removeall("ac") removeall("apb") removeall("apc") removeall("db") removeall("dc") arx.delete_archive_registration("foo")