Exemple #1
0
    def test_shouldCheckIfAllSharedOptionValuesOfAllRulesOfASchedulerAreEqual(
            self, fix):
        schedName = "sched-with-shared-opts"
        sched = mockSched(schedName,
                          sharedOptions=[
                              optInfo("ConfDir"),
                              optInfo("DestFile"),
                              optInfo("Version")
                          ])

        def rule(**schedOpts):
            return mockRule(scheduler=sched, schedOpts=schedOpts)

        rules = [
            rule(Version="1", ConfDir="/home", DestFile="/etc/foo"),
            rule(Version="1", ConfDir="/etc", DestFile="/etc/foo"),
            rule(Version="1", ConfDir="/usr/share")
        ]

        validator = self.construct()

        iterToTest(validator.validate(ruleSet(*rules))).\
            shouldContainMatchingInAnyOrder(
                stringThat.shouldInclude("ConfDir", "/home", "/etc", "/usr/share"),
                stringThat.shouldInclude("DestFile", "‘/etc/foo’", "‘’"))
Exemple #2
0
def test_shouldReturnTheWrappedSchedsCheckErrors(fixture):
    iterToTest(
        fixture.check([buildScheduling(ExecOnSuccess="(")],
                      subCheckErrors=["foo", "bar"])).shouldContainMatching(
                          lambda error: "ExecOnSuccess" in error,
                          lambda error: error == "foo",
                          lambda error: error == "bar")
Exemple #3
0
 def assertIsWrongSyntax(setting):
     ruleName = "bad-conf"
     iterToTest(
         fixture.check([
             buildScheduling(ruleName, AllowedHours=setting)
         ])).shouldIncludeMatching(
             lambda error: strToTest(error).shouldInclude(
                 ruleName, "syntax", "AllowedHours", setting))
Exemple #4
0
    def test_shouldPassTheSpecifiedTag(self, fixture):
        logger = fixture.make(tag="beer")

        with fixture.testServer() as server:
            logger.write(b"\n")

        iterToTest(server.packets).shouldContainMatching(
            lambda packet: packet.tag == b"beer")
Exemple #5
0
def test_shouldAddLocOptInfosToAvailableOptionsBasedOnPorts():
  wrapped = fakeConfigurable("syncer", 
      ports=[port(), port(), port()], availableOptions=[])
  syncer = DefaultValueSynchronizer(wrapped)

  iterToTest(syncer.availableOptions).shouldContainMatching(
      lambda opt: opt.name == "Loc1" and opt.optionType == types.Location,
      lambda opt: opt.name == "Loc2", lambda opt: opt.name == "Loc3")
Exemple #6
0
    def test_shouldUseTheUtilLinuxLoggerProgramForLogging(self, fixture):
        logger = fixture.make(prefix=b"prefix")

        with fixture.testServer() as server:
            logger.write(b"foo\n")

        iterToTest(server.packets).shouldContainMatching(
            lambda packet: packet.message == b"prefix: foo")
Exemple #7
0
def test_shouldReturnNameAndBasicInfoOfRulesEvenWithoutBuildingThem(fixture):
  fixture.writeAnyRule("foo")
  fixture.writeAnyRule("bar")
  fixture.writeInstanceFile("@bar")

  iterToTest(fixture.read(mockedFileReader=mock.mock(),
    loadLazyRules=False)).shouldContainMatchingInAnyOrder(
      lambda rule: rule.name == "foo" and not rule.enabled,
      lambda rule: rule.name == "bar" and rule.enabled)
Exemple #8
0
 def test_shouldReportErrorIfALocDoesNotExistAsADirectory(self, fix):
     validator = self.construct()
     ruleName = "rulename"
     iterToTest(
         validator.validate([
             fix.validRule(),
             self.invalidRule(fix, ruleName)
         ])).shouldContainMatching(
             lambda error: "does not exist" in error and ruleName in error)
Exemple #9
0
def test_shouldCollectParseErrorsBeforeThrowingException(fixture):
    with pytest.raises(OptionParseException) as ex:
        fixture.parser.parseOptions(
            [optInfo("Opt1", types.Positive),
             optInfo("Opt2", types.Bool)], dict(Opt1="-2", Opt2="foo"))

    iterToTest(ex.value.errors).shouldContainMatchingInAnyOrder(
        lambda error: error.optionName == "Opt1" and "negative" in error.
        message, lambda error: error.optionName == "Opt2" and "truth" in error.
        expectedType)
Exemple #10
0
 def test_shouldNotFailForFunctionsThatHaveAReasonableDefault(
         self, fixture):
     syncer = self.loadSynchronizerWithCode("", fixture)
     assert syncer.onePortMustHaveFileProtocol == False
     _ = syncer.availableOptions
     iterToTest(syncer.ports).shouldContainMatching(
         lambda port: "file" in port.supportedProtocols and \
             not port.isWrittenTo,
         lambda port: "file" in port.supportedProtocols and port.isWrittenTo)
     assert syncer.versionsOf(mkSyncerOpts(), "/mnt/data/bar", 1) == []
     assert syncer.check(mkSyncerOpts()) == []
Exemple #11
0
    def test_shouldNotProcessListFilesOutputToEnhanceItsSpeedIfRequested(
            self, fixture):
        options = dict(ListFilesExactly=False)

        writeFileTree(fixture.loc1, ["folder", ["sub", "foo", "bar"]])
        version = fixture.getSingleVersion(additionalOptions=options)

        iterToTest(
            fixture.listPort1Files(
                "folder", version, recursively=True,
                additionalOpts=options)).shouldContainInAnyOrder(
                    "sub", "sub/foo", "sub/bar")
Exemple #12
0
    def test_shouldFindSyntaxErrorsInItsOptions(self, fixture):
        assert fixture.check(
            dict(AdditionalSyncOpts="--exclude '**/.*'")) == []

        iterToTest(
            fixture.check(
                dict(AdditionalSyncOpts="--exclude '",
                     RemoteShellCommand="("))).shouldContainMatchingInAnyOrder(
                         stringThat.shouldInclude("AdditionalSyncOpts",
                                                  "unexpected"),
                         stringThat.shouldInclude("RemoteShellCommand",
                                                  "unexpected"))
Exemple #13
0
    def test_shouldPrintTheActualMountPointIfTheAssertionTurnsOutFalse(
            self, fix):
        mountPoint = fix.tmpdir.mkdir("mount")

        with nonEmptyFSMountedAt(mountPoint):
            loc1 = mountPoint.mkdir("sub").mkdir("loc1")
            rule = mockRule(loc1=str(loc1), options=dict(MustBeMountPoint="1"))
            errors = self.construct().validate(ruleSet(rule))

        iterToTest(errors).shouldContainMatching(
            stringThat.shouldInclude("actual",
                                     str(mountPoint) + "’"))
  def test_shouldLogSystemExceptionsInLessDetail(self, fixture):
    class SysException(BaseException):
      pass

    def raiseException(logger):
      raise SysException()

    with pytest.raises(SysException):
      fixture.log.logExecution("foo", constantTimeClock(), raiseException)

    iterToTest(fixture.executionsOf("foo")).shouldContainMatching(
        lambda execution: strToTest(execution.output).\
            shouldInclude("exception").but.shouldNotInclude("traceback"))
Exemple #15
0
    def test_shouldUseTheSpecifiedFacilityAndSeverity(self, fixture):
        logger = fixture.make(facility="mail", severity="warning")

        with fixture.testServer() as server:
            logger.write(b"\n")
            logger.write(b"\n", severity="err")
            logger.write(b"\n", facility="user")

        iterToTest(server.packets).shouldContainMatching(
            lambda packet: packet.facility == "mail" and packet.severity ==
            "warning", lambda packet: packet.facility == "mail" and packet.
            severity == "err", lambda packet: packet.facility == "user" and
            packet.severity == "warning")
Exemple #16
0
    def test_shouldReturnEachSyncerCheckErrorWithAnAppropriatePrefix(
            self, fix):
        rule1 = mockRule("first",
                         syncerName="syncer1",
                         syncerCheckErrors=["Wrong option syntax"])
        rule2 = mockRule(
            "second",
            syncerName="syncer2",
            syncerCheckErrors=["Contradictory values", "Unreadable File"])

        iterToTest(self.construct().validate(ruleSet(rule1, rule2))).\
            shouldContainMatchingInAnyOrder(
                stringThat.shouldInclude("syntax", "first", "syncer1"),
                stringThat.shouldInclude("Contradictory", "second", "syncer2"),
                stringThat.shouldInclude("Unreadable", "second", "syncer2"))
Exemple #17
0
    def test_shouldTurnEachCheckErrorFromTheUsedSchedulersIntoAString(
            self, fix):
        sched1, sched2 = mockSched("first"), mockSched("second")
        rule1, rule2 = mockRule(scheduler=sched1), mockRule(scheduler=sched2)
        validator = self.construct()

        sched1.expectCalls(
            schedCallWithRules("check", rule1, ret=["foo", "bar"]))
        sched2.expectCalls(schedCallWithRules("check", rule2, ret=["quux"]))

        iterToTest(validator.validate(ruleSet(rule1, rule2))).\
            shouldContainMatchingInAnyOrder(
                stringThat.shouldInclude("first", "reported error", "foo"),
                stringThat.shouldInclude("first", "bar"),
                stringThat.shouldInclude("second", "quux"))
Exemple #18
0
    def test_shouldBeAbleToDryTestTheRsyncCommandThatWouldBeUsedToSync(
            self, fixture):
        assert "DryRun" in fixture.optionNames

        iterToTest(fixture.check(dict(DryRun=True, AdditionalSyncOpts="--bar"))).\
            shouldContainMatching(stringThat.shouldInclude("unknown option", "bar"))

        (fixture.loc1 / "file").write("")
        assert fixture.check({}) == []
        assert not os.path.isfile(str(fixture.loc2 / "file"))

        fixture.loc1.chmod(0o300)
        iterToTest(fixture.check(dict(DryRun=True))).shouldContainMatching(
            stringThat.shouldInclude("Permission denied"))
        assert fixture.check(dict(DryRun=False)) == []
Exemple #19
0
def test_shouldCheckSyntaxOfScriptsWithoutExecutingThem(fixture, tmpdir):
    flagFile = str(tmpdir / "flag")

    erroneousCode = "touch {0}\n(echo foo".format(flagFile)

    schedulings = [
        buildScheduling("touching", ExecOnFailure=erroneousCode),
        buildScheduling(ExecBefore="{")
    ]

    iterToTest(fixture.check(schedulings)).shouldContainMatching(
        lambda error: strToTest(error).shouldInclude(
            "unexpected", "ExecOnFailure", "syntax", "touching"),
        lambda error: "ExecBefore" in error)
    assert not os.path.isfile(flagFile)
Exemple #20
0
def test_shouldReturnALazyRuleForEachFileAndBuildWithTheFactoryWhenLoadIsCalled(
    fixture):
  fixture.writeAnyRule("rule-1")
  fixture.writeAnyRule("rule-2")

  fileReader = mock.mock()

  lazyRules = fixture.read(fileReader, loadLazyRules=False, namePrefix="a-")
  assert lazyRules[0].name.startswith("a-rule-")

  ruleOpts1, schedOpts1, syncerOpts1, ruleOpts2, schedOpts2, syncerOpts2 = \
      object(), object(), object(), object(), object(), object()

  fileReader.expectCallsInAnyOrder(
      readCall(paths=[fixture.rulePath("rule-1")], 
        ret=sectionsDict(ruleOpts1, schedOpts1, syncerOpts1)),
      readCall(paths=[fixture.rulePath("rule-2")],
        ret=sectionsDict(ruleOpts2, schedOpts2, syncerOpts2)))

  firstConstructedRule = object()
  secondConstructedRule = object()

  fixture.factory.expectCallsInAnyOrder(
      buildCall(name="a-rule-1", ruleOpts=ruleOpts1, schedOpts=schedOpts1,
        syncerOpts=syncerOpts1, ret=firstConstructedRule),
      buildCall(name="a-rule-2", ruleOpts=ruleOpts2, schedOpts=schedOpts2,
        syncerOpts=syncerOpts2, ret=secondConstructedRule))

  assert iterToTest(rule.load() for rule in lazyRules).\
      shouldContainInAnyOrder(firstConstructedRule, secondConstructedRule)
Exemple #21
0
def test_shouldParseUnixTimestampsWithAndWithoutMillisecondsAsVersions(
        fixture):
    path = "/etc/config"

    fixture.functions.expectCalls(
        mock.callMatching(
            "callFuzzy",
            lambda funcName, args, _: funcName == "versions-of" and args[
                0] == path and args[1] == "2",
            ret=["250", "0,999",
                 toTimestamp("2013-05-10T13:05:20") + ",025"]))

    iterToTest(fixture.syncer.versionsOf({}, path, 2)).shouldContainInAnyOrder(
        datetime(1970, 1, 1, 0, 4, 10, 0, timezone.utc),
        datetime(1970, 1, 1, 0, 0, 0, 999000, timezone.utc),
        datetime(2013, 5, 10, 13, 5, 20, 25000, timezone.utc))
Exemple #22
0
def test_shouldTreatFirstLineOfPortOutputAsWrittenToFlag(fixture):
    def protocolsCall(number, ret):
        return mock.callMatching("callFuzzy",
                                 lambda funcName, args, _: funcName ==
                                 "info-of-port" and args[0] == number,
                                 ret=ret)

    fixture.functions.expectCallsInAnyOrder(
        protocolsCall("1", ["1", "a", "b"]), protocolsCall("2", ["1", "c"]),
        protocolsCall("3", ["0", "d", "e", "f"]), protocolsCall("4", []))

    iterToTest(fixture.syncer.ports).shouldContainMatching(
        lambda port: port.supportedProtocols == ["a", "b"] and port.isWrittenTo,
        lambda port: port.supportedProtocols == ["c"] and port.isWrittenTo,
        lambda port: port.supportedProtocols == ["d", "e", "f"] and \
            not port.isWrittenTo)
Exemple #23
0
    def test_shouldFindSyntaxErrorsInItsOptions(self, fixture):
        assert fixture.check(
            dict(AdditionalSyncOpts="--one-file-system",
                 ExcludedDirs="/foo")) == []

        iterToTest(
            fixture.check(
                dict(AdditionalSyncOpts="'",
                     AdditionalOptsBothWays="'",
                     RemoteShellCommand="("))).shouldContainMatchingInAnyOrder(
                         stringThat.shouldInclude("unexpected",
                                                  "AdditionalOptsBothWays"),
                         stringThat.shouldInclude("unexpected",
                                                  "AdditionalSyncOpts"),
                         stringThat.shouldInclude("unexpected",
                                                  "RemoteShellCommand"))
  def test_shouldLogAndRethrowExceptions(self, fixture):
    class TestException(Exception):
      def __str__(self):
        return "we have a problem"

    def raiseException(logFile):
      raise TestException()

    with pytest.raises(TestException):
      fixture.log.logExecution("foo", constantTimeClock(), raiseException)
    
    iterToTest(fixture.executionsOf("foo")).shouldContainMatching(
        lambda execution:
          "internal" in execution.output and
          "exception" in execution.output and
          "we have a problem" in execution.output and
          not execution.succeeded)
Exemple #25
0
    def test_shouldRememberTheVersionTimestampInAFileAndElseFallBackOnTheMTime(
            self, fixture):
        someFile = fixture.loc1.join("file")
        someFile.write("")
        fixture.changeMTime(str(someFile), 23)

        fixture.sync()

        assert fixture.versionsOf("does-not-exist", 1) == []

        iterToTest(fixture.versionsOf(
            "file",
            1)).shouldContainMatching(lambda version: version.year > 1970)

        (fixture.loc2 / ".sibt-rsync-timestamp").remove()
        fixture.versionsOf("file", 1) == \
            [datetime(1970, 1, 1, 0, 0, 23, tzinfo=timezone.utc)]
Exemple #26
0
def test_shouldCallVisitorWithEachSchedAndItsRulesUntilNotNoneIsReturned(
        fixture):
    sched1, sched2 = mockScheds(2)
    rule1, rule2, rule3 = fixture.ruleWithSched(sched1), \
        fixture.ruleWithSched(sched1), \
        fixture.ruleWithSched(sched2)
    ruleSet = fixture.makeRuleSet(rule1, rule2, rule3)

    visited = []

    def visit(sched, rules):
        visited.append((sched, set(rules)))

    assert ruleSet.visitSchedulers(visit) is None
    iterToTest(visited).shouldContainInAnyOrder((sched1, {rule1, rule2}),
                                                (sched2, {rule3}))

    assert ruleSet.visitSchedulers(lambda *args: "foo") == "foo"
Exemple #27
0
    def test_shouldBeAbleToListDirsInLoc1AsTheyWereInThePastWithoutRecursion(
            self, fixture):
        version = self.setUpTestTreeSyncAndDeleteIt(fixture,
                                                    self.fileNameWithNewline,
                                                    dict())

        iterToTest(
            fixture.listPort1Files("[folder],", version,
                                   recursively=False)).shouldContainInAnyOrder(
                                       self.fileNameWithNewline, ".file2",
                                       "sub/")

        assert fixture.listPort1Files("[folder],/" +
          self.fileNameWithNewline, version, recursively=False) == \
              [self.fileNameWithNewline]

        assert fixture.listPort1Files(".", version, recursively=False) == \
            ["[folder],/"]
Exemple #28
0
def test_shouldSplitFuzzyOutputForTypeAndNameOfAvailableOptions(fixture):
    ret = ["Default", "b B"]

    fixture.functions.expectCalls(
        mock.callMatching("callFuzzy",
                          lambda funcName, *_: funcName == "available-options",
                          ret=ret))

    assert iterToTest(fixture.syncer.availableOptions).shouldContainMatching(
        lambda opt: opt.name == "Default" and opt.optionType == types.String,
        lambda opt: opt.name == "B" and opt.optionType == types.Bool)
Exemple #29
0
    def test_shouldUseTheIncrementsAsVersions(self, fixture):
        sameFile, topFile, folder, oldFile, newFile = writeFileTree(
            fixture.loc1, [
                ".", "samefile [1]", "file [2]",
                ["usr [3]", "oldfile [4]", "newfile [5]"]
            ])

        sameFile.write("same")
        newFile.remove()
        topFile.write("old")

        oldVersion, newVersion = self.getTwoVersions(
            fixture,
            doBetweenSyncs=lambda:
            (topFile.write("new"), newFile.write(""), oldFile.remove()))

        assert len(fixture.versionsOf("usr", 1)) == 2
        assert fixture.versionsOf("not-there", 1) == []
        assert len(fixture.versionsOf("usr/newfile", 1)) == 1

        iterToTest(fixture.listPort1Files(".",
                                          oldVersion)).shouldContainInAnyOrder(
                                              "samefile", "file", "usr/",
                                              "usr/oldfile")
        iterToTest(fixture.listPort1Files(".",
                                          newVersion)).shouldContainInAnyOrder(
                                              "samefile", "file", "usr/",
                                              "usr/newfile")

        fixture.restorePort1File("usr", oldVersion, None)
        assert os.listdir(str(folder)) == ["oldfile"]

        assert topFile.read() == "new"
        fixture.restorePort1File(".", oldVersion, None)
        assert topFile.read() == "old"

        fixture.restorePort1File(".", newVersion, None)
        assert topFile.read() == "new"
        assert os.listdir(str(folder)) == ["newfile"]
        assert set(os.listdir(str(
            fixture.loc1))) == {"usr", "samefile", "file"}
  def test_shouldCorrectlyReadExecutionsThatAreStillInProgress(self, fixture):
    startTime = anyUTCDateTime()
    executionsInThisProcess = []
    executionsInOtherProcess = []

    def execute(logger):
      logger.write(b"output\n")
      executionsInThisProcess.extend(fixture.executionsOf("quux"))
      executionsInOtherProcess.extend(fixture.inNewProcess(r"""
        return fixture.executionsOf("quux")"""))
      return True

    fixture.log.logExecution("quux", constantTimeClock(startTime), execute)

    iterToTest(executionsInOtherProcess).shouldContainMatching(
        lambda execution: 
          execution.startTime == startTime and
          execution.output == "output\n" and
          execution.finished is False)
    iterToTest(executionsInThisProcess).shouldContainMatching(
        lambda execution: execution.finished is False)