def testInitFromCronObject(self): state = rdf_protodict.AttributedDict() state["quux"] = "norf" state["thud"] = "blargh" cron_job = rdf_cronjobs.CronJob() cron_job.cron_job_id = "foo" cron_job.current_run_id = "bar" cron_job.last_run_time = self._DATETIME("2001-01-01") cron_job.last_run_status = "FINISHED" cron_job.frequency = rdfvalue.DurationSeconds("1d") cron_job.lifetime = rdfvalue.DurationSeconds("30d") cron_job.enabled = False cron_job.forced_run_requested = True cron_job.state = state cron_job.description = "testdescription" api_cron_job = cron_plugin.ApiCronJob.InitFromObject(cron_job) self.assertEqual(api_cron_job.cron_job_id, "foo") self.assertEqual(api_cron_job.current_run_id, "bar") self.assertEqual(api_cron_job.description, "testdescription") self.assertEqual(api_cron_job.last_run_time, self._DATETIME("2001-01-01")) self.assertEqual(api_cron_job.last_run_status, "FINISHED") self.assertEqual(api_cron_job.frequency, rdfvalue.DurationSeconds("1d")) self.assertEqual(api_cron_job.lifetime, rdfvalue.DurationSeconds("30d")) self.assertFalse(api_cron_job.enabled) self.assertTrue(api_cron_job.forced_run_requested) api_state_items = {_.key: _.value for _ in api_cron_job.state.items} self.assertEqual(api_state_items, {"quux": "norf", "thud": "blargh"})
def testMinSendInterval(self, mock_send, mock_config): del mock_config # Unused. worker = mock.MagicMock() collector = client_stats.ClientStatsCollector(worker) worker.stats_collector = collector worker.IsActive = lambda: False with test_lib.FakeTimeline(thread=collector) as timeline: timeline.Run(duration=rdfvalue.DurationSeconds("15s")) self.assertTrue(mock_send.called) collector.RequestSend() mock_send.reset_mock() timeline.Run(duration=rdfvalue.DurationSeconds("10s")) self.assertFalse(mock_send.called) mock_send.reset_mock() timeline.Run(duration=rdfvalue.DurationSeconds("20s")) self.assertFalse(mock_send.called) mock_send.reset_mock() timeline.Run(duration=rdfvalue.DurationSeconds("40s")) self.assertTrue(mock_send.called) mock_send.reset_mock() timeline.Run(duration=rdfvalue.DurationSeconds("30s")) self.assertFalse(mock_send.called)
def testRunSingleSleep(self): log = [] def foo(): while True: log.append("foo") time.sleep(10) thread = threading.Thread(name="foo-thread", target=foo) with test_lib.FakeTimeline(thread) as foo_timeline: log.append("start") foo_timeline.Run(duration=rdfvalue.DurationSeconds("5s")) log.append("5 seconds have passed") foo_timeline.Run(duration=rdfvalue.DurationSeconds("3s")) log.append("3 seconds have passed") foo_timeline.Run(duration=rdfvalue.DurationSeconds("4s")) log.append("4 seconds have passed") foo_timeline.Run(duration=rdfvalue.DurationSeconds("22s")) log.append("22 seconds have passed") self.assertEqual(log, [ "start", "foo", "5 seconds have passed", "3 seconds have passed", "foo", "4 seconds have passed", "foo", "foo", "22 seconds have passed", ])
def testCachingIsDonePerArguments(self): decorated = cache.WithLimitedCallFrequency( rdfvalue.DurationSeconds("30s"))(self.mock_fn) now = rdfvalue.RDFDatetime.Now() with test_lib.FakeTime(now): r1_a = decorated(1) r1_b = decorated(2) self.assertNotEqual(r1_a, r1_b) self.assertEqual(self.mock_fn.call_count, 2) with test_lib.FakeTime(now + rdfvalue.DurationSeconds("15s")): r2_a = decorated(1) r2_b = decorated(2) self.assertEqual(r1_a, r2_a) self.assertEqual(r1_b, r2_b) self.assertEqual(self.mock_fn.call_count, 2) with test_lib.FakeTime(now + rdfvalue.DurationSeconds("30s")): r3_a = decorated(1) r3_b = decorated(2) self.assertNotEqual(r1_a, r3_a) self.assertNotEqual(r1_b, r3_b) self.assertEqual(self.mock_fn.call_count, 4)
def testStatefulSystemCronJobMaintainsState(self): DummyStatefulSystemCronJobRel.VALUES = [] # We need to have a cron job started to have a place to maintain # state. cron_manager = cronjobs.CronManager() args = rdf_cronjobs.CronJobAction( action_type=rdf_cronjobs.CronJobAction.ActionType. SYSTEM_CRON_ACTION, system_cron_action=rdf_cronjobs.SystemCronAction( job_class_name="DummyStatefulSystemCronJobRel")) job = rdf_cronjobs.CronJob(cron_job_id="test_cron", args=args, enabled=True, frequency=rdfvalue.DurationSeconds("2h"), lifetime=rdfvalue.DurationSeconds("1h"), allow_overruns=False) data_store.REL_DB.WriteCronJob(job) fake_time = rdfvalue.RDFDatetime.Now() for i in range(3): with test_lib.FakeTime(fake_time + rdfvalue.DurationSeconds("%dh" % (3 * i))): cron_manager.RunOnce() cron_manager._GetThreadPool().Join() runs = cron_manager.ReadJobRuns("test_cron") self.assertLen(runs, i + 1) for run in runs: self.assertEqual(run.status, "FINISHED") self.assertListEqual(DummyStatefulSystemCronJobRel.VALUES, [0, 1, 2])
class PurgeClientStatsCronJob(cronjobs.SystemCronJobBase): """Deletes outdated client statistics.""" frequency = rdfvalue.DurationSeconds("1w") lifetime = rdfvalue.DurationSeconds("20h") def Run(self): end = rdfvalue.RDFDatetime.Now() - db.CLIENT_STATS_RETENTION if data_store.AFF4Enabled(): client_urns = export_utils.GetAllClients(token=self.token) for batch in collection.Batch(client_urns, 10000): with data_store.DB.GetMutationPool() as mutation_pool: for client_urn in batch: mutation_pool.DeleteAttributes( client_urn.Add("stats"), [u"aff4:stats"], start=0, end=end.AsMicrosecondsSinceEpoch()) self.HeartBeat() if data_store.RelationalDBEnabled(): total_deleted_count = 0 for deleted_count in data_store.REL_DB.DeleteOldClientStats( yield_after_count=_STATS_DELETION_BATCH_SIZE, retention_time=end): self.HeartBeat() total_deleted_count += deleted_count self.Log("Deleted %d ClientStats that expired before %s", total_deleted_count, end)
def testRunException(self): log = [] def quux(): time.sleep(10) log.append("foo") time.sleep(10) raise Exception("bar") thread = threading.Thread(name="quux-thread", target=quux) with test_lib.FakeTimeline(thread) as quux_timeline: log.append("start") quux_timeline.Run(duration=rdfvalue.DurationSeconds("6s")) log.append("6 seconds have passed") quux_timeline.Run(duration=rdfvalue.DurationSeconds("5s")) log.append("5 seconds have passed") quux_timeline.Run(duration=rdfvalue.DurationSeconds("7s")) log.append("7 seconds have passed") self.assertEqual(log, [ "start", "6 seconds have passed", "foo", "5 seconds have passed", "7 seconds have passed", ]) with self.assertRaisesRegex(Exception, "bar"): quux_timeline.Run(duration=rdfvalue.DurationSeconds("10s"))
class LoggingCronJob(cronjobs.SystemCronJobBase): lifetime = rdfvalue.DurationSeconds("1h") frequency = rdfvalue.DurationSeconds("2h") def Run(self): for i in range(7): self.Log("Log message %d." % i)
def testSendWhenWorkerIsActive(self, mock_send, mock_config): del mock_config # Unused. worker = mock.MagicMock() collector = client_stats.ClientStatsCollector(worker) worker.stats_collector = collector with test_lib.FakeTimeline(thread=collector) as timeline: worker.IsActive = lambda: True mock_send.reset_mock() timeline.Run(duration=rdfvalue.DurationSeconds("5s")) self.assertTrue(mock_send.called) mock_send.reset_mock() timeline.Run(duration=rdfvalue.DurationSeconds("2m")) self.assertTrue(mock_send.called) worker.IsActive = lambda: False mock_send.reset_mock() timeline.Run(duration=rdfvalue.DurationSeconds("30m")) self.assertFalse(mock_send.called) worker.IsActive = lambda: True mock_send.reset_mock() timeline.Run(duration=rdfvalue.DurationSeconds("5s")) self.assertTrue(mock_send.called)
def testRunSleepZero(self): log = [] def norf(): time.sleep(0) log.append("norf") time.sleep(0) log.append("norf") time.sleep(0) log.append("norf") thread = threading.Thread(name="norf-thread", target=norf) with test_lib.FakeTimeline(thread) as norf_timeline: log.append("start") norf_timeline.Run(duration=rdfvalue.DurationSeconds("0s")) log.append("rest") norf_timeline.Run(duration=rdfvalue.DurationSeconds("0s")) log.append("stop") self.assertEqual(log, [ "start", "norf", "norf", "norf", "rest", "stop", ])
def testCronJobLeasing(self): job = self._CreateCronJob() self.db.WriteCronJob(job) current_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch(10000) lease_time = rdfvalue.DurationSeconds("5m") with test_lib.FakeTime(current_time): leased = self.db.LeaseCronJobs(lease_time=lease_time) self.assertLen(leased, 1) leased_job = leased[0] self.assertTrue(leased_job.leased_by) self.assertEqual(leased_job.leased_until, current_time + lease_time) with test_lib.FakeTime(current_time + rdfvalue.DurationSeconds("1m")): leased = self.db.LeaseCronJobs(lease_time=lease_time) self.assertFalse(leased) with test_lib.FakeTime(current_time + rdfvalue.DurationSeconds("6m")): leased = self.db.LeaseCronJobs(lease_time=lease_time) self.assertLen(leased, 1) leased_job = leased[0] self.assertTrue(leased_job.leased_by) self.assertEqual( leased_job.leased_until, current_time + rdfvalue.DurationSeconds("6m") + lease_time)
def testHuntIsStoppedWhenExpirationTimeIsReached(self): client_ids = self.SetupClients(5) duration = rdfvalue.DurationSeconds("1d") expiry_time = rdfvalue.RDFDatetime.Now() + duration hunt_id = self._CreateHunt( client_rule_set=foreman_rules.ForemanClientRuleSet(), client_rate=0, duration=duration, args=self.GetFileHuntArgs()) client_mock = hunt_test_lib.SampleHuntMock(failrate=-1) foreman_obj = foreman.Foreman() for client_id in client_ids: foreman_obj.AssignTasksToClient(client_id) hunt_test_lib.TestHuntHelper(client_mock, client_ids[:3]) hunt_obj = data_store.REL_DB.ReadHuntObject(hunt_id) self.assertEqual(hunt_obj.hunt_state, rdf_hunt_objects.Hunt.HuntState.STARTED) with test_lib.FakeTime(expiry_time - rdfvalue.DurationSeconds("1s")): hunt_test_lib.TestHuntHelper(client_mock, client_ids[3:4]) hunt_obj = data_store.REL_DB.ReadHuntObject(hunt_id) self.assertEqual(hunt_obj.hunt_state, rdf_hunt_objects.Hunt.HuntState.STARTED) with test_lib.FakeTime(expiry_time + rdfvalue.DurationSeconds("1s")): hunt_test_lib.TestHuntHelper(client_mock, client_ids[4:5]) hunt_obj = data_store.REL_DB.ReadHuntObject(hunt_id) self.assertEqual(hunt_obj.hunt_state, rdf_hunt_objects.Hunt.HuntState.COMPLETED)
class SystemCronFlow(flow.GRRFlow): """SystemCronFlows are scheduled automatically on workers startup.""" frequency = rdfvalue.DurationSeconds("1d") lifetime = rdfvalue.DurationSeconds("20h") allow_overruns = False # Jobs that are broken, or are under development can be disabled using # the "enabled" attribute. These jobs won't get scheduled automatically, # and will get paused if they were scheduled before. enabled = True __abstract = True # pylint: disable=g-bad-name def _ValidateState(self): # For normal flows it's a bug to write an empty state, here it's ok. pass @property def disabled(self): raise ValueError("Disabled flag is deprecated, use enabled instead.") @disabled.setter def disabled(self, _): raise ValueError("Disabled flag is deprecated, use enabled instead.")
def testReadApprovalRequestsForSubjectKeepsExpiredApprovalsWhenAsked(self): client_id = "C.0000000050000001" d = self.db d.WriteGRRUser("requestor") time_future = rdfvalue.RDFDatetime.Now() + rdfvalue.DurationSeconds( "1d") time_past = rdfvalue.RDFDatetime.Now() - rdfvalue.DurationSeconds("1d") approval_ids = set() for i in range(10): approval_request = rdf_objects.ApprovalRequest( approval_type=rdf_objects.ApprovalRequest.ApprovalType. APPROVAL_TYPE_CLIENT, subject_id=client_id, requestor_username="******", reason="some test reason", expiration_time=(time_future if i % 2 == 0 else time_past)) approval_ids.add(d.WriteApprovalRequest(approval_request)) approvals = list( d.ReadApprovalRequests( "requestor", rdf_objects.ApprovalRequest.ApprovalType.APPROVAL_TYPE_CLIENT, subject_id=client_id, include_expired=True)) self.assertLen(approvals, 10) self.assertEqual(set(a.approval_id for a in approvals), approval_ids)
def testReadApprovalRequestsFiltersOutExpiredApprovals(self): d = self.db d.WriteGRRUser("requestor") time_future = rdfvalue.RDFDatetime.Now() + rdfvalue.DurationSeconds( "1d") time_past = rdfvalue.RDFDatetime.Now() - rdfvalue.DurationSeconds("1d") non_expired_approval_ids = set() for i in range(10): approval_request = rdf_objects.ApprovalRequest( approval_type=rdf_objects.ApprovalRequest.ApprovalType. APPROVAL_TYPE_CLIENT, subject_id="C.000000005000000%d" % i, requestor_username="******", reason="some test reason", expiration_time=(time_future if i % 2 == 0 else time_past)) approval_id = d.WriteApprovalRequest(approval_request) if i % 2 == 0: non_expired_approval_ids.add(approval_id) approvals = list( d.ReadApprovalRequests( "requestor", rdf_objects.ApprovalRequest.ApprovalType.APPROVAL_TYPE_CLIENT)) self.assertLen(approvals, 5) self.assertEqual(set(a.approval_id for a in approvals), non_expired_approval_ids)
def StartInterrogationHunt(self): """Starts an interrogation hunt on all available clients.""" flow_name = compatibility.GetName(flows_discovery.Interrogate) flow_args = flows_discovery.InterrogateArgs(lightweight=False) description = "Interrogate run by cron to keep host info fresh." if data_store.RelationalDBEnabled(): hunt_id = hunt.CreateAndStartHunt( flow_name, flow_args, self.token.username, client_limit=0, client_rate=50, crash_limit=config.CONFIG["Cron.interrogate_crash_limit"], description=description, duration=rdfvalue.DurationSeconds("1w"), output_plugins=self.GetOutputPlugins()) self.Log("Started hunt %s.", hunt_id) else: with hunts_implementation.StartHunt( hunt_name=hunts_standard.GenericHunt.__name__, client_limit=0, flow_runner_args=rdf_flow_runner.FlowRunnerArgs( flow_name=flow_name), flow_args=flow_args, output_plugins=self.GetOutputPlugins(), crash_limit=config.CONFIG["Cron.interrogate_crash_limit"], client_rate=50, expiry_time=rdfvalue.DurationSeconds("1w"), description=description, token=self.token) as hunt_obj: hunt_obj.GetRunner().Start() self.Log("Started hunt %s.", hunt_obj.urn)
def MakeCASignedCert(common_name, private_key, ca_cert, ca_private_key, serial_number=2): """Make a cert and sign it with the CA's private key.""" public_key = private_key.GetPublicKey() builder = x509.CertificateBuilder() builder = builder.issuer_name(ca_cert.GetIssuer()) subject = x509.Name( [x509.NameAttribute(oid.NameOID.COMMON_NAME, common_name)]) builder = builder.subject_name(subject) valid_from = rdfvalue.RDFDatetime.Now() - rdfvalue.DurationSeconds("1d") valid_until = rdfvalue.RDFDatetime.Now() + rdfvalue.DurationSeconds("3650d") builder = builder.not_valid_before(valid_from.AsDatetime()) builder = builder.not_valid_after(valid_until.AsDatetime()) builder = builder.serial_number(serial_number) builder = builder.public_key(public_key.GetRawPublicKey()) builder = builder.add_extension( x509.BasicConstraints(ca=False, path_length=None), critical=True) certificate = builder.sign( private_key=ca_private_key.GetRawPrivateKey(), algorithm=hashes.SHA256(), backend=openssl.backend) return rdf_crypto.RDFX509Cert(certificate)
def testHeartBeatingFlowIsNotTreatedAsStuck(self): worker_obj = self._TestWorker() initial_time = rdfvalue.RDFDatetime.FromSecondsSinceEpoch(100) stuck_flows_timeout = flow_runner.FlowRunner.stuck_flows_timeout lease_timeout = rdfvalue.DurationSeconds( worker_lib.GRRWorker.flow_lease_time) WorkerStuckableTestFlow.Reset(heartbeat=True) try: with test_lib.FakeTime(initial_time.AsSecondsSinceEpoch()): session_id = flow.StartAFF4Flow( flow_name=WorkerStuckableTestFlow.__name__, client_id=self.client_id, token=self.token, sync=False) # Process all messages worker_obj.RunOnce() # Wait until worker thread starts processing the flow. WorkerStuckableTestFlow.WaitUntilWorkerStartsProcessing() # Increase the time in steps, using LetFlowHeartBeat/WaitForFlowHeartBeat # to control the flow execution that happens in the parallel thread. current_time = rdfvalue.RDFDatetime(initial_time) future_time = initial_time + stuck_flows_timeout + rdfvalue.DurationSeconds( "1m") while current_time <= future_time: current_time += lease_timeout - rdfvalue.DurationSeconds("1s") with test_lib.FakeTime(current_time.AsSecondsSinceEpoch()): checked_flow = aff4.FACTORY.Open(session_id, token=self.token) WorkerStuckableTestFlow.LetFlowHeartBeat() WorkerStuckableTestFlow.StopFlow() # Now current_time is > future_time, where future_time is the time # when stuck flow should have been killed. Calling RunOnce() here, # because if the flow is going to be killed, it will be killed # during worker.RunOnce() call. with test_lib.FakeTime(current_time.AsSecondsSinceEpoch()): worker_obj.RunOnce() # Check that the flow wasn't killed forecfully. checked_flow = aff4.FACTORY.Open(session_id, token=self.token) self.assertEqual(checked_flow.context.state, rdf_flow_runner.FlowContext.State.RUNNING) finally: # Release the semaphore so that worker thread unblocks and finishes # processing the flow. with test_lib.FakeTime(current_time.AsSecondsSinceEpoch()): WorkerStuckableTestFlow.LetWorkerFinishProcessing() worker_obj.thread_pool.Join() # Check that the flow has finished normally. checked_flow = aff4.FACTORY.Open(session_id, token=self.token) self.assertEqual(checked_flow.context.state, rdf_flow_runner.FlowContext.State.TERMINATED)
class DummySystemCronJobRel(cronjobs.SystemCronJobBase): """Dummy system cron job.""" lifetime = rdfvalue.DurationSeconds("42h") frequency = rdfvalue.DurationSeconds("42d") def Run(self): pass
class DummySystemCronJob(aff4_cronjobs.SystemCronFlow): """Dummy system cron job.""" lifetime = rdfvalue.DurationSeconds("42h") frequency = rdfvalue.DurationSeconds("42d") def Start(self): self.CallState(next_state="End")
def testLerpQuarter(self): start_time = rdfvalue.RDFDatetime.FromHumanReadable("2000-01-01") end_time = start_time + rdfvalue.DurationSeconds("4d") lerped_time = rdfvalue.RDFDatetime.Lerp(0.25, start_time=start_time, end_time=end_time) self.assertEqual(lerped_time, start_time + rdfvalue.DurationSeconds("1d"))
def fhesh(): log.append(rdfvalue.RDFDatetime.Now().Format("%Y-%m-%d")) time.sleep(rdfvalue.DurationSeconds("2d").seconds) log.append(rdfvalue.RDFDatetime.Now().Format("%Y-%m-%d")) time.sleep(rdfvalue.DurationSeconds("15s").seconds) log.append(rdfvalue.RDFDatetime.Now().Format("%Y-%m-%d %H:%M:%S")) time.sleep(rdfvalue.DurationSeconds("20m").seconds) log.append(rdfvalue.RDFDatetime.Now().Format("%Y-%m-%d %H:%M:%S"))
def testLerpMiddle(self): start_time = rdfvalue.RDFDatetime.FromHumanReadable("2010-01-01") end_time = start_time + rdfvalue.DurationSeconds("10d") lerped_time = rdfvalue.RDFDatetime.Lerp(0.5, start_time=start_time, end_time=end_time) self.assertEqual(lerped_time, start_time + rdfvalue.DurationSeconds("5d"))
def testIAddDuration(self): date = rdfvalue.RDFDatetime(1e9) date += rdfvalue.DurationSeconds("12h") self.assertEqual(date, 1e9 + 12 * 3600e6) date = rdfvalue.RDFDatetime(1e9) date += rdfvalue.DurationSeconds("-60s") self.assertEqual(date, 1e9 - 60e6)
def testSubDuration(self): duration = rdfvalue.DurationSeconds("5m") date = rdfvalue.RDFDatetime(1e9) self.assertEqual(int(date - duration), 1e9 - 5 * 60e6) duration = rdfvalue.DurationSeconds("-60s") self.assertEqual(int(date - duration), 1e9 + 60e6) duration = rdfvalue.DurationSeconds("1w") self.assertEqual(int(date - duration), 1e9 - 7 * 24 * 3600e6)
def testTimeoutOfLongRunningJobIsHandledCorrectly(self): wait_event = threading.Event() signal_event = threading.Event() waiting_func = functools.partial(WaitAndSignal, wait_event, signal_event) fake_time = rdfvalue.RDFDatetime.Now() with mock.patch.object(cronjobs.RunHunt, "Run", wraps=waiting_func): with test_lib.FakeTime(fake_time): cron_manager = cronjobs.CronManager() create_flow_args = rdf_cronjobs.CreateCronJobArgs() create_flow_args.lifetime = "1h" job_id = cron_manager.CreateJob(cron_args=create_flow_args) cron_manager.RunOnce(token=self.token) # Make sure the cron job has actually been started. signal_event.wait(10) cron_job = cron_manager.ReadJob(job_id, token=self.token) self.assertTrue(cron_manager.JobIsRunning(cron_job)) runs = cron_manager.ReadJobRuns(job_id) self.assertLen(runs, 1) run = runs[0] self.assertEqual(cron_job.current_run_id, run.run_id) self.assertEqual(run.status, "RUNNING") prev_timeout_value = stats_collector_instance.Get().GetMetricValue( "cron_job_timeout", fields=[job_id]) prev_latency_value = stats_collector_instance.Get().GetMetricValue( "cron_job_latency", fields=[job_id]) fake_time += rdfvalue.DurationSeconds("2h") with test_lib.FakeTime(fake_time): wait_event.set() cron_manager._GetThreadPool().Join() cron_job = cron_manager.ReadJob(job_id, token=self.token) runs = cron_manager.ReadJobRuns(job_id) self.assertLen(runs, 1) run = runs[0] self.assertEqual(cron_job.last_run_status, "LIFETIME_EXCEEDED") self.assertEqual(run.status, "LIFETIME_EXCEEDED") # Check that timeout counter got updated. current_timeout_value = stats_collector_instance.Get( ).GetMetricValue("cron_job_timeout", fields=[job_id]) self.assertEqual(current_timeout_value - prev_timeout_value, 1) # Check that latency stat got updated. current_latency_value = stats_collector_instance.Get( ).GetMetricValue("cron_job_latency", fields=[job_id]) self.assertEqual( current_latency_value.count - prev_latency_value.count, 1) self.assertEqual( current_latency_value.sum - prev_latency_value.sum, rdfvalue.DurationSeconds("2h").seconds)
class InterrogateClientsCronFlow(aff4_cronjobs.SystemCronFlow, InterrogationHuntMixin): """The legacy cron flow which runs an interrogate hunt on all clients.""" frequency = rdfvalue.DurationSeconds("1w") # This just starts a hunt, which should be essentially instantantaneous lifetime = rdfvalue.DurationSeconds("30m") def Start(self): self.StartInterrogationHunt()
class HeartbeatingOverruningCronJob(cronjobs.SystemCronJobBase): lifetime = rdfvalue.DurationSeconds("1h") frequency = rdfvalue.DurationSeconds("2h") allow_overruns = True def Run(self): cron_started_event.set() heartbeat_event.wait() fake_time = self.run_state.started_at + rdfvalue.DurationSeconds("3h") with test_lib.FakeTime(fake_time): self.HeartBeat()
class GRRVersionBreakDownCronJob(cronjobs.SystemCronJobBase): """Saves a snapshot of n-day-active stats for all GRR client versions.""" frequency = rdfvalue.DurationSeconds("6h") lifetime = rdfvalue.DurationSeconds("6h") def Run(self): version_stats = data_store.REL_DB.CountClientVersionStringsByLabel( _FLEET_BREAKDOWN_DAY_BUCKETS) _WriteFleetBreakdownStatsToDB( version_stats, rdf_stats.ClientGraphSeries.ReportType.GRR_VERSION)
def testOnlyTheLatestCrashIsDisplayed(self): timestamp = rdfvalue.RDFDatetime.Now() client_id = self.CreateClient(last_ping=timestamp) self.RecordCrash(client_id, timestamp - rdfvalue.DurationSeconds("2h")) self.RecordCrash(client_id, timestamp - rdfvalue.DurationSeconds("5s")) self.RequestAndGrantClientApproval(client_id) self.Open("/#c=" + str(client_id)) self.WaitUntil(self.IsTextPresent, "Last crash") self.WaitUntilContains("seconds", self.GetText, "css=grr-client-summary .last-crash")