def test_shouldRoundTheIntervalsToDaysAndWarnAboutLostParts(self, fixture): assert optInfo("Interval", types.TimeDelta) in fixture.optionInfos logger = BufferingErrorLogger() fixture.init(logger=logger) schedulings = [ buildScheduling("one-day", Interval=timedelta(hours=22)), buildScheduling("two-days", Interval=timedelta(days=2, hours=6)), buildScheduling("three-weeks", Interval=timedelta(weeks=3)), buildScheduling("no-interval") ] def shouldHaveWarned(): logger.string.shouldInclude("one-day", "rounding", "two-days").andAlso.\ shouldNotInclude("three-weeks") logger.clear() assert fixture.check(schedulings, logger=logger) == [] shouldHaveWarned() def checkTab(tabPath): strToTest(local(tabPath).read()).shouldIncludeLinePatterns( "3 0 no-interval*", "1 0 one-day*", "2 0 two-days*", "21 0 three-weeks*") return True fixture.checkOption("-t", schedulings, checkTab) shouldHaveWarned()
def test_shouldReturnAsManyCheckErrorsAsItCanFind(self, fixture): fixture.init() schedulings = [ buildScheduling(AllowedHours="bar"), buildScheduling(AllowedHours="3") ] assert len(fixture.check(schedulings)) > 1
def test_shouldHaveAnOptionThatCausesItToWriteTheTabWithoutExecuting( self, fixture): assert "OutputTabFile" in fixture.optionNames fixture.init() tabFile = fixture.tmpdir / "tab" fixture.schedule([ buildScheduling("foo", OutputTabFile=localLocation(tabFile)), buildScheduling("bar", OutputTabFile=localLocation(tabFile)) ]) strToTest(tabFile.read()).shouldIncludeLinePatterns("*foo*", "*bar*")
def test_shouldPrintLineForEachScheduledRuleButNotScheduleThem(fixture): sub = mock.mock() sub.name = "sub-sched" output = mock.mock() output.expectCallsInAnyOrder( mock.callMatching( "println", lambda line: "first" in line and "sub-sched" in line), mock.callMatching("println", lambda line: "second" in line)) dry = DryScheduler(sub, output) dry.schedule([buildScheduling("first"), buildScheduling("second")]) output.checkExpectedCalls()
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)
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")
def schedule(): fixture.scheduleWithMockedSibt( r"""#!/usr/bin/env bash touch "{0}" """.format(sibtExecutedFlag), [ buildScheduling(lastTime=lastTime, Interval=timedelta(days=2)) ])
def assertIsWrongSyntax(setting): ruleName = "bad-conf" iterToTest( fixture.check([ buildScheduling(ruleName, AllowedHours=setting) ])).shouldIncludeMatching( lambda error: strToTest(error).shouldInclude( ruleName, "syntax", "AllowedHours", setting))
def test_shouldHaveAnInterfaceToAnacronsStartHoursRange(self, fixture): assert "AllowedHours" in fixture.optionNames fixture.init() def checkTab(tabPath): strToTest(local(tabPath).read()).shouldIncludeLinePatterns( "*START_HOURS_RANGE=6-20") return True schedulings = [buildScheduling(AllowedHours="6-20")] fixture.checkOption("-t", schedulings, checkTab)
def test_shouldCallSibtWithTheRightArgsForEachScheduling(self, fixture): flagFile = str(fixture.miscDir / "test") assert not os.path.isfile(flagFile) fixture.scheduleWithMockedSibt( r"""#!/usr/bin/env bash if [ $1 = --some-global-opt ] && [ "$2" = 'blah "'"'"'foo' ] && \ [ $3 = execute-rule ] && [ $4 = -- ] && [ "$5" = 'some*rule' ]; then touch {0} fi""".format(flagFile), [buildScheduling("some*rule")], sibtArgs=["--some-global-opt", "blah \"'foo"]) assert os.path.isfile(flagFile)
def execute(self, execs, ruleName=None): execEnv = execEnvironment(logger=self.logger, logSubProcessWith=self._logSubProcessWith) scheduler = self.makeSched(subExecute=self._subExecute) try: ret = scheduler.execute( execEnv, buildScheduling(ruleName=ruleName, **self._optionsFromExecs(execs))) finally: self.callsMock.checkExpectedCalls() self.callsMock.clearExpectedCalls() return ret
def test_shouldExecuteAllScheduledRulesAtOnce(self, fixture): names = ["foo", "bar", "baz", "quux", "foobar"] schedulings = [buildScheduling(name) for name in names] flagFiles = [fixture.miscDir / name for name in names] startSeconds = time.perf_counter() fixture.scheduleWithMockedSibt( r"""#!/usr/bin/env bash sleep 0.25 touch "{0}"/"$3" """.format(fixture.miscDir), schedulings) elapsedSeconds = time.perf_counter() - startSeconds assert elapsedSeconds > 0.25 assert elapsedSeconds < 0.5 for flagFile in flagFiles: assert os.path.isfile(str(flagFile))
def test_shouldPutTemporaryTabAndScriptsIntoTmpDirAndDeleteThemAfterwards( self, fixture): assert "TmpDir" in fixture.optionNames fixture.init() def checkTab(tab): assert len(fixture.tmpDir.listdir()) > 0 strToTest(local(tab).read()).shouldIncludeLinePatterns("*rule-id*") return True fixture.checkOption( "-t", [buildScheduling("rule-id", TmpDir=localLocation(fixture.tmpDir))], checkTab) assert len(fixture.tmpDir.listdir()) == 0
def test_shouldCheckIfAllowedHoursSettingHasTheRightSyntax(self, fixture): fixture.init() def assertIsWrongSyntax(setting): ruleName = "bad-conf" iterToTest( fixture.check([ buildScheduling(ruleName, AllowedHours=setting) ])).shouldIncludeMatching( lambda error: strToTest(error).shouldInclude( ruleName, "syntax", "AllowedHours", setting)) assertIsWrongSyntax("foo") assertIsWrongSyntax("5-") assertIsWrongSyntax("5-7 foo") assertIsWrongSyntax("7-5") assertIsWrongSyntax("0-25") assert fixture.check([buildScheduling(AllowedHours="0-19")]) == []
def nextExecutionLocalTime(self, schedulingOptions, lastLocalTime): ret = self.makeSched().nextExecutionTime( buildScheduling(lastTime=toUTC(lastLocalTime), **schedulingOptions)) assert ret.tzinfo == timezone.utc return ret.astimezone().replace(tzinfo=None)
def sysloggedScheduling(self, **options): return buildScheduling(Syslog=True, SyslogOptions=loggerOptions(TestPort), **options)