from __future__ import print_function import unittest import time, os, sys import P4 pythonVer = "python" if sys.version_info[0] >= 3: pythonVer = "python3" parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, parent_dir) from p4testutils import TestCase, P4Server, localDirectory, create_file, append_to_file # from TestTriggers import TestTriggers os.environ["LOGS"] = "." LOGGER_NAME = "TestCheckCaseTrigger" LOG_FILE = "log-TestCheckCaseTrigger.log" # Run tests on a case-sensitive server or a case-insensitive server. # NOTE: For case-insensitive server, add case_sensitive=false to end of TestCheckCaseTrigger arguments. case_sensitive = True # Handle Python2 version of os.makedirs def makedirs(folder, *args, **kwargs): if not os.path.exists(folder): os.makedirs(folder) def connect(func): def func_wrapper(self): self.p4.connect() self.assertTrue(self.p4.connected(), "Not connected") func(self) self.p4.disconnect() os.chdir(self.server.client_root) return func_wrapper class TestCheckCaseTrigger(TestCase): def __init__(self, methodName='runTest'): super(TestCheckCaseTrigger, self).__init__(LOGGER_NAME, LOG_FILE, methodName=methodName) def setUp(self): # Set up server as case-sensitive (default) or using argv argument. self.server = P4Server(case_sensitive_flag=case_sensitive) trigpath = os.path.join(parent_dir, "CheckCaseTrigger.py") p4 = self.server.p4 self.client_root = self.server.client_root self.p4 = p4 p4.logger = self.logger # This works if no spaces in server root pathname! port = p4.port.replace('"', '') self.logger.debug("port: |%s|" % port) triggers = p4.fetch_triggers() triggers['Triggers'] = ['CheckCase change-submit //... " {} {} -p %quote%{}%quote% ' '-u {} %change% "'.format(pythonVer, trigpath, port, p4.user)] self.logger.debug(triggers) p4.save_triggers(triggers) # Reconnect to pick up changes p4.disconnect() p4.connect() def tearDown(self): if self.p4.connected(): self.p4.disconnect() time.sleep(1) # self.server.cleanupTestTree() def localFile(self, name): return os.path.join(self.client_root, name) def addFile(self, name): makedirs(self.client_root, exist_ok=True) path, filename = os.path.split(name) if path: pname = os.path.join(self.client_root, path) makedirs(pname, exist_ok=True) fname = os.path.join(self.client_root, name) with open(fname, "w") as f: f.write("Content") self.p4.run_add(fname) def _doSubmit(self, msg, *args): """Submits the changes""" try: result = self.p4.run_submit(*args) self.assertTrue( 'submittedChange' in result[-1], msg) except P4.P4Exception as inst: self.fail("submit failed with exception ") def createFiles(self, testDir): testAbsoluteDir = os.path.join(self.client_root, testDir) os.mkdir(testAbsoluteDir) # create a bunch of files files = ('foo.txt', 'bar.txt', 'baz.txt') for file in files: fname = os.path.join(testAbsoluteDir, file) f = open(fname, "w") f.write("Test Text") f.close() self.p4.run_add(fname) self.assertEqual(len(self.p4.run_opened()), len(files), "Unexpected number of open files") return files def expectFailSubmit(self, msg, desc): """Submits the changes, but expects to fail the trigger""" try: result = self.p4.run_submit("-d", desc) self.fail(msg) except P4.P4Exception as inst: pass # expected def expectSucceedSubmit(self, msg, desc): """Submits the change, but expects to succeed""" change = self.p4.fetch_change() change._description = desc self._doSubmit(msg, change) @connect def testSimpleSubmit(self): self.assertEqual(len(self.p4.run_opened()), 0, "Shouldn't have open files") testDir = 'test_files' files = self.createFiles(testDir) self.expectSucceedSubmit("Failed to submit the add", "My Add Test") @connect def testSimpleFail(self): self.addFile("foo") self.expectSucceedSubmit("Adding one file should not fail", "Simple Add") self.p4.run_sync("@0") self.addFile("Foo") self.expectFailSubmit("Did not catch foo != Foo", "Foo") @connect def testP4Files(self): # Test whether p4 files -i ignores case of file string. self.addFile("A/case_test/1_lowercase.text") self.addFile("A/case_test/10_lowercase.text") self.addFile("A/case_test/100_lowercase.text") self.addFile("A/case_test/1000_lowercase.text") self.addFile("A/case_test/10000_lowercase.text") self.addFile("A/B/case_test/1_lowercase.text") self.addFile("A/B/case_test/10_lowercase.text") self.addFile("A/B/case_test/100_lowercase.text") self.addFile("A/B/case_test/1000_lowercase.text") self.addFile("A/B/case_test/10000_lowercase.text") self.expectSucceedSubmit("Adding files in A/case_test & A/B/case_test should not fail", "foo") # p4 files with -i option should ignore case of file string on case-sensitive server. self.assertEqual(len(self.p4.run_files("-i", "//depot/a/...")), 10, "Should return 10 files") @connect def testCaseInsensitive(self): # Test whether p4 files -i ignores case of file string. self.addFile("A/CASE_TEST/FOO1.TXT") self.expectSucceedSubmit("Adding unique files should not fail", "A/CASE_TEST") # Case Variant Adds Should Fail on either case-sensitive or case-insensitive server. # NOTE: For case-insensitive server use case_sensitive=False command-line argument. # For case-insensitive server, the duplication is caught in the p4 submit command # and the file removed from the changelist. self.addFile("a/case_test/foo1.txt") self.expectFailSubmit("Should not be able to add case-variant files", "a/case_test") @connect def testDirectoryFail(self): self.addFile("foo/bar") self.expectSucceedSubmit("Adding one file should not fail", "Simple Add") self.p4.run_sync("@0") self.addFile("FOO/bar") self.expectFailSubmit("Did not catch foo != FOO/bar", "bar") @connect def testDirectoryFail_2(self): self.addFile("foo/bar/bar2") self.expectSucceedSubmit("Adding one file should not fail", "Simple Add") #self.p4.run_sync("@0") self.addFile("FOO/bar2") self.expectFailSubmit("Did not catch foo/bar/bar2 != FOO/bar2", "bar") self.addFile("FOO/bar/bar") self.expectFailSubmit("Did not catch foo/bar/bar2 != FOO/bar/bar", "bar") self.addFile("FOO/bar/bar2") self.expectFailSubmit("Did not catch foo/bar/bar2 != FOO/bar/bar2", "bar") self.addFile("FOO/BAR") self.expectFailSubmit("Did not catch foo/bar/bar2 != FOO/BAR", "bar") if case_sensitive == True: self.addFile("foo/BAR/bar") self.expectFailSubmit("Did not catch foo/bar/bar2 != foo/BAR/bar", "bar") self.addFile("foo/bar/BAR") self.expectSucceedSubmit("Should be able to add both foo/bar/bar2 & foo/bar/BAR", "bar") @connect def testDirectoryFail_3(self): self.addFile("foo/bar") self.expectSucceedSubmit("Adding one file should not fail", "Simple Add") self.p4.run_sync("@0") self.addFile("foo/bar/BAR/bar2") #Can't have file and directory with the same name. self.expectFailSubmit("Can't have file bar and directory bar", "bar") @connect def testDirectoryFail_4(self): self.addFile("bar/bar/bar/foo1") self.expectSucceedSubmit("Adding one file should not fail", "Simple Add") self.p4.run_sync("@0") self.addFile("bar/bar/bar/foo2") self.expectSucceedSubmit("Adding file with different name should not fail", "foo2") self.p4.run_sync("@0") self.addFile("bar/bar/bar/foo3") self.expectSucceedSubmit("Adding file with different name should not fail", "foo3") self.p4.run_sync("@0") self.addFile("bar/bar/bar/FOO2") self.expectFailSubmit("Adding file that differs by case should fail", "FOO2") @connect def testDirectoryFail_5(self): self.addFile("bar/bar/bar1/foo") self.expectSucceedSubmit("Adding one file should not fail", "foo") self.p4.run_sync("@0") self.addFile("bar/bar/bar2/foo") self.expectSucceedSubmit("Adding file with different name should not fail", "foo") self.p4.run_sync("@0") self.addFile("bar/bar/bar3/foo") self.expectSucceedSubmit("Adding file with different name should not fail", "foo") self.p4.run_sync("@0") self.addFile("bar/bar/bar4/Foo") self.expectSucceedSubmit("Adding file with different name should not fail", "Foo") self.p4.run_sync("@0") self.addFile("bar/bar/bar1/Foo") self.expectFailSubmit("Adding file that differs by case should fail", "Foo") @connect def testDirectoryFail_6(self): #Single file in unique directories; Two levels self.addFile("case_test/1_lowercase.text") self.expectSucceedSubmit("Adding one file should not fail", "foo") self.addFile("case_tesT/1_lowercase.text") self.addFile("case_tEst/1_lowercase.text") self.addFile("case_Test/1_lowercase.text") self.addFile("case_TEst/1_lowercase.text") self.addFile("casE_test/1_lowercase.text") self.addFile("cAse_test/1_lowercase.text") self.expectFailSubmit("Directories differ only by case", "case_test") @connect def testDirectoryFail_7(self): #Unique files in single directory; Two levels. self.addFile("case_test/1_lowercase.text") self.expectSucceedSubmit("Adding one file should not fail", "foo") self.addFile("cAse_test/1_lowercase.text") self.addFile("cAse_test/10_lowercase.text") self.addFile("cAse_test/100_lowercase.text") self.addFile("cAse_test/1000_lowercase.text") self.addFile("cAse_test/10000_lowercase.text") self.expectFailSubmit("Directories differ only by case", "case_test") @connect def testDirectoryFail_8(self): # Multiple files; Three levels. self.addFile("A/case_test/1_lowercase.text") self.addFile("A/case_test/10_lowercase.text") self.addFile("A/case_test/100_lowercase.text") self.addFile("A/case_test/1000_lowercase.text") self.addFile("A/case_test/10000_lowercase.text") self.expectSucceedSubmit("Adding files in A/case_test should not fail", "foo") #self.p4.run_sync("@0") self.addFile("A/cAse_test/1_lowercase.text") self.addFile("A/cAse_test/10_lowercase.text") self.addFile("A/cAse_test/100_lowercase.text") self.addFile("A/cAse_test/1000_lowercase.text") self.addFile("A/cAse_test/10000_lowercase.text") self.expectFailSubmit("A/case_test & A/cAse_test differ only by case", "case_test") @connect def testDirectoryFail_9(self): # Multiple files; Three levels. self.addFile("A/case_test/1_lowercase.text") self.addFile("A/case_test/10_lowercase.text") self.addFile("A/case_test/100_lowercase.text") self.addFile("A/case_test/1000_lowercase.text") self.addFile("A/case_test/10000_lowercase.text") self.expectSucceedSubmit("Adding files in A/case_test should not fail", "foo") self.addFile("A/B/case_test/1_lowercase.text") self.addFile("A/B/case_test/10_lowercase.text") self.addFile("A/B/case_test/100_lowercase.text") self.addFile("A/B/case_test/1000_lowercase.text") self.addFile("A/B/case_test/10000_lowercase.text") self.expectSucceedSubmit("Adding files in A/B/case_test should not fail", "foo") #self.p4.run_sync("@0") self.addFile("A/cAse_test/1_lowercase.text") self.addFile("A/cAse_test/10_lowercase.text") self.addFile("A/cAse_test/100_lowercase.text") self.addFile("A/cAse_test/1000_lowercase.text") self.addFile("A/cAse_test/10000_lowercase.text") self.addFile("A/B/cAse_test/1_lowercase.text") self.addFile("A/B/cAse_test/10_lowercase.text") self.addFile("A/B/cAse_test/100_lowercase.text") self.addFile("A/B/cAse_test/1000_lowercase.text") self.addFile("A/B/cAse_test/10000_lowercase.text") self.expectFailSubmit("A/B/case_test & A/B/cAse_test differ only by case", "case_test") @connect def testDirectoryFail_10(self): # Multiple files; Three levels; Differ at every level. self.addFile("A/B/case_test/1_lowercase.text") self.addFile("A/B/case_test/10_lowercase.text") self.addFile("A/B/case_test/100_lowercase.text") self.addFile("A/B/case_test/1000_lowercase.text") self.addFile("A/B/case_test/10000_lowercase.text") self.expectSucceedSubmit("Adding files in A/case_test should not fail", "foo") # Adds differ only by case at every level. self.addFile("a/b/cAse_test/1_Lowercase.text") self.addFile("a/b/cAse_test/10_Lowercase.text") self.addFile("a/b/cAse_test/100_Lowercase.text") self.addFile("a/b/cAse_test/1000_Lowercase.text") self.addFile("a/b/cAse_test/10000_Lowercase.text") self.expectFailSubmit("Should not add files that differ only by case", "a/b/cAse_test") @connect def testDirectoryFail_11(self): # One file at each level; Three levels; Differ at every level. self.addFile("A/1_lowercase.text") self.addFile("A/B/1_lowercase.text") self.addFile("A/B/case_test/1_lowercase.text") self.expectSucceedSubmit("Adding unique files should not fail", "A/B/case_test") # Adds differ only by case at every level. self.addFile("a/1_lowerCase.text") self.addFile("a/b/1_lowerCase.text") self.addFile("a/b/cAse_test/1_lowerCase.text") self.expectFailSubmit("Should not add files that differ only by case", "a/b/cAse_test") @connect def testDirectoryFail_12(self): # Two files at each level; Three levels; Differ at every level. self.addFile("A/1_lowercase.text") self.addFile("A/10_lowercase.text") self.addFile("A/B/1_lowercase.text") self.addFile("A/B/10_lowercase.text") self.addFile("A/B/case_test/1_lowercase.text") self.addFile("A/B/case_test/10_lowercase.text") self.expectSucceedSubmit("Adding unique files should not fail", "A/B/case_test") # Adds differ only by case at every level. self.addFile("a/1_lowerCase.text") self.addFile("a/10_lowerCase.text") self.addFile("a/b/1_lowerCase.text") self.addFile("a/b/10_lowerCase.text") self.addFile("a/b/cAse_test/1_lowerCase.text") self.addFile("a/b/cAse_test/10_lowerCase.text") self.expectFailSubmit("Should not add files that differ only by case", "a/b/cAse_test") @connect def testDirectoryFail_13(self): # Two files at each level; Four levels; Differ at every level. self.addFile("A/1_lowercase.text") self.addFile("A/10_lowercase.text") self.addFile("A/B/1_lowercase.text") self.addFile("A/B/10_lowercase.text") self.addFile("A/B/case_test/1_lowercase.text") self.addFile("A/B/case_test/10_lowercase.text") self.expectSucceedSubmit("Adding unique files should not fail", "A/B/case_test") # Unique adds. self.addFile("A/2_lowercase.text") self.addFile("A/20_lowercase.text") self.addFile("A/B/2_lowercase.text") self.addFile("A/B/20_lowercase.text") self.addFile("A/B/case_test/2_lowercase.text") self.addFile("A/B/case_test/20_lowercase.text") self.expectSucceedSubmit("Adding unique files should not fail", "A/B/case_test") # Some adds differ by case only at first level. self.addFile("A/B/case_test/3_lowercase.text") self.addFile("a/B/case_test/30_lowercase.text") self.expectFailSubmit("Should not add files that differ only by case", "A/B/case_test") # Some adds differ by case only at second level. self.addFile("A/B/case_test/4_lowercase.text") self.addFile("A/b/case_test/40_lowerCase.text") self.expectFailSubmit("Should not add files that differ only by case", "A/B/case_test") # Some adds differ by case only at third level. self.addFile("A/B/case_test/5_lowercase.text") self.addFile("A/B/Case_test/50_lowerCase.text") self.expectFailSubmit("Should not add files that differ only by case", "A/B/case_test") # Some adds differ by case only at fourth level. if (case_sensitive == True): self.addFile("A/B/case_test/6_lowercase.text") self.addFile("A/B/case_test/20_lowerCase.text") self.expectFailSubmit("Should not add files that differ only by case", "A/B/case_test") # Adds differ by case-only at every level self.addFile("a/2_lowerCase.text") self.addFile("a/20_lowerCase.text") self.addFile("a/b/2_lowerCase.text") self.addFile("a/b/20_lowerCase.text") self.addFile("a/b/case_Test/2_lowerCase.text") self.addFile("a/b/case_Test/20_lowerCase.text") self.expectFailSubmit("Should not add files that differ only by case", "A/B/case_test") @connect def testRenameFile(self): self.addFile("foo") self.expectSucceedSubmit("Adding one file should not fail", "Simple Add") self.p4.run_edit(self.localFile("foo")) self.p4.run_move(self.localFile("foo"), self.localFile("bar")) self.expectSucceedSubmit("Renaming a file should not fail", "Simple Move") @connect @unittest.skipUnless(sys.platform.startswith("linux"), "requires linux") def testRenameFail(self): self.addFile("foo") self.addFile("bar") self.expectSucceedSubmit("Adding two files should not fail", "Double Add") if case_sensitive == True: self.p4.run_sync("%s@0" % self.localFile("bar")) self.p4.run_edit(self.localFile("foo")) self.p4.run_move(self.localFile("foo"), self.localFile("BAR")) self.p4.run_move(self.localFile("foo"), self.localFile("bar")) self.expectFailSubmit("Moving into a file with existing naming conflict should not succeed", "Illegal move") @connect def testDirectoryConflictFail(self): self.addFile("foo") self.expectSucceedSubmit("Adding single file should not fail", "Simple Add") self.p4.run_sync("@0") #self.logger.debug("testDirectoryConflictFail1: dirs= %s", self.p4.run_dirs("//depot/*")) #self.logger.debug("testDirectoryConflictFail1: files= %s", self.p4.run_files("//depot/...")) self.addFile("FOO/bar") self.expectFailSubmit("Adding a directory conflicting with an existing file should not succeed", "Illegal add") @connect def testMultipleLevelWildcardFail(self): # 9 *'s self.addFile("1/2/3/4/5/6/7/8/9/foo9.txt") self.expectSucceedSubmit("Adding single file should not fail", "1/2/3/4/5/6/7/8/9/foo9.txt") self.p4.run_sync("@0") # 9 *'s + 2 * self.addFile("1/2/3/4/5/6/7/8/9/10/foo10.txt") self.expectSucceedSubmit("Adding single file should not fail", "1/2/3/4/5/6/7/8/9/10/foo10.txt") self.p4.run_sync("@0") # 18 *'s self.addFile("1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/foo18.txt") self.expectSucceedSubmit("Adding single file should not fail", "1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/foo18.txt") self.p4.run_sync("@0") # 18 *'s + 2 * self.addFile("1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/foo19.txt") self.expectSucceedSubmit("Adding single file should not fail", "1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/foo19.txt") self.p4.run_sync("@0") # Add file that only differs by case. self.addFile("1/2/3/4/5/6/7/8/9/10/11/12/13/14/15/16/17/18/19/FOO19.txt") self.expectFailSubmit("Adding a file conflicting with an existing file should not succeed", "Illegal add") @connect def testFileWithDirectoryConflictFail(self): self.logger.debug("testFileWithDirectoryConflict: dirs= %s", self.p4.run_dirs("//depot/*")) self.addFile("FOO/bar") self.expectSucceedSubmit("Adding single file should not fail", "Simple Add") self.p4.run_sync("@0") os.rmdir(os.path.join(self.client_root, "FOO")) self.addFile("foo") self.expectFailSubmit("Adding a file conflicting with an existing directory should not succeed", "Illegal add") @connect @unittest.skipUnless(sys.platform.startswith("linux"), "requires linux") def testFileWithDirectorySameChangeFail(self): self.addFile("FOO/bar") self.addFile("foo") self.expectFailSubmit("Adding a file conflicting with an existing directory should not succeed", "Illegal add") @connect @unittest.skipUnless(sys.platform.startswith("linux"), "requires linux") def testMultipleFilesFail(self): if (case_sensitive == True): self.addFile("foo") self.addFile("FOO") self.expectFailSubmit("Adding two conflicting files should not succeed", "Illegal add") @connect @unittest.skipUnless(sys.platform.startswith("linux"), "requires linux") def testMultipleDirectoriesFail(self): if (case_sensitive == True): self.addFile("foo/foo") self.addFile("FOO/foo") self.expectFailSubmit("Adding two conflicting directories should not succeed", "Illegal add") @connect @unittest.skipUnless(sys.platform.startswith("linux"), "requires linux") def testMessageFail(self): if (case_sensitive == True): self.addFile("foo") self.addFile("Foo") try: self.p4.run_submit('-d','Expect to fail') self.fail("Illegal add did not cause exception") except P4.P4Exception as exc: error = exc.errors[0] self.logger.debug("testMessageFail: error = %s", error) self.assertTrue('//depot/foo' in error) self.assertTrue('//depot/Foo' in error) if __name__ == '__main__': # Determine if we're testing on a case-sensitive or case-insensitive server. kwargs = {} for arg in sys.argv[1:]: p = arg.split("=", 1) if len(p) != 1: kwargs[p[0]] = p[1] #print("kwargs: %s" % kwargs) # case_sensitive is initialized to True # Note: Need to remove 'case_sensitive' after test as it's not a valid unittest argument. if 'case_sensitive' in kwargs: if kwargs['case_sensitive'] == 'False': case_sensitive = False sys.argv.pop() #print("case_sensitive: = %s" % case_sensitive) #print("cmd_entry2: %s" % sys.argv) unittest.main()