def testCronJobRespectsStartTime(self): with test_lib.FakeTime(0): cron_manager = cronjobs.CronManager() start_time1 = rdfvalue.RDFDatetime(100 * 1000 * 1000) cron_args1 = cronjobs.CreateCronJobFlowArgs(start_time=start_time1) cron_args1.flow_runner_args.flow_name = "FakeCronJob" cron_args2 = cronjobs.CreateCronJobFlowArgs() cron_args2.flow_runner_args.flow_name = "FakeCronJob" cron_job_urn1 = cron_manager.ScheduleFlow(cron_args1, token=self.token) cron_job_urn2 = cron_manager.ScheduleFlow(cron_args2, token=self.token) cron_manager.RunOnce(token=self.token) cron_job1 = aff4.FACTORY.Open( cron_job_urn1, aff4_type=cronjobs.CronJob, token=self.token) cron_job2 = aff4.FACTORY.Open( cron_job_urn2, aff4_type=cronjobs.CronJob, token=self.token) self.assertEqual( cron_job1.Get(cron_job1.Schema.CRON_ARGS).start_time, start_time1) # Flow without a start time should now be running self.assertFalse(cron_job1.IsRunning()) self.assertTrue(cron_job2.IsRunning()) # Move the clock past the start time with test_lib.FakeTime(500): cron_manager.RunOnce(token=self.token) cron_job1 = aff4.FACTORY.Open( cron_job_urn1, aff4_type=cronjobs.CronJob, token=self.token) cron_job2 = aff4.FACTORY.Open( cron_job_urn2, aff4_type=cronjobs.CronJob, token=self.token) # Start time should be the same self.assertEqual( cron_job1.Get(cron_job1.Schema.CRON_ARGS).start_time, start_time1) # Now both should be running self.assertTrue(cron_job1.IsRunning()) self.assertTrue(cron_job2.IsRunning()) # Check setting a bad flow urn is handled and removed with aff4.FACTORY.OpenWithLock( cron_job_urn2, aff4_type=cronjobs.CronJob, token=self.token) as cron_job2: cron_job2.Set(cron_job2.Schema.CURRENT_FLOW_URN("aff4:/does/not/exist")) self.assertFalse(cron_job2.IsRunning()) cron_job2 = aff4.FACTORY.Open( cron_job_urn2, aff4_type=cronjobs.CronJob, token=self.token) self.assertFalse(cron_job2.Get(cron_job2.Schema.CURRENT_FLOW_URN))
def Run(self): with test_lib.FakeTime(42): self.CreateUser("approver") cron_manager = aff4_cronjobs.CronManager() cron_args = aff4_cronjobs.CreateCronJobFlowArgs(periodicity="1d", allow_overruns=False) cron_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token) cron_id = cron_urn.Basename() def ReplaceCronAndApprovalIds(): approvals = list( aff4.FACTORY.ListChildren( aff4.ROOT_URN.Add("ACL").Add("cron").Add(cron_id).Add( self.token.username))) return { approvals[0].Basename(): "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 Run(self): with test_lib.FakeTime(42): self.CreateAdminUser("requestor") cron_manager = aff4_cronjobs.CronManager() cron_args = aff4_cronjobs.CreateCronJobFlowArgs( periodicity="1d", allow_overruns=False) cron_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token) with test_lib.FakeTime(44): requestor_token = access_control.ACLToken(username="******") approval_urn = security.CronJobApprovalRequestor( reason="foo", subject_urn=cron_urn, approver=self.token.username, token=requestor_token).Request() approval_id = approval_urn.Basename() with test_lib.FakeTime(126): self.Check("GrantCronJobApproval", args=user_plugin.ApiGrantCronJobApprovalArgs( cron_job_id=cron_urn.Basename(), approval_id=approval_id, username="******"), replace={ cron_urn.Basename(): "CronJob_123456", approval_id: "approval:111111" })
def testCronJobRunDoesNothingIfDueTimeHasNotComeYet(self): with test_lib.FakeTime(0): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs( allow_overruns=False, periodicity="1h") cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_job_urn = cron_manager.ScheduleFlow( cron_args=cron_args, token=self.token) cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open( cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) cron_job_flows = list(cron_job.ListChildren()) self.assertEqual(len(cron_job_flows), 1) # Let 59 minutes pass. Frequency is 1 hour, so new flow is not # supposed to start. time.time = lambda: 59 * 60 cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open( cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) cron_job_flows = list(cron_job.ListChildren()) self.assertEqual(len(cron_job_flows), 1)
def testReschedulingJobWithFixedNameDoesNotCreateNewObjectVersion(self): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs(allow_overruns=True, periodicity="1d") cron_args.flow_runner_args.flow_name = "FakeCronJob" # Schedule cron job with a fixed name. Check that we have 1 version # of "TYPE" attribute. cron_job_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token, job_name="TheJob") cron_job = aff4.FACTORY.Open(cron_job_urn, age=aff4.ALL_TIMES, 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_job_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token, job_name="TheJob") cron_job = aff4.FACTORY.Open(cron_job_urn, age=aff4.ALL_TIMES, token=self.token) attr_values = list(cron_job.GetValuesForAttribute( cron_job.Schema.TYPE)) self.assertTrue(len(attr_values) == 1)
def testCronJobRunAllowsOverrunsWhenAllowOverrunsIsTrue(self): with test_lib.FakeTime(0): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs( allow_overruns=True, periodicity="1h") cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_job_urn = cron_manager.ScheduleFlow( cron_args=cron_args, token=self.token) cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open( cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) cron_job_flows = list(cron_job.ListChildren()) self.assertEqual(len(cron_job_flows), 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 = aff4.FACTORY.Open( cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) cron_job_flows = list(cron_job.ListChildren()) self.assertEqual(len(cron_job_flows), 2)
def testCronJobRunDoesNothingIfCurrentFlowIsRunning(self): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs(allow_overruns=False, periodicity="1d") cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_job_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token) cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) cron_job_flows = list(cron_job.ListChildren()) self.assertEqual(len(cron_job_flows), 1) cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) cron_job_flows = list(cron_job.ListChildren()) self.assertEqual(len(cron_job_flows), 1)
def testDisabledCronJobDoesNotScheduleFlows(self): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_job_urn1 = cron_manager.ScheduleFlow(cron_args, token=self.token) cron_job_urn2 = cron_manager.ScheduleFlow(cron_args, token=self.token) cron_job1 = aff4.FACTORY.Open(cron_job_urn1, aff4_type=cronjobs.CronJob, mode="rw", token=self.token) cron_job1.Set(cron_job1.Schema.DISABLED(1)) cron_job1.Close() cron_manager.RunOnce(token=self.token) cron_job1 = aff4.FACTORY.Open(cron_job_urn1, aff4_type=cronjobs.CronJob, token=self.token) cron_job2 = aff4.FACTORY.Open(cron_job_urn2, aff4_type=cronjobs.CronJob, token=self.token) # Disabled flow shouldn't be running, while not-disabled flow should run # as usual. self.assertFalse(cron_job1.IsRunning()) self.assertTrue(cron_job2.IsRunning())
def testFailedFlowUpdatesStats(self): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs( allow_overruns=False, periodicity="1d") cron_args.flow_runner_args.flow_name = "FailingFakeCronJob" cron_job_urn = cron_manager.ScheduleFlow( cron_args=cron_args, token=self.token) prev_metric_value = stats.STATS.GetMetricValue( "cron_job_failure", fields=[cron_job_urn.Basename()]) cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open(cron_job_urn, token=self.token) cron_flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN) for _ in flow_test_lib.TestFlowHelper( cron_flow_urn, check_flow_errors=False, token=self.token): pass # This RunOnce call should determine that the flow has failed cron_manager.RunOnce(token=self.token) # Check that stats got updated current_metric_value = stats.STATS.GetMetricValue( "cron_job_failure", fields=[cron_job_urn.Basename()]) self.assertEqual(current_metric_value - prev_metric_value, 1)
def testLatencyStatsAreCorrectlyRecorded(self): with test_lib.FakeTime(0): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_args.periodicity = "1w" cron_job_urn = cron_manager.ScheduleFlow( 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_urn.Basename()]) # Fast foward one minute with test_lib.FakeTime(60): cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open( cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) cron_flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN) for _ in flow_test_lib.TestFlowHelper( cron_flow_urn, check_flow_errors=False, token=self.token): pass # 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_urn.Basename()]) self.assertEqual(current_metric_value.count - prev_metric_value.count, 1) self.assertEqual(current_metric_value.sum - prev_metric_value.sum, 60)
def testCronJobPreservesFlowNameAndArguments(self): """Testing initialization of a ConfigManager.""" pathspec = rdf_paths.PathSpec( path="/foo", pathtype=rdf_paths.PathSpec.PathType.TSK) cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs( periodicity="1d", allow_overruns=False) cron_args.flow_runner_args.flow_name = transfer.GetFile.__name__ cron_args.flow_args.pathspec = pathspec cron_job_urn = cron_manager.ScheduleFlow( cron_args=cron_args, token=self.token) # Check that CronJob definition is saved properly cron_root = aff4.FACTORY.Open(cron_manager.CRON_JOBS_PATH, token=self.token) cron_jobs = list(cron_root.ListChildren()) self.assertEqual(len(cron_jobs), 1) self.assertEqual(cron_jobs[0], cron_job_urn) cron_job = aff4.FACTORY.Open(cron_jobs[0], token=self.token) cron_args = cron_job.Get(cron_job.Schema.CRON_ARGS) self.assertEqual(cron_args.flow_runner_args.flow_name, transfer.GetFile.__name__) self.assertEqual(cron_args.flow_args.pathspec, pathspec) self.assertEqual(cron_args.periodicity, rdfvalue.Duration("1d")) self.assertEqual(cron_args.allow_overruns, False)
def testCronJobStartsFlowAndCreatesSymlinkOnRun(self): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_job_urn = cron_manager.ScheduleFlow( cron_args=cron_args, token=self.token) cron_job = aff4.FACTORY.Open( cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) self.assertFalse(cron_job.IsRunning()) # The job never ran, so DueToRun() should return true. self.assertTrue(cron_job.DueToRun()) cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open( cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) self.assertTrue(cron_job.IsRunning()) # Check that a link to the flow is created under job object. cron_job_flows = list(cron_job.ListChildren()) self.assertEqual(len(cron_job_flows), 1) # Check that the link points to the correct flow. cron_job_flow = aff4.FACTORY.Open(cron_job_flows[0], token=self.token) self.assertEqual(cron_job_flow.runner_args.flow_name, "FakeCronJob")
def testSchedulingJobWithFixedNamePreservesTheName(self): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs( allow_overruns=True, periodicity="1d") cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_job_urn = cron_manager.ScheduleFlow( cron_args=cron_args, token=self.token, job_name="TheJob") self.assertEqual("TheJob", cron_job_urn.Basename())
def testKillOldFlows(self): with test_lib.FakeTime(0): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_args.periodicity = "1w" cron_args.lifetime = FakeCronJob.lifetime cron_job_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token) cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) self.assertTrue(cron_job.IsRunning()) self.assertFalse(cron_job.KillOldFlows()) prev_timeout_value = stats.STATS.GetMetricValue( "cron_job_timeout", fields=[cron_job_urn.Basename()]) prev_latency_value = stats.STATS.GetMetricValue( "cron_job_latency", fields=[cron_job_urn.Basename()]) # Fast foward one day with test_lib.FakeTime(24 * 60 * 60 + 1): flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN) cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) self.assertFalse(cron_job.IsRunning()) # Check the termination log log_collection = flow.GRRFlow.LogCollectionForFID(flow_urn) for line in log_collection: if line.urn == flow_urn: self.assertTrue( "lifetime exceeded" in str(line.log_message)) # Check that timeout counter got updated. current_timeout_value = stats.STATS.GetMetricValue( "cron_job_timeout", fields=[cron_job_urn.Basename()]) self.assertEqual(current_timeout_value - prev_timeout_value, 1) # Check that latency stat got updated. current_latency_value = stats.STATS.GetMetricValue( "cron_job_latency", fields=[cron_job_urn.Basename()]) self.assertEqual( current_latency_value.count - prev_latency_value.count, 1) self.assertEqual( current_latency_value.sum - prev_latency_value.sum, 24 * 60 * 60 + 1)
def Run(self): with test_lib.FakeTime(42): self.CreateAdminUser("approver") cron_manager = aff4_cronjobs.CronManager() cron_args = aff4_cronjobs.CreateCronJobFlowArgs( periodicity="1d", allow_overruns=False) cron1_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token) cron2_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token) with test_lib.FakeTime(44): approval_urn = security.CronJobApprovalRequestor( reason="foo", subject_urn=cron1_urn, approver="approver", token=self.token).Request() approval1_id = approval_urn.Basename() with test_lib.FakeTime(45): approval_urn = security.CronJobApprovalRequestor( reason="bar", subject_urn=cron2_urn, approver="approver", token=self.token).Request() approval2_id = approval_urn.Basename() with test_lib.FakeTime(84): approver_token = access_control.ACLToken(username="******") security.CronJobApprovalGrantor(reason="bar", delegate=self.token.username, subject_urn=cron2_urn, token=approver_token).Grant() with test_lib.FakeTime(126): self.Check("GetCronJobApproval", args=user_plugin.ApiGetCronJobApprovalArgs( username=self.token.username, cron_job_id=cron1_urn.Basename(), approval_id=approval1_id), replace={ cron1_urn.Basename(): "CronJob_123456", approval1_id: "approval:111111" }) self.Check("GetCronJobApproval", args=user_plugin.ApiGetCronJobApprovalArgs( username=self.token.username, cron_job_id=cron2_urn.Basename(), approval_id=approval2_id), replace={ cron2_urn.Basename(): "CronJob_567890", approval2_id: "approval:222222" })
def setUp(self): super(ApiListCronJobFlowsHandlerRegressionTest, self).setUp() with test_lib.FakeTime(44): cron_args = cronjobs.CreateCronJobFlowArgs(periodicity="7d", lifetime="1d") cron_args.flow_runner_args.flow_name = self.flow_name cronjobs.CRON_MANAGER.ScheduleFlow(cron_args, job_name=self.flow_name, token=self.token) cronjobs.CRON_MANAGER.RunOnce(token=self.token)
def testCronJobRunMonitorsRunningFlowState(self): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs(allow_overruns=False, periodicity="1d") cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_job_urn = cron_manager.ScheduleFlow(cron_args, token=self.token) # Run() wasn't called, so nothing is supposed to be running cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) self.assertFalse(cron_job.IsRunning()) cron_manager.RunOnce(token=self.token) # Run() was called and flow was started, so the job should be # considered running. cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) self.assertTrue(cron_job.IsRunning()) # Find the flow that is currently running for the job and terminate it. cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) self.assertTrue(cron_job.IsRunning()) cron_job_flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN) self.assertTrue(cron_job_flow_urn is not None) flow.GRRFlow.TerminateFlow(cron_job_flow_urn, token=self.token) # Check we're dead cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) self.assertFalse(cron_job.IsRunning()) # This will understand that current flow has terminated. New flow won't be # started, because iterations are supposed to be started once per day # (frequency=1d). cron_manager.RunOnce(token=self.token) # Still dead cron_job = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) self.assertFalse(cron_job.IsRunning())
def testRendersRequestedCronJobApproval(self): cron_manager = aff4_cronjobs.CronManager() cron_args = aff4_cronjobs.CreateCronJobFlowArgs(periodicity="1d", allow_overruns=False) cron_job_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token) self.RequestCronJobApproval(cron_job_urn.Basename(), reason=self.token.reason, approver="approver", requestor=self.token.username) args = user_plugin.ApiListCronJobApprovalsArgs() result = self.handler.Handle(args, token=self.token) self.assertEqual(len(result.items), 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 = cronjobs.CreateCronJobFlowArgs(periodicity="7d", lifetime="1d") cron_args.flow_runner_args.flow_name = flow_name cronjobs.CRON_MANAGER.ScheduleFlow(cron_args, job_name=flow_name, token=self.token) cronjobs.CRON_MANAGER.RunOnce(token=self.token)
def CreateCronJob(self, flow_name, periodicity="1d", lifetime="7d", description="", disabled=False, token=None): cron_args = cronjobs.CreateCronJobFlowArgs(periodicity=periodicity, lifetime=lifetime, description=description) cron_args.flow_runner_args.flow_name = flow_name return cronjobs.CRON_MANAGER.ScheduleFlow(cron_args, job_name=flow_name, disabled=disabled, token=token)
def setUp(self): super(ApiCreateCronJobApprovalHandlerTest, self).setUp() self.SetUpApprovalTest() cron_manager = aff4_cronjobs.CronManager() cron_args = aff4_cronjobs.CreateCronJobFlowArgs( periodicity="1d", allow_overruns=False) self.subject_urn = cron_urn = cron_manager.ScheduleFlow( cron_args=cron_args, token=self.token) cron_id = cron_urn.Basename() self.handler = user_plugin.ApiCreateCronJobApprovalHandler() self.args = user_plugin.ApiCreateCronJobApprovalArgs(cron_job_id=cron_id) self.args.approval.reason = self.token.reason self.args.approval.notified_users = ["approver"] self.args.approval.email_cc_addresses = ["*****@*****.**"]
def testCronManagerListJobsDoesNotListDeletedJobs(self): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs( allow_overruns=True, periodicity="1d") cron_args.flow_runner_args.flow_name = "FakeCronJob" cron_job_urn = cron_manager.ScheduleFlow( cron_args=cron_args, token=self.token) cron_jobs = list(cron_manager.ListJobs(token=self.token)) self.assertEqual(len(cron_jobs), 1) cron_manager.DeleteJob(cron_job_urn, token=self.token) cron_jobs = list(cron_manager.ListJobs(token=self.token)) self.assertEqual(len(cron_jobs), 0)
def Handle(self, args, token=None): args.flow_args.hunt_runner_args.hunt_name = "GenericHunt" # TODO(user): The following should be asserted in a more elegant way. # Also, it's not clear whether cron job scheduling UI is used often enough # to justify its existence. We should check with opensource users whether # they find this feature useful and if not, deprecate it altogether. if args.flow_name != standard.CreateAndRunGenericHuntFlow.__name__: raise ValueError( "Only CreateAndRunGenericHuntFlow flows are supported " "here (got: %s)." % args.flow_name) # 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.flow_runner_args.ClearFieldsWithLabel( rdf_structs.SemanticDescriptor.Labels.HIDDEN, exceptions="output_plugins") if not args.flow_runner_args.flow_name: args.flow_runner_args.flow_name = args.flow_name cron_args = aff4_cronjobs.CreateCronJobFlowArgs( description=args.description, periodicity=args.periodicity, flow_runner_args=args.flow_runner_args, flow_args=args.flow_args, allow_overruns=args.allow_overruns, lifetime=args.lifetime) urn = aff4_cronjobs.CRON_MANAGER.ScheduleFlow(cron_args=cron_args, disabled=True, token=token) fd = aff4.FACTORY.Open(urn, aff4_type=aff4_cronjobs.CronJob, token=token, age=aff4.ALL_TIMES) return ApiCronJob().InitFromAff4Object(fd)
def testLastRunStatusGetsUpdatedOnEveryRun(self): cron_manager = cronjobs.CronManager() cron_args = cronjobs.CreateCronJobFlowArgs() cron_args.flow_runner_args.flow_name = "OccasionallyFailingFakeCronJob" cron_args.periodicity = "30s" cron_job_urn = cron_manager.ScheduleFlow(cron_args=cron_args, token=self.token) 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 = aff4.FACTORY.Open(cron_job_urn, aff4_type=cronjobs.CronJob, token=self.token) cron_flow_urn = cron_job.Get(cron_job.Schema.CURRENT_FLOW_URN) for _ in flow_test_lib.TestFlowHelper(cron_flow_urn, check_flow_errors=False, token=self.token): pass # This RunOnce call should determine that the flow has finished cron_manager.RunOnce(token=self.token) cron_job = aff4.FACTORY.Open(cron_job_urn, age=aff4.ALL_TIMES, 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().FromSecondsFromEpoch(0)) self.assertEqual(statuses[1].age, rdfvalue.RDFDatetime().FromSecondsFromEpoch(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(CleanCronJobsTest, self).setUp() with test_lib.FakeTime(40): cron_args = cronjobs.CreateCronJobFlowArgs( periodicity=RetentionTestSystemCronJob.frequency) cron_args.flow_runner_args.flow_name = RetentionTestSystemCronJob.__name__ cron_args.lifetime = RetentionTestSystemCronJob.lifetime self.cron_jobs_urns = [] self.cron_jobs_urns.append( cronjobs.CRON_MANAGER.ScheduleFlow(cron_args=cron_args, job_name="Foo", token=self.token, disabled=False)) self.cron_jobs_urns.append( cronjobs.CRON_MANAGER.ScheduleFlow(cron_args=cron_args, job_name="Bar", token=self.token, disabled=False)) for i in range(self.NUM_CRON_RUNS): with test_lib.FakeTime(40 + 60 * i): cronjobs.CRON_MANAGER.RunOnce(token=self.token, force=True)