def test_configFileCreation(self): """Test basic functionality. You call config and specify the entries. The generated config file should contain the same information. Make sure that the config file creation works if the configDir exists already or not and an old config file exists already or not """ hostNameEntry = "TestHostName\n" apiTokenEntry = "TestApiKey\n" # Config Dir Config File # Exists Exists with util.TempDir() as td: d = td.dir() with open(os.path.join(d, wavectl.ConfigCommand.configFileName), "w"): self.configFileCreationTest(d, hostNameEntry, apiTokenEntry) # Config Dir Config File # Exists Does Not with util.TempDir() as td: d = td.dir() self.configFileCreationTest(d, hostNameEntry, apiTokenEntry) # Config Dir Config File # Does Not Does Not d = tempfile.mkdtemp() shutil.rmtree(d, ignore_errors=True) self.configFileCreationTest(d, hostNameEntry, apiTokenEntry)
def repoDirHasUntrackedFiles(self, rsrcType, rsrcs): """The repoDir has some untracked files and the user attempts to do a pull.""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.createPullBranch(r, wavectl.PullCommand.datetimeFormat, wavectl.PullCommand.pullBranchSuffix) # Create a new file in the repoDir without adding it to the index n = "newFile" fn = os.path.join(d, n) with open(fn, "w") as f: f.write("Some new modification") # The alert pull command is expected to work even though there are some # uncommitted_files in the repo. So we should expect to see these files # in the repoDir self.executePull(rsrcType, d, r, rsrcs, additionalFileNames=[n], pullAdditionalParams=["--inGit"])
def noBranchNameForMergeIntoBranch(self, rsrcType, rsrcs): """The "noBranchName" is passed as merge-into-branch parameter. We do not expect any merge to the master branch to happen. The pull operation should only create a pull branch and switch back to the initial branch""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.createPullBranch(r, wavectl.PullCommand.datetimeFormat, wavectl.PullCommand.pullBranchSuffix) # Since the --merge-into-branch parameter was passed as None, there # should not be any resource files in the master branch. self.executePull(rsrcType, d, r, [], pullAdditionalParams=[ "--inGit", "--merge-into-branch", "None" ]) # However resources should exist in the latest pull branch. # In case of --merge--into-branch=None, the pull still happens. But the # retrieved files are not merged into any other branch. npb = self.getNewestPullBranch( r, wavectl.PullCommand.pullBranchSuffix) npb.checkout() self.checkFilesInDir(rsrcType, rsrcs, d, additionalFileNames=["README.md"]) self.assertTrue(not r.is_dirty(untracked_files=True))
def test_parse_relative_path(self): # this makes sure we convert a relative path to absolute # hiddenServiceDir args. see Issue #77 # make sure we have a valid thing from get_global_tor without # actually launching tor config = TorConfig() config.post_bootstrap = defer.succeed(config) from txtorcon import torconfig torconfig._global_tor_config = None get_global_tor( self.reactor, _tor_launcher=lambda react, config, prog: defer.succeed(config)) orig = os.path.realpath('.') try: with util.TempDir() as t: t = str(t) os.chdir(t) os.mkdir(os.path.join(t, 'foo')) hsdir = os.path.join(t, 'foo', 'blam') os.mkdir(hsdir) ep = serverFromString( self.reactor, 'onion:88:localPort=1234:hiddenServiceDir=foo/blam') self.assertEqual(os.path.realpath(hsdir), ep.hidden_service_dir) finally: os.chdir(orig)
def deletedRsrcs(self, rsrcType, rsrcs): """Some resources get deleted in the wavefront gui. Make sure consecutive pulls do not retain those resources. The resource' files in the pull directory also get deleted in following pulls""" assert len( rsrcs) > 5 and "This test expects to have a handful of resources" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.createPullBranch(r, wavectl.PullCommand.datetimeFormat, wavectl.PullCommand.pullBranchSuffix) self.executePull(rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"]) time.sleep(2) # Mock the deleted rsrcs call to return a value. rt = util.resourceTypeFromString(rsrcType) util.mockRsrcType(rt, rsrcs[2:], rsrcs[0:2]) # Do another pull. After that make sure that the deleted alert's file # also disappears. self.executePull(rsrcType, d, r, rsrcs[2:], pullAdditionalParams=["--inGit"])
def pushSingleFile(self, rsrcType, rsrcs, pushedRsrc, matchParams, expectedOutRegex): """ Select one file to push. Only the resource represented in that file should be pushed to the wavefront server. If pushMatchesTargetFile parameter is false, the push command will have accompanying match parameters that will not match with the resource in the file. The single file push attempt will actually not write anything to the wavefront server""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.executePull(rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"]) # Compile the full path of the single file to be pushed. targetRsrc = pushedRsrc rt = util.resourceTypeFromString(rsrcType) fileName = str(targetRsrc[rt._uniqueKey]) + rt.fileExtension() target = os.path.join(d, fileName) out = self.executePush(rsrcType, target, pushAdditionalParams=["--inGit"], rsrcAdditionalParams=matchParams) actualOut = out.strip().split("\n") util.SummaryLineProcessor.compareExpectedActualLineByLine( self, expectedOutRegex, actualOut)
def pullIntoSubdirInRepo(self, rsrcType, rsrcs, subdirState): """The given directory is to a subdir of a git repo. Depending on the subdirState parameter, the pull happens on an existing subdir or on a new subdir.""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.createPullBranch(r, wavectl.PullCommand.datetimeFormat, wavectl.PullCommand.pullBranchSuffix) subdirName = "subdir" subdir = os.path.join(d, subdirName) if subdirState == self.existingDir: os.mkdir(subdir) self.executePull(rsrcType, subdir, r, rsrcs, pullAdditionalParams=["--inGit"]) repoInSubdir = git.Repo(subdir, search_parent_directories=True) self.assertEqual(r.working_tree_dir, repoInSubdir.working_tree_dir)
def multiPull(self, rsrcType, rsrcs, firstExpectedRsrs, firstAdditionalParams, secondExpectedRsrs, secondAdditionalParams): """Execute multiple pull operations and make sure all expected resources are in the final directory""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.createPullBranch(r, wavectl.PullCommand.datetimeFormat, wavectl.PullCommand.pullBranchSuffix) self.executePull(rsrcType, d, r, firstExpectedRsrs, pullAdditionalParams=["--inGit"], rsrcAdditionalParams=firstAdditionalParams) time.sleep(2) self.executePull(rsrcType, d, r, secondExpectedRsrs, pullAdditionalParams=["--inGit"], rsrcAdditionalParams=secondAdditionalParams)
def repoIsDirtyInDifferentDir(self, rsrcType, rsrcs, whatIsDirty): """Execute a pull operation on a git repo that is dirty because of some changes in another directory than the pull directory. Depending on the whatIsDirty parameter the changes may be staged or not-yet-staged.""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.createPullBranch(r, wavectl.PullCommand.datetimeFormat, wavectl.PullCommand.pullBranchSuffix) cleanSubdirName = "cleanSubdir" cleanSubdir = os.path.join(d, cleanSubdirName) os.mkdir(cleanSubdir) dirtySubdirName = "dirtySubdir" dirtySubdir = os.path.join(d, dirtySubdirName) os.mkdir(dirtySubdir) newFileName = "file1" self.addNewFileToRepo(r, newFileName, subdir=dirtySubdirName) if whatIsDirty == self.index: pass elif whatIsDirty == self.workingTree: # In order to make the working tree dirty we commit the file # and make a local modification on it. r.index.commit( "Initial commit of {0} file".format(newFileName), skip_hooks=True) # File1 has local modifications in a separate subdir from the # actual pull directory. fp = os.path.join(d, dirtySubdirName, newFileName) with open(fp, "r+") as f: f.write("Some new modification") else: assert not "Unexpected value in whatIsDirty" assert(r.is_dirty()) args = ["pull", d, "--inGit", rsrcType] wc = wavectl.Wavectl( designForTestArgv=args, designForTestRsrcs=rsrcs) self.assertRaisesRegexp( wavectl.PullError, (r"The path at .+ is dirty. " r"Please commit your outstanding changes .*"), wc.runCmd)
def emptyPush(self, rsrcType, expectedOutRegex): """Execute a push operation without any entries in the directory. The wavectl actually does not send any PUSH requests in this case""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) out = self.executePush(rsrcType, d, pushAdditionalParams=["--inGit"]) actualOut = out.strip().split("\n") util.SummaryLineProcessor.compareExpectedActualLineByLine( self, expectedOutRegex, actualOut)
def existingRepoDir(self, rsrcType, rsrcs): """The pull <rsrc> command is passed a directory that is an already initialized empty git repo. Command impl should use that directory and add files to it.""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.createPullBranch(r, wavectl.PullCommand.datetimeFormat, wavectl.PullCommand.pullBranchSuffix) self.executePull(rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"])
def repoIsDirtyInDifferentDir(self, rsrcType, rsrcs, whatIsDirty, expectedOutRegex): """The repo is dirty in a different sub-dir than the subdir used for push. Depending on the whatIsDirty value, either the index is dirty or the working tree is dity""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) cleanSubdirName = "cleanSubdir" cleanSubdir = os.path.join(d, cleanSubdirName) # The pull will also create the cleanSubdir self.executePull(rsrcType, cleanSubdir, r, rsrcs, pullAdditionalParams=["--inGit"]) dirtySubdirName = "dirtySubdir" dirtySubdir = os.path.join(d, dirtySubdirName) os.mkdir(dirtySubdir) newFileName = "file1" self.addNewFileToRepo(r, newFileName, subdir=dirtySubdirName) if whatIsDirty == self.index: pass elif whatIsDirty == self.workingTree: # In order to make the working tree dirty we commit the file # and make a local modification on it. r.index.commit( "Initial commit of {0} file".format(newFileName)) fp = os.path.join(d, dirtySubdirName, newFileName) with open(fp, "r+") as f: f.write("Some new modification") else: assert not "Unexpected value in whatIsDirty" assert (r.is_dirty()) out = self.executePush(rsrcType, cleanSubdir, pushAdditionalParams=["--inGit"]) actualOut = out.strip().split("\n") util.SummaryLineProcessor.compareExpectedActualLineByLine( self, expectedOutRegex, actualOut)
def pullWithoutAPullBranch(self, rsrcType, rsrcs): """ The repo does not have a pull branch. That should mean that this is the first pull happening to this git repo. In that case the pull operation creates the pull branch from the current branch the repo was on.""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) # Do not create a pull branch !! self.executePull(rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"])
def noChangePush(self, rsrcType, rsrcs, expectedOutRegex): """ First do a pull and then do a push without changing any of the files""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) # First execute a pull to populate a directory with the resources. self.executePull(rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"]) out = self.executePush(rsrcType, d, pushAdditionalParams=["--inGit"]) actualOut = out.strip().split("\n") util.SummaryLineProcessor.compareExpectedActualLineByLine( self, expectedOutRegex, actualOut)
def pushWithCustomerTag(self, rsrcType, rsrcs, rsrcAdditionalParams, expectedOutRegex, callFromParent=False): """The push operation has multiple cusomer tags. The tags should be effectively AND'ed and resources that match all tags should be sent in the push request. That is the same behavior when we are passing tags to get requests to the webfront server""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.executePull(rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"]) # In some test cases we execute this test from another # directory than the directory with the resources. if callFromParent: parentDir = os.path.dirname(d) dirName = os.path.basename(d) else: dirName = d with util.CwdChanger(parentDir) if callFromParent \ else util.DummyContextManager() as cc: out = self.executePush( rsrcType, dirName, pushAdditionalParams=["--inGit"], rsrcAdditionalParams=rsrcAdditionalParams) actualOut = out.strip().split("\n") util.SummaryLineProcessor.compareExpectedActualLineByLine( self, expectedOutRegex, actualOut)
def pushTargetFileIsDirty(self, rsrcType): """Push is using one file to push. In a repo the pushed single file is dirty. Push should complain""" rt = util.resourceTypeFromString(rsrcType) with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) fileName = "newRsrc" + rt.fileExtension() self.addNewFileToRepo(r, fileName) args = ["push", os.path.join(d, fileName), "--inGit", rsrcType] wc = wavectl.Wavectl(designForTestArgv=args) self.assertRaisesRegexp( wavectl.MutatorError, (r"The path at .+ is dirty. " r"Please commit your outstanding changes .*"), wc.runCmd)
def noChangePull(self, rsrcType, rsrcs): """Between two pull attempts there has not been any change to the resources. The second pull should just work even though there is nothing to commit""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.createPullBranch(r, wavectl.PullCommand.datetimeFormat, wavectl.PullCommand.pullBranchSuffix) self.executePull(rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"]) # Current time is used for the branch names. So we need to wait for # some time to elapse so a new pull branch with a different name # can be created. time.sleep(2) oldRef = r.head.ref oldCommit = r.head.commit # Without any change, do another pull self.executePull(rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"]) # Since there has not been any change to the resources. The head # and the commit should not change self.assertEqual(oldRef, r.head.ref) self.assertEqual(oldCommit, r.head.commit)
def createSingleRsrc(self, rsrcType, rsrc, expectedOutRegex): """Test the creation of one rsrc. Write the json blob of the given rsrc on a file and call create on it. Create function prints out the summary line for the created rsrc. After create's completion, compare the stdout""" with util.TempDir() as td: d = td.dir() # Write the selected resource to create it in the wavefront # server via wavectl create. rt = util.resourceTypeFromString(rsrcType) targetFile = tempfile.NamedTemporaryFile(mode="w", dir=d, delete=False, suffix=rt.fileExtension()) json.dump(rsrc, targetFile) targetFile.close() # so that writes are flushed. out = self.executeCreate(rsrcType, targetFile.name) actualOut = out.strip().split("\n") util.SummaryLineProcessor.compareExpectedActualLineByLine( self, expectedOutRegex, actualOut)
def existingVanillaDir(self, rsrcType, rsrcs): """The pull operation is done on a regular dir outside of source control""" with util.TempDir() as td: d = td.dir() self.executePull(rsrcType, d, None, rsrcs)
def mergeConflictDuringPull(self, rsrcType, rsrcs): """By the time we execute a pull, there has been changes both on the local files and on the wavefront database, so that the pull results in a merge conflict. The wavectl raises and exception and expects the user to resolve this merge conflict and merge the pull branch manually to the desired branch (possibly the master branch)""" with util.TempDir() as td: d = td.dir() r = self.repoInit(d) self.addReadmeFileToRepo(r) self.createPullBranch(r, wavectl.PullCommand.datetimeFormat, wavectl.PullCommand.pullBranchSuffix) self.executePull(rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"]) rt = util.resourceTypeFromString(rsrcType) # Get the first resource and modify it locally. Without changing the # passed rsrcs collection rsrc = copy.deepcopy(rsrcs[0]) # Do the local change # Some key name that exists in all supported resources conflictingField = "name" oldValue = rsrc[conflictingField] rsrc[conflictingField] = "Adding some local change " + oldValue uniqueId = str(rsrc[rt._uniqueKey]) with open(os.path.join(d, uniqueId + rt.fileExtension()), "w") as f: # The separators avoid the trailing whitespace. json.dump( rsrc, f, sort_keys=True, indent=4, separators=( ',', ': ')) r.index.add([f.name]) r.index.commit("Modified the file: {0}".format( uniqueId + rt.fileExtension())) assert(not r.is_dirty()) # TODO: Maybe the pull branch name should contain a microsecond portion # wait so that the new pull branch name would be different. time.sleep(2) # Modify the same alert in a different way "remotely" rsrc[conflictingField] = "Adding some remote change " + oldValue # The first rsrcs has been modified and duplicated in one variable # the rest comes from the function parameters. # Re-mock the rsrcTypes to return the newly modified resource # collection. util.mockRsrcType(rt, [rsrc] + rsrcs[1:], []) try: self.executePull( rsrcType, d, r, rsrcs, pullAdditionalParams=["--inGit"]) except git.GitCommandError as e: assert re.search( (r"stdout: 'Auto-merging .+\.(alert|dashboard).*\n.*" r"CONFLICT [(].+[)]: " r"Merge conflict in .*\.(alert|dashboard).*\n.*" r"Automatic merge failed; " r"fix conflicts and then commit the result.'"), e.stdout) else: assert not "Missing expected exception"