def setUp(self): super(CleanCronJobsFlowTest, self).setUp() with test_lib.FakeTime(40): cron_args = rdf_cronjobs.CreateCronJobArgs( frequency=RetentionTestSystemCronJob.frequency, flow_name=RetentionTestSystemCronJob.__name__, lifetime=RetentionTestSystemCronJob.lifetime) self.cron_jobs_names = [] self.cron_jobs_names.append(cronjobs.GetCronManager().CreateJob( cron_args=cron_args, job_id="Foo", token=self.token, enabled=True)) self.cron_jobs_names.append(cronjobs.GetCronManager().CreateJob( cron_args=cron_args, job_id="Bar", token=self.token, enabled=True)) manager = cronjobs.GetCronManager() for i in range(self.NUM_CRON_RUNS): with test_lib.FakeTime(40 + 60 * i): manager.RunOnce(token=self.token) if data_store.RelationalDBReadEnabled(category="cronjobs"): manager._GetThreadPool().Join()
def testSystemCronFlowsMayBeDisabledViaConfig(self): with test_lib.ConfigOverrider({ "Cron.disabled_system_jobs": ["DummySystemCronJob"] }): aff4_cronjobs.ScheduleSystemCronFlows(token=self.token) jobs = aff4_cronjobs.GetCronManager().ListJobs(token=self.token) self.assertIn("DummySystemCronJob", jobs) # This cron job should be disabled, because it's listed in # Cron.disabled_system_jobs config variable. job = aff4_cronjobs.GetCronManager().ReadJob( "DummySystemCronJob", token=self.token) self.assertTrue(job.Get(job.Schema.DISABLED)) # Now remove the cron job from the list and check that it gets disabled # after next ScheduleSystemCronFlows() call. with test_lib.ConfigOverrider({"Cron.disabled_system_jobs": []}): aff4_cronjobs.ScheduleSystemCronFlows(token=self.token) # System cron job should be enabled. job = aff4_cronjobs.GetCronManager().ReadJob( "DummySystemCronJob", token=self.token) self.assertFalse(job.Get(job.Schema.DISABLED))
def testSystemCronJobSetsStartTime(self): with test_lib.FakeTime(100): now = rdfvalue.RDFDatetime.Now() aff4_cronjobs.ScheduleSystemCronFlows( names=[ DummySystemCronJob.__name__, DummySystemCronJobStartNow.__name__ ], token=self.token) random_time = "DummySystemCronJob" no_random_time = "DummySystemCronJobStartNow" random_time_job = aff4_cronjobs.GetCronManager().ReadJob( random_time, token=self.token) no_random_time_job = aff4_cronjobs.GetCronManager().ReadJob( no_random_time, token=self.token) start_time_now = no_random_time_job.Get( no_random_time_job.Schema.CRON_ARGS).start_time self.assertEqual(start_time_now, now) random_start_time = random_time_job.Get( random_time_job.Schema.CRON_ARGS).start_time self.assertTrue( now < random_start_time < (now + DummySystemCronJob.frequency))
def testDeletesRunsOlderThanGivenAge(self): all_children = [] for cron_name in self.cron_jobs_names: all_children.extend( cronjobs.GetCronManager().ReadJobRuns(cron_name)) with test_lib.ConfigOverrider( {"DataRetention.cron_jobs_flows_ttl": rdfvalue.Duration("150s")}): # Only two iterations are supposed to survive, as they were running # every minute. with test_lib.FakeTime(40 + 60 * self.NUM_CRON_RUNS): self._RunCleanup() latest_timestamp = rdfvalue.RDFDatetime.Now() for cron_name in self.cron_jobs_names: children = cronjobs.GetCronManager().ReadJobRuns(cron_name) self.assertEqual(len(children), 2) for child in children: self.assertLess(child.started_at, latest_timestamp) self.assertGreater( child.started_at, latest_timestamp - rdfvalue.Duration("150s")) self.assertIn("Deleted 16", self.cleaner_job.run_state.log_message)
def Handle(self, args, token=None): job_id = str(args.cron_job_id) if data_store.RelationalDBEnabled(): aff4_cronjobs.GetCronManager().RequestForcedRun(job_id) else: aff4_cronjobs.GetCronManager().RunOnce( names=[job_id], token=token, force=True)
def testForceRunCronJob(self): cronjobs.GetCronManager().EnableJob(job_id=u"OSBreakDown") with test_lib.FakeTime( # 2274264646 corresponds to Sat, 25 Jan 2042 12:10:46 GMT. rdfvalue.RDFDatetime.FromSecondsSinceEpoch(2274264646), increment=1e-6): self.Open("/") self.Click("css=a[grrtarget=crons]") self.Click("css=td:contains('OSBreakDown')") # Click on Force Run button and check that dialog appears. self.Click("css=button[name=ForceRunCronJob]:not([disabled])") self.WaitUntil(self.IsTextPresent, "Are you sure you want to FORCE-RUN this cron job?") # Click on "Proceed" and wait for authorization dialog to appear. self.Click("css=button[name=Proceed]") self.WaitUntil(self.IsTextPresent, "Create a new approval") self.Click("css=grr-request-approval-dialog button[name=Cancel]") # Wait for dialog to disappear. self.WaitUntilNot(self.IsVisible, "css=.modal-open") self.RequestAndGrantCronJobApproval(u"OSBreakDown") # Click on Force Run button and check that dialog appears. self.Click("css=button[name=ForceRunCronJob]:not([disabled])") self.WaitUntil(self.IsTextPresent, "Are you sure you want to FORCE-RUN this cron job?") # Click on "Proceed" and wait for success label to appear. # Also check that "Proceed" button gets disabled. self.Click("css=button[name=Proceed]") self.WaitUntil(self.IsTextPresent, "Cron job flow was FORCE-STARTED successfully!") self.assertFalse(self.IsElementPresent("css=button[name=Proceed]")) # Click on "Close" and check that dialog disappears. self.Click("css=button[name=Close]") self.WaitUntilNot(self.IsVisible, "css=.modal-open") # Relational cron jobs will only be run the next time a worker checks in. if data_store.RelationalDBReadEnabled(): manager = cronjobs.GetCronManager() manager.RunOnce(token=self.token) manager._GetThreadPool().Join() # TODO(amoser): The lower pane does not refresh automatically so we need # to workaround. Remove when we have implemented this auto refresh. self.Open("/") self.Click("css=a[grrtarget=crons]") self.Click("css=td:contains('OSBreakDown')") # View should be refreshed automatically. The last run date should appear. self.WaitUntil( self.IsElementPresent, "css=grr-cron-jobs-list " "tr:contains('OSBreakDown') td:contains('2042')")
def Handle(self, args, token=None): cron_id = str(args.cron_job_id) if args.enabled: aff4_cronjobs.GetCronManager().EnableJob(cron_id, token=token) else: aff4_cronjobs.GetCronManager().DisableJob(cron_id, token=token) cron_job_obj = aff4_cronjobs.GetCronManager().ReadJob(cron_id, token=token) return ApiCronJob().InitFromObject(cron_job_obj)
def testDeletesCronFromCollection(self): jobs = list(cronjobs.GetCronManager().ListJobs(token=self.token)) self.assertEqual(len(jobs), 1) self.assertEqual(jobs[0], self.cron_job_id) args = cron_plugin.ApiDeleteCronJobArgs(cron_job_id=self.cron_job_id) self.handler.Handle(args, token=self.token) jobs = list(cronjobs.GetCronManager().ListJobs(token=self.token)) self.assertEqual(len(jobs), 0)
def testSystemCronFlowsGetScheduledAutomatically(self): aff4_cronjobs.ScheduleSystemCronFlows( names=[DummySystemCronJob.__name__], token=self.token) jobs = aff4_cronjobs.GetCronManager().ListJobs(token=self.token) self.assertIn("DummySystemCronJob", jobs) # System cron job should be enabled by default. job = aff4_cronjobs.GetCronManager().ReadJob("DummySystemCronJob", token=self.token) self.assertFalse(job.Get(job.Schema.DISABLED))
def testSystemCronFlowsWithDisabledAttributeDoNotGetScheduled(self): aff4_cronjobs.ScheduleSystemCronFlows( names=[DummyDisabledSystemCronJob.__name__], token=self.token) jobs = aff4_cronjobs.GetCronManager().ListJobs(token=self.token) self.assertIn("DummyDisabledSystemCronJob", jobs) # System cron job should be enabled by default. job = aff4_cronjobs.GetCronManager().ReadJob( "DummyDisabledSystemCronJob", token=self.token) self.assertTrue(job.Get(job.Schema.DISABLED))
def setUp(self): super(ApiListCronJobRunsHandlerRegressionTest, self).setUp() with test_lib.FakeTime(44): cron_args = rdf_cronjobs.CreateCronJobFlowArgs(periodicity="7d", lifetime="1d") cron_args.flow_runner_args.flow_name = self.flow_name cronjobs.GetCronManager().CreateJob(cron_args, job_id=self.flow_name, token=self.token) cronjobs.GetCronManager().RunOnce(token=self.token)
def Handle(self, args, token=None): cron_id = str(args.cron_job_id) if args.state == "ENABLED": aff4_cronjobs.GetCronManager().EnableJob(cron_id, token=token) elif args.state == "DISABLED": aff4_cronjobs.GetCronManager().DisableJob(cron_id, token=token) else: raise ValueError("Invalid cron job state: %s" % str(args.state)) cron_job_obj = aff4_cronjobs.GetCronManager().ReadJob(cron_id, token=token) return ApiCronJob().InitFromObject(cron_job_obj)
def testReschedulingJobWithFixedNameDoesNotCreateNewObjectVersion(self): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobArgs(allow_overruns=True, frequency="1d", flow_name="FakeCronJob") # Schedule cron job with a fixed name. Check that we have 1 version # of "TYPE" attribute. cron_manager.CreateJob(cron_args=cron_args, token=self.token, job_id="TheJob") cron_job = cron_manager.ReadJob("TheJob", token=self.token) attr_values = list(cron_job.GetValuesForAttribute( cron_job.Schema.TYPE)) self.assertTrue(len(attr_values) == 1) # Reschedule the job. Check that we still have only one "TYPE" version. cron_manager.CreateJob(cron_args=cron_args, token=self.token, job_id="TheJob") cron_job = cron_manager.ReadJob("TheJob", token=self.token) attr_values = list(cron_job.GetValuesForAttribute( cron_job.Schema.TYPE)) self.assertTrue(len(attr_values) == 1)
def testLatencyStatsAreCorrectlyRecorded(self): with test_lib.FakeTime(0): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobArgs(flow_name="FakeCronJob", frequency="1w") cron_job_id = cron_manager.CreateJob(cron_args=cron_args, token=self.token) cron_manager.RunOnce(token=self.token) prev_metric_value = stats.STATS.GetMetricValue("cron_job_latency", fields=[cron_job_id]) # Fast forward one minute with test_lib.FakeTime(60): cron_manager.RunOnce(token=self.token) cron_job = cron_manager.ReadJob(cron_job_id, token=self.token) cron_flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN) flow_test_lib.TestFlowHelper(cron_flow_urn, check_flow_errors=False, token=self.token) # This RunOnce call should determine that the flow has finished cron_manager.RunOnce(token=self.token) # Check that stats got updated current_metric_value = stats.STATS.GetMetricValue("cron_job_latency", fields=[cron_job_id]) self.assertEqual(current_metric_value.count - prev_metric_value.count, 1) self.assertEqual(current_metric_value.sum - prev_metric_value.sum, 60)
def testCronJobRunAllowsOverrunsWhenAllowOverrunsIsTrue(self): with test_lib.FakeTime(0): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobArgs(allow_overruns=True, frequency="1h", flow_name="FakeCronJob") job_id = cron_manager.CreateJob(cron_args=cron_args, token=self.token) cron_manager.RunOnce(token=self.token) cron_job_runs = cron_manager.ReadJobRuns(job_id, token=self.token) self.assertEqual(len(cron_job_runs), 1) # Let an hour pass. Frequency is 1h (i.e. cron job iterations are # supposed to be started every hour), so the new flow should be started # by RunOnce(). Previous iteration flow hasn't finished yet, but # allow_overruns is True, so it's ok to start new iteration. time.time = lambda: 60 * 60 + 1 cron_manager.RunOnce(token=self.token) cron_job_runs = cron_manager.ReadJobRuns(job_id, token=self.token) self.assertEqual(len(cron_job_runs), 2)
def testShowsCronJobDetailsOnClick(self): self.Open("/") self.Click("css=a[grrtarget=crons]") self.Click("css=td:contains('OSBreakDown')") # Tabs should appear in the bottom pane self.WaitUntil(self.IsElementPresent, "css=#main_bottomPane #Details") self.WaitUntil(self.IsElementPresent, "css=#main_bottomPane #Runs") self.WaitUntil(self.IsTextPresent, "Allow Overruns") self.WaitUntil(self.IsTextPresent, "Cron Arguments") # Click on "Runs" tab self.Click("css=#main_bottomPane #Runs") # Click on the first flow and wait for flow details panel to appear. runs = cronjobs.GetCronManager().ReadJobRuns( utils.GetName(cron_system.OSBreakDown)) try: run_id = runs[0].run_id except AttributeError: run_id = runs[0].urn.Basename() self.assertEqual(len(runs), 1) self.WaitUntil(self.IsElementPresent, "css=td:contains('%s')" % run_id)
def Run(self): with test_lib.FakeTime(42): self.CreateUser(u"approver") cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobArgs(frequency="1d", allow_overruns=False) cron_id = cron_manager.CreateJob(cron_args=cron_args, token=self.token) def ReplaceCronAndApprovalIds(): approvals = self.ListCronJobApprovals() return { approvals[0].id: "approval:112233", cron_id: "CronJob_123456" } with test_lib.FakeTime(126): self.Check("CreateCronJobApproval", args=user_plugin.ApiCreateCronJobApprovalArgs( cron_job_id=cron_id, approval=user_plugin.ApiCronJobApproval( reason="really important reason!", notified_users=["approver1", "approver2"], email_cc_addresses=["*****@*****.**"])), replace=ReplaceCronAndApprovalIds)
def testCronJobRunPreventsOverrunsWhenAllowOverrunsIsFalse(self): with test_lib.FakeTime(0): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobArgs(allow_overruns=False, frequency="1h", flow_name="FakeCronJob") job_id = cron_manager.CreateJob(cron_args=cron_args, token=self.token) cron_manager.RunOnce(token=self.token) cron_job_runs = cron_manager.ReadJobRuns(job_id, token=self.token) self.assertLen(cron_job_runs, 1) # Let an hour pass. Frequency is 1h (i.e. cron job iterations are # supposed to be started every hour), so the new flow should be started # by RunOnce(). However, as allow_overruns is False, and previous # iteration flow hasn't finished yet, no flow will be started. time.time = lambda: 60 * 60 + 1 cron_manager.RunOnce(token=self.token) cron_job_runs = cron_manager.ReadJobRuns(job_id, token=self.token) self.assertLen(cron_job_runs, 1)
def setUp(self): super(TestCronView, self).setUp() for flow_name in [ cron_system.GRRVersionBreakDown.__name__, cron_system.OSBreakDown.__name__, cron_system.LastAccessStats.__name__ ]: cron_args = rdf_cronjobs.CreateCronJobArgs( frequency="7d", lifetime="1d", flow_name=flow_name) cronjobs.GetCronManager().CreateJob( cron_args, job_id=flow_name, token=self.token) manager = cronjobs.GetCronManager() manager.RunOnce(token=self.token) if data_store.RelationalDBReadEnabled(): manager._GetThreadPool().Join()
def _GetRunId(cron_job_name, token=None): runs = aff4_cronjobs.GetCronManager().ReadJobRuns(cron_job_name, token=token) try: return runs[0].run_id except AttributeError: return runs[0].urn.Basename()
def testLatencyStatsAreCorrectlyRecorded(self): with test_lib.FakeTime(0): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "FakeCronJobRel" cron_args.periodicity = "1w" cron_job_id = cron_manager.CreateJob(cron_args=cron_args) cron_manager.RunOnce(token=self.token) prev_metric_value = stats.STATS.GetMetricValue("cron_job_latency", fields=[cron_job_id]) # Fast forward one minute with test_lib.FakeTime(60): cron_manager.RunOnce(token=self.token) run_urn = cron_manager.ReadJobRuns(cron_job_id)[-1].urn flow_test_lib.TestFlowHelper(run_urn, check_flow_errors=False, token=self.token) # This RunOnce call should determine that the flow has finished cron_manager.RunOnce(token=self.token) # Check that stats got updated current_metric_value = stats.STATS.GetMetricValue("cron_job_latency", fields=[cron_job_id]) self.assertEqual(current_metric_value.count - prev_metric_value.count, 1) self.assertEqual(current_metric_value.sum - prev_metric_value.sum, 60)
def Run(self): with test_lib.FakeTime(42): self.CreateAdminUser(u"requestor") cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobArgs(frequency="1d", allow_overruns=False) cron_id = cron_manager.CreateJob(cron_args=cron_args, token=self.token) with test_lib.FakeTime(44): approval_id = self.RequestCronJobApproval( cron_id, approver=self.token.username, requestor=u"requestor", reason="foo") with test_lib.FakeTime(126): self.Check("GrantCronJobApproval", args=user_plugin.ApiGrantCronJobApprovalArgs( cron_job_id=cron_id, approval_id=approval_id, username=u"requestor"), replace={ cron_id: "CronJob_123456", approval_id: "approval:111111" })
def testLastRunStatusGetsUpdatedOnEveryRun(self): job_id = "OccasionallyFailingFakeCronJob" aff4_cronjobs.ScheduleSystemCronFlows(names=[job_id], token=self.token) cron_manager = aff4_cronjobs.GetCronManager() for fake_time in [0, 60]: with test_lib.FakeTime(fake_time): # This call should start a new cron job flow cron_manager.RunOnce(token=self.token) cron_job = cron_manager.ReadJob(job_id, token=self.token) cron_flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN) print "&****" flow_test_lib.TestFlowHelper(cron_flow_urn, check_flow_errors=False, token=self.token) # This RunOnce call should determine that the flow has finished cron_manager.RunOnce(token=self.token) cron_job = cron_manager.ReadJob(job_id, token=self.token) statuses = list( cron_job.GetValuesForAttribute(cron_job.Schema.LAST_RUN_STATUS)) statuses = sorted(statuses, key=lambda x: x.age) self.assertEqual(len(statuses), 2) self.assertEqual(statuses[0].age, rdfvalue.RDFDatetime.FromSecondsSinceEpoch(0)) self.assertEqual(statuses[1].age, rdfvalue.RDFDatetime.FromSecondsSinceEpoch(60)) self.assertEqual(statuses[0].status, rdf_cronjobs.CronJobRunStatus.Status.OK) self.assertEqual(statuses[1].status, rdf_cronjobs.CronJobRunStatus.Status.ERROR)
def setUp(self): super(TestCronView, self).setUp() for flow_name in [ cron_system.GRRVersionBreakDown.__name__, cron_system.OSBreakDown.__name__, cron_system.LastAccessStats.__name__ ]: cron_args = rdf_cronjobs.CreateCronJobFlowArgs(periodicity="7d", lifetime="1d") cron_args.flow_runner_args.flow_name = flow_name cronjobs.GetCronManager().CreateJob(cron_args, job_id=flow_name, token=self.token) cronjobs.GetCronManager().RunOnce(token=self.token)
def testLastRunStatusGetsUpdated(self): cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "OccasionallyFailingFakeCronJobRel" cron_args.periodicity = "30s" job_id = cron_manager.CreateJob(cron_args=cron_args) statuses = [] for fake_time in [0, 60]: with test_lib.FakeTime(fake_time): # This call should start a new cron job flow cron_manager.RunOnce(token=self.token) run_urn = cron_manager.ReadJobRuns(job_id)[-1].urn flow_test_lib.TestFlowHelper(run_urn, check_flow_errors=False, token=self.token) # This RunOnce call should determine that the flow has finished cron_manager.RunOnce(token=self.token) cron_job = cron_manager.ReadJob(job_id, token=self.token) statuses.append(cron_job.last_run_status) statuses = sorted(statuses, key=lambda x: x.age) self.assertEqual(len(statuses), 2) self.assertEqual(statuses[0], rdf_cronjobs.CronJobRunStatus.Status.OK) self.assertEqual(statuses[1], rdf_cronjobs.CronJobRunStatus.Status.ERROR)
def Handle(self, source_args, token=None): # Make sure we don't modify source arguments. args = source_args.Copy() # Clear all fields marked with HIDDEN. args.flow_args.ClearFieldsWithLabel( rdf_structs.SemanticDescriptor.Labels.HIDDEN) # Clear all fields marked with HIDDEN, except for output_plugins - they are # marked HIDDEN, because we have a separate UI for them, not because they # shouldn't be shown to the user at all. # # TODO(user): Refactor the code to remove the HIDDEN label from # FlowRunnerArgs.output_plugins. args.hunt_runner_args.ClearFieldsWithLabel( rdf_structs.SemanticDescriptor.Labels.HIDDEN, exceptions="output_plugins") cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobArgs.FromApiCreateCronJobArgs(args) cron_job_id = cron_manager.CreateJob( cron_args=cron_args, enabled=False, token=token) cron_obj = cron_manager.ReadJob(cron_job_id) return ApiCronJob().InitFromObject(cron_obj)
def testCronJobPreservesFlowNameAndArguments(self): """Testing initialization of a ConfigManager.""" pathspec = rdf_paths.PathSpec(path="/foo", pathtype=rdf_paths.PathSpec.PathType.TSK) cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobArgs( frequency="1d", allow_overruns=False, flow_name=transfer.GetFile.__name__) cron_args.flow_args.pathspec = pathspec job_id = cron_manager.CreateJob(cron_args=cron_args, token=self.token) # Check that CronJob definition is saved properly jobs = cron_manager.ListJobs(token=self.token) self.assertEqual(len(jobs), 1) self.assertEqual(jobs[0], job_id) cron_job = cron_manager.ReadJob(job_id, token=self.token) cron_args = cron_job.Get(cron_job.Schema.CRON_ARGS) # CreateJob creates a cronjob that runs the CreateAndRunGenericHuntFlow # which in turn starts a hunt with the flow that we passed in. self.assertEqual(cron_args.flow_runner_args.flow_name, standard.CreateAndRunGenericHuntFlow.__name__) self.assertEqual( cron_args.flow_args.hunt_args.flow_runner_args.flow_name, transfer.GetFile.__name__) self.assertEqual(cron_args.flow_args.hunt_args.flow_args.pathspec, pathspec) self.assertEqual(cron_args.periodicity, rdfvalue.Duration("1d")) self.assertEqual(cron_args.allow_overruns, False)
def testCronJobPreservesFlowNameAndArguments(self): """Testing initialization of a ConfigManager.""" pathspec = rdf_paths.PathSpec(path="/foo", pathtype=rdf_paths.PathSpec.PathType.TSK) cron_manager = aff4_cronjobs.GetCronManager() cron_args = rdf_cronjobs.CreateCronJobFlowArgs(periodicity="1d", allow_overruns=False) cron_args.flow_runner_args.flow_name = transfer.GetFile.__name__ cron_args.flow_args.pathspec = pathspec job_id = cron_manager.CreateJob(cron_args=cron_args) # Check that CronJob definition is saved properly jobs = cron_manager.ListJobs(token=self.token) self.assertEqual(len(jobs), 1) self.assertEqual(jobs[0], job_id) cron_job = cron_manager.ReadJob(job_id, token=self.token) self.assertEqual(cron_job.cron_args.flow_runner_args.flow_name, transfer.GetFile.__name__) self.assertEqual(cron_job.cron_args.flow_args.pathspec, pathspec) self.assertEqual(cron_job.cron_args.periodicity, rdfvalue.Duration("1d")) self.assertEqual(cron_job.cron_args.allow_overruns, False)
def testDoesNothingIfAgeLimitNotSetInConfig(self): with test_lib.FakeTime(40 + 60 * self.NUM_CRON_RUNS): self._RunCleanup() for name in self.cron_jobs_names: runs = cronjobs.GetCronManager().ReadJobRuns(name, token=self.token) self.assertLen(runs, self.NUM_CRON_RUNS)
def testEmailCronJobApprovalRequestLinkLeadsToACorrectPage(self): cronjobs.ScheduleSystemCronFlows( names=[cron_system.OSBreakDown.__name__], token=self.token) cronjobs.GetCronManager().DisableJob(job_id="OSBreakDown") self.RequestCronJobApproval("OSBreakDown", reason=self.APPROVAL_REASON, approver=self.GRANTOR_USERNAME, requestor=self.token.username) self.assertEqual(len(self.messages_sent), 1) message = self.messages_sent[0] self.assertIn(self.APPROVAL_REASON, message) self.assertIn(self.token.username, message) self.assertIn("OSBreakDown", message) # Extract link from the message text and open it. m = re.search(r"href='(.+?)'", message, re.MULTILINE) link = urlparse.urlparse(m.group(1)) self.Open(link.path + "?" + link.query + "#" + link.fragment) # Check that requestor's username and reason are correctly displayed. self.WaitUntil(self.IsTextPresent, self.token.username) self.WaitUntil(self.IsTextPresent, self.APPROVAL_REASON) # Check that host information is displayed. self.WaitUntil(self.IsTextPresent, cron_system.OSBreakDown.__name__) self.WaitUntil(self.IsTextPresent, "Periodicity")