TestCheckCaseTrigger.py #7

  • //
  • guest/
  • perforce_software/
  • sdp/
  • main/
  • Unsupported/
  • Samples/
  • triggers/
  • tests/
  • TestCheckCaseTrigger.py
  • View
  • Commits
  • Open Download .zip Download (44 KB)
from __future__ import print_function

import unittest
import time, os, sys
import logging
import inspect
import platform
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
import CheckCaseTrigger

# 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 = platform.system() == "Linux"
default_depot = "depot"

# 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):
        if not self.p4.connected():
            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 TestCheckCaseTriggerBasic(TestCase):
    """Test class which doesn't reqired p4d scaffolding"""

    def __init__(self, methodName='runTest'):
        super(TestCheckCaseTriggerBasic, self).__init__(LOGGER_NAME, LOG_FILE, methodName=methodName)

    def testBasic(self):
        # Fudge issues with trigger
        CheckCaseTrigger.AllowBypass = 0
        args = ["1"]
        ct = CheckCaseTrigger.CheckCaseTrigger(*args)
        f = []
        self.assertEqual({}, ct.getDirList(f))
        self.assertEqual({}, ct.getFileDirList(f))

        f = ["//d/a.txt"]
        ct.caseSensitive = True
        self.assertEqual({"d": "d"}, ct.getDirList(f))
        self.assertEqual({"d": "d"}, ct.getFileDirList(f))
        ct.caseSensitive = False
        self.assertEqual({"d": "d"}, ct.getDirList(f))
        self.assertEqual({"d": "d"}, ct.getFileDirList(f))

        # Depot name case
        f = ["//D/a.txt"]
        ct.caseSensitive = True
        self.assertEqual({"D": "D"}, ct.getDirList(f))
        self.assertEqual({"D": "D"}, ct.getFileDirList(f))
        ct.caseSensitive = False
        self.assertEqual({"d": "D"}, ct.getDirList(f))
        self.assertEqual({"d": "D"}, ct.getFileDirList(f))

        f = ["//d/a/b.txt"]
        self.assertEqual({"d": "d", "d/a": "d/a"}, ct.getDirList(f))
        self.assertEqual({"d": "d/a", "d/a": "d/a"}, ct.getFileDirList(f))

        f = [
            "//d/a/b.txt",
            "//d/b/c.txt",
            ]
        self.assertEqual(set(["d", "d/a", "d/b"]), set(ct.getDirList(f).keys()))
        self.assertEqual(set(["d", "d/a", "d/b"]), set(ct.getFileDirList(f).keys()))

        f = [
            "//d/a/f.txt",
            "//d/b/c/d/g.txt",
            ]
        self.assertEqual(set(["d", "d/a", "d/b", "d/b/c", "d/b/c/d"]), set(ct.getDirList(f).keys()))
        self.assertEqual(set(["d", "d/a", "d/b", "d/b/c", "d/b/c/d"]), set(ct.getFileDirList(f).keys()))

        f = [
            "//d/a/f.txt",
            "//d/a/b/C/g.txt",
            "//d/a/b/C/h.txt",
            ]
        ct.caseSensitive = True
        self.assertEqual(set(["d", "d/a", "d/a/b", "d/a/b/C"]), set(ct.getDirList(f).keys()))
        self.assertEqual(set(["d", "d/a", "d/a/b", "d/a/b/C"]), set(ct.getFileDirList(f).keys()))
        ct.caseSensitive = False
        self.assertEqual(set(["d", "d/a", "d/a/b", "d/a/b/c"]), set(ct.getDirList(f).keys()))
        self.assertEqual(set(["d", "d/a", "d/a/b", "d/a/b/c"]), set(ct.getFileDirList(f).keys()))

    def setUp(self):
        CheckCaseTrigger.AllowBypass = 0
        args = ["1"]
        self.trigger = CheckCaseTrigger.CheckCaseTrigger(*args)
        self.files = []
        self.depotFiles = []
        self.trigger.options.log = "_log.test.log"
        self.trigger.options.verbosity = logging.DEBUG
        self.trigger.init_logger()
        self.logger = self.trigger.logger
        self.trigger.depotCache['depot'] = 'depot'

    def addFile(self, name, depot=default_depot):
        self.files.append("%s/%s" % (depot, name))

    def createFiles(self, testDir, depot=default_depot):
        files = ('foo.txt', 'bar.txt', 'baz.txt')
        for f in files:
            self.addFile("%s/%s" % (testDir, f), depot=depot)

    def applySubmitState(self):
        "Pretend to do a submit by adding all files from latest submit to the depot"
        self.depotFiles.extend(self.files)
        self.files = []
        self.logger.debug("depot files: %s" % self.depotFiles)

    def expectFailSubmit(self, msg, desc=None):
        """validate depot files"""
        # Look for files in cache. This includes looking for directories in file path.
        badlist = {}
        depotFiles = ["//" + f for f in self.depotFiles]
        depotFiles.extend(["//" + f for f in self.files])
        self.trigger.searchCache(depotFiles, badlist)
        self.logger.debug("badlist: %s" % badlist)
        if len(badlist) == 0:
            self.fail(msg)

    def expectSucceedSubmit(self, msg, desc=None):
        """expect validation to succeed"""
        badlist = {}
        depotFiles = ["//" + f for f in self.depotFiles]
        depotFiles.extend(["//" + f for f in self.files])
        self.trigger.searchCache(depotFiles, badlist)
        self.logger.debug("badlist: %s" % badlist)
        if len(badlist) != 0:
            self.fail(msg)
        self.applySubmitState()

    def testSimpleSubmit(self):
        testDir = 'test_files'
        self.createFiles(testDir)
        self.expectSucceedSubmit("failed")

    def testSimpleFail(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        self.addFile("foo")
        self.expectSucceedSubmit("Adding one file should not fail")

        self.addFile("Foo")
        self.expectFailSubmit("Did not catch foo != Foo")

    def testSimpleSubmitMD(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # Submit with multiple depots
        depot2 = "depot2"
        self.trigger.depotCache['depot2'] = 'depot2'
        testDir = 'test_files'

        self.createFiles(testDir)
        self.createFiles(testDir, depot=depot2)
        self.expectSucceedSubmit("Failed to submit the add", "My Add Test")

    def testDirectoryFail(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        self.addFile("foo/bar")
        self.expectSucceedSubmit("Adding one file should not fail", "Simple Add")

        self.addFile("FOO/bar")
        self.expectFailSubmit("Did not catch foo != FOO/bar", "bar")

    def testDirectoryFail_4(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        self.addFile("bar/bar/bar/foo1")
        self.expectSucceedSubmit("Adding one file should not fail", "Simple Add")

        self.addFile("bar/bar/bar/foo2")
        self.expectSucceedSubmit("Adding file with different name should not fail", "foo2")

        self.addFile("bar/bar/bar/foo3")
        self.expectSucceedSubmit("Adding file with different name should not fail", "foo3")

        self.addFile("bar/bar/bar/FOO2")
        self.expectFailSubmit("Adding file that differs by case should fail", "FOO2")

    def testDirectoryFail_5(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        self.addFile("bar/bar/bar1/foo")
        self.expectSucceedSubmit("Adding one file should not fail", "foo")

        self.addFile("bar/bar/bar2/foo")
        self.expectSucceedSubmit("Adding file with different name should not fail", "foo")

        self.addFile("bar/bar/bar3/foo")
        self.expectSucceedSubmit("Adding file with different name should not fail", "foo")

        self.addFile("bar/bar/bar4/Foo")
        self.expectSucceedSubmit("Adding file with different name should not fail", "Foo")

        self.addFile("bar/bar/bar1/Foo")
        self.expectFailSubmit("Adding file that differs by case should fail", "Foo")

    def testDirectoryFail_6(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")

    def testDirectoryFail_7(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")

    def testDirectoryFail_8(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")

    def testDirectoryFail_9(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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.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")

    def testDirectoryFail_10(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")

    def testDirectoryFail_11(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")

    def testDirectoryFail_12(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")

    def testDirectoryFail_13(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")

        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")

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 {} -v DEBUG %change% "'.format(pythonVer, trigpath, port, p4.user)]
        self.logger.debug(triggers)
        p4.save_triggers(triggers)
        # Reconnect to pick up changes
        p4.disconnect()
        p4.connect()
        # Reset client to include depot in RHS
        client = self.p4.fetch_client(self.server.client_name)
        client._view = "//%s/... //%s/%s/..." % (default_depot, self.server.client_name, default_depot)
        p4.save_client(client)

    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, default_depot, name)

    def addFile(self, name, depot=default_depot):
        makedirs(os.path.join(self.client_root, depot), exist_ok=True)
        path, filename = os.path.split(name)
        if path:
            pname = os.path.join(self.client_root, depot, path)
            makedirs(pname, exist_ok=True)
        fname = os.path.join(self.client_root, depot, 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.save_submit(*args)
            self.assertTrue('submittedChange' in result[-1], msg)
        except P4.P4Exception as inst:
            self.fail("submit failed with exception ")

    def createFiles(self, testDir, depot=default_depot):
        testAbsoluteDir = os.path.join(self.client_root, depot, testDir)
        makedirs(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)

        if depot == default_depot:
            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)

    def createDepot(self, depot):
        """Creates specified depot and add to client view - for multi depot tests"""
        d = self.p4.fetch_depot(depot)
        self.p4.save_depot(d)
        
        client = self.p4.fetch_client(self.server.client_name)
        client._view = [
            "//%s/... //%s/%s/..." % (default_depot, self.server.client_name, default_depot),
            "//%s/... //%s/%s/..." % (depot, self.server.client_name, depot)
        ]
        self.p4.save_client(client)

    @connect
    def testSimpleSubmit(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        self.assertEqual(len(self.p4.run_opened()), 0, "Shouldn't have open files")

        testDir = 'test_files'
        self.createFiles(testDir)
        self.expectSucceedSubmit("Failed to submit the add", "My Add Test")


    @connect
    def testSimpleEdit(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        self.assertEqual(len(self.p4.run_opened()), 0, "Shouldn't have open files")

        testDir = 'test_files'
        self.createFiles(testDir)
        self.expectSucceedSubmit("Failed to submit the add", "My Add Test")

        self.p4.run_edit("//depot/test_files/bar.txt")
        self.expectSucceedSubmit("Failed to submit the edit ", "My Edit Test")

        # self.p4.run_populate("//depot/test_files/...", "//depot/test_files2/...")
        # self.expectSucceedSubmit("Failed to submit the populate", "My Populate Test")

    @connect
    def testSimpleSubmitMD(self):
        # Submit with multiple depots
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        self.assertEqual(len(self.p4.run_opened()), 0, "Shouldn't have open files")

        depot = "depot2"
        self.createDepot(depot)
        testDir = 'test_files'

        self.createFiles(testDir)
        self.createFiles(testDir, depot=depot)
        self.expectSucceedSubmit("Failed to submit the add", "My Add Test")

        depot = "Depot3"
        self.createDepot(depot)
        testDir = 'test_files2'
        self.createFiles(testDir, depot=depot)
        self.expectSucceedSubmit("Failed to submit the add", "My Add Test")

    @connect
    def testSimpleFail(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        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 testSimpleFailMD(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        depot2 = "depot2"
        self.createDepot(depot2)
        self.addFile("foo")
        self.addFile("foo", depot=depot2)
        self.expectSucceedSubmit("Adding one file per depot should not fail", "Simple Add")

        self.p4.run_sync("@0")
        self.addFile("Foo")
        self.addFile("Foo", depot=depot2)
        self.expectFailSubmit("Did not catch foo != Foo", "Foo")

    @connect
    def testP4Files(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")

        if not case_sensitive:
            return

        # 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.logger.debug("================ %s" % inspect.stack()[0][3])
        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.logger.debug("================ %s" % inspect.stack()[0][3])
        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")

        if case_sensitive:
            self.addFile("FOO/BAR")
            self.expectFailSubmit("Did not catch foo/bar/bar2 != FOO/BAR", "bar")

            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.logger.debug("================ %s" % inspect.stack()[0][3])
        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.logger.debug("================ %s" % inspect.stack()[0][3])
        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.logger.debug("================ %s" % inspect.stack()[0][3])
        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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # Single file in unique directories; Two levels
        self.addFile("case_test/1_lowercase.text")
        self.expectSucceedSubmit("Adding one file should not fail", "foo")

        self.p4.run_sync("@0")
        if not case_sensitive:
            self.addFile("case_tesT/1_lowercase1.text")
        else:
            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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # Unique files in single directory; Two levels.
        self.addFile("case_test/1_lowercase.text")
        self.expectSucceedSubmit("Adding one file should not fail", "foo")

        if case_sensitive:
            self.addFile("cAse_test/1_lowercase.text")
        self.addFile("cAse_test/10_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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")
        if not case_sensitive:
            self.addFile("A/cAse_test/1_lowercase1.text")
            self.addFile("A/cAse_test/10_lowercase1.text")
            self.addFile("A/cAse_test/100_lowercase1.text")
            self.addFile("A/cAse_test/1000_lowercase1.text")
            self.addFile("A/cAse_test/10000_lowercase1.text")
        else:
            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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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")

        if not case_sensitive:
            self.addFile("A/cAse_test/1_lowercase1.text")
            self.addFile("A/B/cAse_test/1_lowercase1.text")
        else:
            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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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.
        if not case_sensitive:
            self.addFile("a/b/cAse_test/1_Lowercase1.text")
        else:
            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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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.
        if not case_sensitive:
            self.addFile("a/1_lowerCase1.text")
            self.addFile("a/b/1_lowerCase1.text")
            self.addFile("a/b/cAse_test/1_lowerCase1.text")
        else:
            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
    @unittest.skipUnless(sys.platform.startswith("linux"), "requires linux")
    def testDirectoryFail_12(self):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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:
            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")
        else:
            self.p4.run_sync("@0")

        # 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.logger.debug("================ %s" % inspect.stack()[0][3])
        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.logger.debug("================ %s" % inspect.stack()[0][3])
        self.addFile("foo")
        self.addFile("bar")
        self.expectSucceedSubmit("Adding two files should not fail", "Double Add")
        if case_sensitive:
            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.logger.debug("================ %s" % inspect.stack()[0][3])
        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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        # 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("================ %s" % inspect.stack()[0][3])
        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, default_depot, "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.logger.debug("================ %s" % inspect.stack()[0][3])
        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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        if case_sensitive:
            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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        if case_sensitive:
            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):
        self.logger.debug("================ %s" % inspect.stack()[0][3])
        if case_sensitive:
            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()
# Change User Description Committed
#7 30043 C. Thomas Tyler Released SDP 2023.2.30041 (2023/12/22).
Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'.
#6 29954 C. Thomas Tyler Released SDP 2023.1.29949 (2023/12/01).
Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'.
#5 29401 C. Thomas Tyler Released SDP 2022.2.29399 (2023/02/06).
Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'.
#4 29205 C. Thomas Tyler Released SDP 2022.1.29203 (2022/11/22).
Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'.
#3 29143 C. Thomas Tyler Released SDP 2022.1.29141 (2022/10/29).
Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'.
#2 28240 C. Thomas Tyler Released SDP 2021.1.28238 (2021/11/12).
Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'.
#1 27331 C. Thomas Tyler Released SDP 2020.1.27325 (2021/01/29).
Copy Up using 'p4 copy -r -b perforce_software-sdp-dev'.
//guest/perforce_software/sdp/dev/Unsupported/Samples/triggers/tests/TestCheckCaseTrigger.py
#1 26652 Robert Cowham This is Tom's change:

Introduced new 'Unsupported' directory to clarify that some files
in the SDP are not officially supported. These files are samples for
illustration, to provide examples, or are deprecated but not yet
ready for removal from the package.

The Maintenance and many SDP triggers have been moved under here,
along with other SDP scripts and triggers.

Added comments to p4_vars indicating that it should not be edited
directly. Added reference to an optional site_global_vars file that,
if it exists, will be sourced to provide global user settings
without needing to edit p4_vars.

As an exception to the refactoring, the totalusers.py Maintenance
script will be moved to indicate that it is supported.

Removed settings to support long-sunset P4Web from supported structure.

Structure under new .../Unsupported folder is:
   Samples/bin             Sample scripts.
   Samples/triggers        Sample trigger scripts.
   Samples/triggers/tests  Sample trigger script tests.
   Samples/broker          Sample broker filter scripts.
   Deprecated/triggers     Deprecated triggers.

To Do in a subsequent change: Make corresponding doc changes.
//guest/perforce_software/sdp/dev/Server/Unix/p4/common/bin/triggers/tests/TestCheckCaseTrigger.py
#1 25715 Robert Cowham Refactor CheckCaseTrigger to work in SDP trigger style - and fix SDP failures.
       Added modified version of Sven's test harness which works (for Mac at least where
some tests must be skipped due to filesystem being case insensitive).