def testFailingOutputPluginDoesNotAffectOtherOutputPlugins(self): self.StartHunt(output_plugins=[ output_plugin.OutputPluginDescriptor( plugin_name="FailingDummyHuntOutputPlugin"), output_plugin.OutputPluginDescriptor( plugin_name="DummyHuntOutputPlugin") ]) # Process hunt results. self.ProcessHuntOutputPlugins() self.assertEqual(DummyHuntOutputPlugin.num_calls, 0) self.assertEqual(DummyHuntOutputPlugin.num_responses, 0) self.AssignTasksToClients() self.RunHunt(failrate=-1) # We shouldn't get any more calls after the first call to # ProcessHuntResultsCronFlow. self.assertRaises(standard.ResultsProcessingError, self.ProcessHuntOutputPlugins) for _ in range(5): self.ProcessHuntOutputPlugins() self.assertEqual(DummyHuntOutputPlugin.num_calls, 1) self.assertEqual(DummyHuntOutputPlugin.num_responses, 10)
def testResultsProcessingErrorContainsDetailedFailureData(self): failing_plugin_descriptor = output_plugin.OutputPluginDescriptor( plugin_name="FailingDummyHuntOutputPlugin") plugin_descriptor = output_plugin.OutputPluginDescriptor( plugin_name="DummyHuntOutputPlugin") hunt_urn = self.StartHunt( output_plugins=[failing_plugin_descriptor, plugin_descriptor]) # Process hunt results. self.ProcessHuntOutputPlugins() self.assertEqual(DummyHuntOutputPlugin.num_calls, 0) self.assertEqual(DummyHuntOutputPlugin.num_responses, 0) self.AssignTasksToClients() self.RunHunt(failrate=-1) # We shouldn't get any more calls after the first call to # ProcessHuntResultsCronFlow. try: self.ProcessHuntOutputPlugins() except standard.ResultsProcessingError as e: self.assertEqual(len(e.exceptions_by_hunt), 1) self.assertTrue(hunt_urn in e.exceptions_by_hunt) self.assertEqual(len(e.exceptions_by_hunt[hunt_urn]), 1) self.assertTrue( failing_plugin_descriptor in e.exceptions_by_hunt[hunt_urn]) self.assertEqual( len(e.exceptions_by_hunt[hunt_urn][failing_plugin_descriptor]), 1) self.assertEqual( e.exceptions_by_hunt[hunt_urn][failing_plugin_descriptor] [0].message, "Oh no!")
def testFailingPluginDoesNotImpactOtherPlugins(self): self.RunFlow( plugins=[ output_plugin.OutputPluginDescriptor( plugin_name="FailingDummyFlowOutputPlugin"), output_plugin.OutputPluginDescriptor( plugin_name="DummyFlowOutputPlugin")]) self.assertEqual(DummyFlowOutputPlugin.num_calls, 1) self.assertEqual(DummyFlowOutputPlugin.num_responses, 1)
def testMultipleHuntsOutputIsProcessedCorrectly(self): self.StartHunt(output_plugins=[output_plugin.OutputPluginDescriptor( plugin_name="DummyHuntOutputPlugin")]) self.StartHunt(output_plugins=[output_plugin.OutputPluginDescriptor( plugin_name="StatefulDummyHuntOutputPlugin")]) self.AssignTasksToClients() self.RunHunt(failrate=-1) self.ProcessHuntOutputPlugins() # Check that plugins worked correctly self.assertEqual(DummyHuntOutputPlugin.num_calls, 1) self.assertListEqual(StatefulDummyHuntOutputPlugin.data, [0])
def setUp(self): super(ApiListHuntOutputPluginLogsHandlerTest, self).setUp() self.client_ids = self.SetupClients(5) self.handler = hunt_plugin.ApiListHuntOutputPluginLogsHandler() self.output_plugins = [ output_plugin.OutputPluginDescriptor( plugin_name=DummyHuntTestOutputPlugin.__name__, plugin_args=DummyHuntTestOutputPlugin.args_type( filename_regex="foo")), output_plugin.OutputPluginDescriptor( plugin_name=DummyHuntTestOutputPlugin.__name__, plugin_args=DummyHuntTestOutputPlugin.args_type( filename_regex="bar")) ]
def testChecksAllHuntsEvenIfOneRaises(self): self.StartHunt(output_plugins=[output_plugin.OutputPluginDescriptor( plugin_name=DummyHuntOutputPluginWithRaisingVerifier.__name__)]) self.StartHunt(output_plugins=[output_plugin.OutputPluginDescriptor( plugin_name=VerifiableDummyHuntOutputPlugin.__name__)]) self.AssignTasksToClients() self.RunHunt() _, prev_results = self.GetVerificationsStats() self.assertRaises(standard.HuntVerificationError, flow.GRRFlow.StartFlow, flow_name="VerifyHuntOutputPluginsCronFlow", token=self.token) _, results = self.GetVerificationsStats() self.assertEqual(results["SUCCESS"] - prev_results.get("SUCCESS", 0), 1)
def Run(self): with test_lib.FakeTime(42, increment=1): hunt_urn = self.StartHunt( description="the hunt", output_plugins=[ output_plugin.OutputPluginDescriptor( plugin_name=DummyHuntTestOutputPlugin.__name__, plugin_args=DummyHuntTestOutputPlugin.args_type( filename_regex="blah!", fetch_binaries=True)) ]) self.client_ids = self.SetupClients(2) for index, client_id in enumerate(self.client_ids): self.AssignTasksToClients(client_ids=[client_id]) self.RunHunt(failrate=-1) with test_lib.FakeTime(100042 + index * 100): self.ProcessHuntOutputPlugins() self.Check( "GET", "/api/hunts/%s/output-plugins/" "DummyHuntTestOutputPlugin_0/logs" % hunt_urn.Basename(), replace={ hunt_urn.Basename(): "H:123456" })
def testUserChangesToCopiedFlowAreRespected(self): args = flows_processes.ListProcessesArgs(filename_regex="test[a-z]*", fetch_binaries=True) flow.GRRFlow.StartFlow( flow_name=flows_processes.ListProcesses.__name__, args=args, client_id=self.client_id, output_plugins=[self.email_descriptor], token=self.token) # Navigate to client and select newly created flow. self.Open("/#c=C.0000000000000001") self.Click("css=a[grrtarget='client.flows']") self.Click("css=td:contains('ListProcesses')") # Open wizard and change the arguments. self.Click("css=button[name=copy_flow]") self.Type("css=label:contains('Filename Regex') ~ * input", "somethingElse*") self.Click( "css=label:contains('Fetch Binaries') ~ * input[type=checkbox]") # Change output plugin and add another one. self.Click("css=label:contains('Output Plugins') ~ * button") self.Select( "css=grr-output-plugin-descriptor-form " "label:contains('Plugin') ~ * select:eq(0)", "DummyOutputPlugin") self.Type( "css=grr-output-plugin-descriptor-form " "label:contains('Filename Regex'):eq(0) ~ * input:text", "foobar!") self.Click("css=button:contains('Launch')") # Check that flows list got updated and that the new flow is selected. self.WaitUntil( self.IsElementPresent, "css=grr-client-flows-list tr:contains('ListProcesses'):nth(1)") self.WaitUntil( self.IsElementPresent, "css=grr-client-flows-list " "tr:contains('ListProcesses'):nth(0).row-selected") # Now open the last flow and check that it has the changes we made. with self.ACLChecksDisabled(): fd = aff4.FACTORY.Open(self.client_id.Add("flows"), token=self.token) flows = sorted(fd.ListChildren(), key=lambda x: x.age) fobj = aff4.FACTORY.Open(flows[-1], token=self.token) self.assertEqual( fobj.args, flows_processes.ListProcessesArgs( filename_regex="somethingElse*", )) self.assertListEqual(list(fobj.runner_args.output_plugins), [ output_plugin.OutputPluginDescriptor( plugin_name=DummyOutputPlugin.__name__, plugin_args=flows_processes.ListProcessesArgs( filename_regex="foobar!")), self.email_descriptor ])
def testHuntResultsArrivingWhileOldResultsAreProcessedAreHandled(self): self.StartHunt(output_plugins=[output_plugin.OutputPluginDescriptor( plugin_name="DummyHuntOutputPlugin")]) # Process hunt results. self.ProcessHuntOutputPlugins() # Check that nothing has happened because hunt hasn't reported any # results yet. self.assertEqual(DummyHuntOutputPlugin.num_calls, 0) self.assertEqual(DummyHuntOutputPlugin.num_responses, 0) # Generate new results while the plugin is working. self.num_processed = 0 def ProcessResponsesStub(_, responses): # Add 5 more results the first time we are called. if not self.num_processed: self.AssignTasksToClients(self.client_ids[5:]) self.RunHunt(failrate=-1) # Just count the total number processed - we don't care about batch size # at this point. self.num_processed += len(responses) with utils.Stubber(DummyHuntOutputPlugin, "ProcessResponses", ProcessResponsesStub): self.AssignTasksToClients(self.client_ids[:5]) self.RunHunt(failrate=-1) self.ProcessHuntOutputPlugins() self.assertEqual(10, self.num_processed) del self.num_processed
def testOutputPluginsProcessingStatusIsWrittenToStatusCollection(self): plugin_descriptor = output_plugin.OutputPluginDescriptor( plugin_name="DummyHuntOutputPlugin") hunt_urn = self.StartHunt(output_plugins=[plugin_descriptor]) # Run the hunt and process output plugins. self.AssignTasksToClients(self.client_ids) self.RunHunt(failrate=-1) self.ProcessHuntOutputPlugins() hunt = aff4.FACTORY.Open(hunt_urn, token=self.token) status_collection = aff4.FACTORY.Open( hunt.output_plugins_status_collection_urn, token=self.token) errors_collection = aff4.FACTORY.Open( hunt.output_plugins_errors_collection_urn, token=self.token) self.assertEqual(len(errors_collection), 0) self.assertEqual(len(status_collection), 1) self.assertEqual(status_collection[0].status, "SUCCESS") self.assertEqual(status_collection[0].batch_index, 0) self.assertEqual(status_collection[0].batch_size, 10) self.assertEqual(status_collection[0].plugin_descriptor, plugin_descriptor)
def testShowsFilesAndAllowsDownloadWhenCSVExportIsUsed(self): with self.ACLChecksDisabled(): self.client_ids = self.SetupClients(10) # Create hunt. self.CreateSampleHunt(output_plugins=[ output_plugin.OutputPluginDescriptor( plugin_name=csv_plugin.CSVOutputPlugin.__name__) ]) # Actually run created hunt. client_mock = test_lib.SampleHuntMock() test_lib.TestHuntHelper(client_mock, self.client_ids, False, self.token) # Make sure results are processed. flow_urn = flow.GRRFlow.StartFlow( flow_name=process_results.ProcessHuntResultCollectionsCronFlow. __name__, token=self.token) for _ in test_lib.TestFlowHelper(flow_urn, token=self.token): pass self.Open("/#main=ManageHunts") self.Click("css=td:contains('GenericHunt')") # Click the Results tab. self.Click("css=li[heading=Results]") self.WaitUntil(self.IsTextPresent, "Following files were written") # Check that displayed file can be downloaded. self.Click("css=a:contains('ExportedFile.csv')") self.WaitUntil(self.FileWasDownloaded)
def testMultipleOutputPluginsProcessingStatusAreWrittenToStatusCollection( self): plugin_descriptor = output_plugin.OutputPluginDescriptor( plugin_name="DummyHuntOutputPlugin") hunt_urn = self.StartHunt(output_plugins=[plugin_descriptor]) # Run the hunt on first 4 clients and process output plugins. self.AssignTasksToClients(self.client_ids[:4]) self.RunHunt(failrate=-1) self.ProcessHuntOutputPlugins() # Run the hunt on last 6 clients and process output plugins. self.AssignTasksToClients(self.client_ids[4:]) self.RunHunt(failrate=-1) self.ProcessHuntOutputPlugins() hunt = aff4.FACTORY.Open(hunt_urn, token=self.token) status_collection = aff4.FACTORY.Open( hunt.output_plugins_status_collection_urn, token=self.token) errors_collection = aff4.FACTORY.Open( hunt.output_plugins_errors_collection_urn, token=self.token) self.assertEqual(len(errors_collection), 0) self.assertEqual(len(status_collection), 2) items = sorted(status_collection, key=lambda x: x.age) self.assertEqual(items[0].status, "SUCCESS") self.assertEqual(items[0].batch_index, 0) self.assertEqual(items[0].batch_size, 4) self.assertEqual(items[0].plugin_descriptor, plugin_descriptor) self.assertEqual(items[1].status, "SUCCESS") self.assertEqual(items[1].batch_index, 0) self.assertEqual(items[1].batch_size, 6) self.assertEqual(items[1].plugin_descriptor, plugin_descriptor)
def testProcessHuntResultsCronFlowAbortsIfRunningTooLong(self): self.assertEqual(LongRunningDummyHuntOutputPlugin.num_calls, 0) test = [0] def TimeStub(): test[0] += 1e-6 return test[0] with utils.Stubber(time, "time", TimeStub): self.StartHunt(output_plugins=[ output_plugin.OutputPluginDescriptor( plugin_name="LongRunningDummyHuntOutputPlugin") ]) self.AssignTasksToClients() self.RunHunt(failrate=-1) # LongRunningDummyHuntOutputPlugin will set the time to 100s on the first # run, which will effectively mean that it's running for too long. self.ProcessHuntOutputPlugins( batch_size=1, max_running_time=rdfvalue.Duration("99s")) # In normal conditions, there should be 10 results generated. # With batch size of 1 this should result in 10 calls to output plugin. # But as we were using TimeStub, the flow should have aborted after 1 # call. self.assertEqual(LongRunningDummyHuntOutputPlugin.num_calls, 1)
def Run(self): with test_lib.FakeTime(42, increment=1): hunt_urn = self.StartHunt( description="the hunt", output_plugins=[ output_plugin.OutputPluginDescriptor( plugin_name=standard_test.FailingDummyHuntOutputPlugin. __name__) ]) self.client_ids = self.SetupClients(2) for index, client_id in enumerate(self.client_ids): self.AssignTasksToClients(client_ids=[client_id]) self.RunHunt(failrate=-1) with test_lib.FakeTime(100042 + index * 100): try: self.ProcessHuntOutputPlugins() except process_results.ResultsProcessingError: if flags.FLAGS.debug: pdb.post_mortem() self.Check("GET", "/api/hunts/%s/output-plugins/" "FailingDummyHuntOutputPlugin_0/errors" % hunt_urn.Basename(), replace={hunt_urn.Basename(): "H:123456"})
def testErrorOutputPluginStatusIsAlsoWrittenToErrorsCollection(self): failing_plugin_descriptor = output_plugin.OutputPluginDescriptor( plugin_name="FailingDummyHuntOutputPlugin") plugin_descriptor = output_plugin.OutputPluginDescriptor( plugin_name="DummyHuntOutputPlugin") hunt_urn = self.StartHunt(output_plugins=[ failing_plugin_descriptor, plugin_descriptor ]) # Run the hunt and process output plugins. self.AssignTasksToClients(self.client_ids) self.RunHunt(failrate=-1) try: self.ProcessHuntOutputPlugins() except process_results.ResultsProcessingError: pass hunt = aff4.FACTORY.Open(hunt_urn, token=self.token) status_collection = aff4.FACTORY.Open( hunt.output_plugins_status_collection_urn, token=self.token) errors_collection = aff4.FACTORY.Open( hunt.output_plugins_errors_collection_urn, token=self.token) self.assertEqual(len(errors_collection), 1) self.assertEqual(len(status_collection), 2) self.assertEqual(errors_collection[0].status, "ERROR") self.assertEqual(errors_collection[0].batch_index, 0) self.assertEqual(errors_collection[0].batch_size, 10) self.assertEqual(errors_collection[0].plugin_descriptor, failing_plugin_descriptor) self.assertEqual(errors_collection[0].summary, "Oh no!") items = sorted(status_collection, key=lambda x: x.plugin_descriptor.plugin_name) self.assertEqual(items[0].status, "SUCCESS") self.assertEqual(items[0].batch_index, 0) self.assertEqual(items[0].batch_size, 10) self.assertEqual(items[0].plugin_descriptor, plugin_descriptor) self.assertEqual(items[1].status, "ERROR") self.assertEqual(items[1].batch_index, 0) self.assertEqual(items[1].batch_size, 10) self.assertEqual(items[1].plugin_descriptor, failing_plugin_descriptor) self.assertEqual(items[1].summary, "Oh no!")
def testFlowLogsFailedOutputPluginProcessing(self): flow_urn = self.RunFlow(plugins=output_plugin.OutputPluginDescriptor( plugin_name="FailingDummyFlowOutputPlugin")) flow_obj = aff4.FACTORY.Open(flow_urn, token=self.token) log_messages = [item.log_message for item in flow_obj.GetLog()] self.assertTrue( "Plugin FailingDummyFlowOutputPlugin failed to process 1 replies " "due to: Oh no!" in log_messages)
def testFlowLogsSuccessfulOutputPluginProcessing(self): flow_urn = self.RunFlow(plugins=output_plugin.OutputPluginDescriptor( plugin_name="DummyFlowOutputPlugin")) flow_obj = aff4.FACTORY.Open(flow_urn, token=self.token) log_messages = [item.log_message for item in flow_obj.GetLog()] self.assertTrue( "Plugin DummyFlowOutputPlugin sucessfully processed 1 flow replies." in log_messages)
def testGetPluginArgsHandlesMissingPluginsCorrectly(self): descriptor = output_plugin.OutputPluginDescriptor( plugin_name="TestOutputPluginWithArgs", plugin_args=rdf_flows.FlowRunnerArgs(flow_name="GetFile")) serialized = descriptor.SerializeToString() deserialized = output_plugin.OutputPluginDescriptor() deserialized.ParseFromString(serialized) self.assertEqual(deserialized, descriptor) self.assertEqual(deserialized.GetPluginClass(), TestOutputPluginWithArgs) with utils.Stubber(output_plugin.OutputPlugin, "classes", {}): deserialized = output_plugin.OutputPluginDescriptor() deserialized.ParseFromString(serialized) self.assertTrue(deserialized.GetPluginClass(), output_plugin.UnknownOutputPlugin) # UnknownOutputPlugin should just return serialized arguments as bytes. self.assertEqual(deserialized.plugin_args, descriptor.plugin_args.SerializeToString())
def _CreateHunt(self, description): output_plugins = [ output_plugin.OutputPluginDescriptor(plugin_name="TestOutputPlugin") ] with hunts.GRRHunt.StartHunt( hunt_name=standard.GenericHunt.__name__, flow_runner_args=rdf_flows.FlowRunnerArgs(flow_name="GetFile"), output_plugins=output_plugins, description=description, client_rate=0, token=self.token) as hunt: return hunt
def testReturnsNAStatusForGenericHuntWithUnverifiableOutputPlugins(self): self.StartHunt(output_plugins=[output_plugin.OutputPluginDescriptor( plugin_name=DummyHuntOutputPlugin.__name__)]) self.AssignTasksToClients() self.RunHunt() _, prev_results = self.GetVerificationsStats() flow.GRRFlow.StartFlow(flow_name="VerifyHuntOutputPluginsCronFlow", token=self.token) _, results = self.GetVerificationsStats() self.assertEqual(results["N_A"] - prev_results.get("N_A", 0), 1)
def testRunsCorrespondingVerifierIfThereIsOne(self): self.StartHunt(output_plugins=[output_plugin.OutputPluginDescriptor( plugin_name=VerifiableDummyHuntOutputPlugin.__name__)]) self.AssignTasksToClients() self.RunHunt() _, prev_results = self.GetVerificationsStats() flow.GRRFlow.StartFlow(flow_name="VerifyHuntOutputPluginsCronFlow", token=self.token) _, results = self.GetVerificationsStats() self.assertEqual(results["SUCCESS"] - prev_results.get("SUCCESS", 0), 1)
def testRaisesIfVerifierRaises(self): self.StartHunt(output_plugins=[output_plugin.OutputPluginDescriptor( plugin_name=DummyHuntOutputPluginWithRaisingVerifier.__name__)]) self.AssignTasksToClients() self.RunHunt() prev_count, _ = self.GetVerificationsStats() self.assertRaises(standard.HuntVerificationError, flow.GRRFlow.StartFlow, flow_name="VerifyHuntOutputPluginsCronFlow", token=self.token) count, _ = self.GetVerificationsStats() self.assertEqual(count - prev_count, 0)
def ParseOption(self, option, request): # Depending on the plugin we parse a different protobuf. plugin = output_plugin.OutputPlugin.classes.get(option) if plugin and plugin.description: result = output_plugin.OutputPluginDescriptor(plugin_name=option) result.plugin_args = forms.SemanticProtoFormRenderer( plugin.args_type(), id=self.id, prefix=self.prefix).ParseArgs(request) result.plugin_args.Validate() return result
def testDoesNotCheckHuntsOutsideOfCheckRange(self): now = rdfvalue.RDFDatetime().Now() with test_lib.FakeTime(now - rdfvalue.Duration("61m"), increment=1e-6): self.StartHunt(output_plugins=[output_plugin.OutputPluginDescriptor( plugin_name=VerifiableDummyHuntOutputPlugin.__name__)]) self.AssignTasksToClients() self.RunHunt() prev_count, _ = self.GetVerificationsStats() flow.GRRFlow.StartFlow(flow_name="VerifyHuntOutputPluginsCronFlow", check_range="60m", token=self.token) count, _ = self.GetVerificationsStats() self.assertEqual(count - prev_count, 0)
def setUp(self): super(TestFlowCopy, self).setUp() # Prepare our fixture. with self.ACLChecksDisabled(): self.client_id = rdf_client.ClientURN("C.0000000000000001") test_lib.ClientFixture(self.client_id, self.token) self.RequestAndGrantClientApproval("C.0000000000000001") self.email_descriptor = output_plugin.OutputPluginDescriptor( plugin_name=email_plugin.EmailOutputPlugin.__name__, plugin_args=email_plugin.EmailOutputPluginArgs( email_address="test@localhost", emails_limit=42))
def testCreateHuntFromFlow(self): email_descriptor = output_plugin.OutputPluginDescriptor( plugin_name=email_plugin.EmailOutputPlugin.__name__, plugin_args=email_plugin.EmailOutputPluginArgs( email_address="test@localhost", emails_limit=42)) args = flows_processes.ListProcessesArgs(filename_regex="test[a-z]*", fetch_binaries=True) flow.GRRFlow.StartFlow( flow_name=flows_processes.ListProcesses.__name__, args=args, client_id=self.client_id, output_plugins=[email_descriptor], token=self.token) # Navigate to client and select newly created flow. self.Open("/#c=C.0000000000000001") self.Click("css=a[grrtarget='client.flows']") self.Click("css=td:contains('ListProcesses')") # Open wizard and check if flow arguments are copied. self.Click("css=button[name=create_hunt]") self.WaitUntilEqual("test[a-z]*", self.GetValue, "css=label:contains('Filename Regex') ~ * input") self.WaitUntil( self.IsChecked, "css=label:contains('Fetch Binaries') " "~ * input[type=checkbox]") # Go to next page and check that we did not copy the output plugins. self.Click("css=button:contains('Next')") self.WaitUntilNot(self.IsElementPresent, "css=grr-output-plugin-descriptor-form") # Nothing else to check, so finish the hunt. self.Click("css=button:contains('Next')") self.Click("css=button:contains('Next')") self.Click("css=button:contains('Create Hunt')") self.Click("css=button:contains('Done')") # Check that we get redirected to ManageHunts. self.WaitUntilEqual(1, self.GetCssCount, "css=grr-hunts-list table tbody tr") self.WaitUntilEqual(1, self.GetCssCount, "css=grr-hunts-list table tbody tr.row-selected") self.WaitUntil(self.IsTextPresent, "GenericHunt") self.WaitUntil(self.IsTextPresent, flows_processes.ListProcesses.__name__)
def setUp(self): super(TestFlowCopy, self).setUp() # Prepare our fixture. self.client_id = rdf_client.ClientURN("C.0000000000000001") # This attribute is used by StandardHuntTestMixin. self.client_ids = [self.client_id] fixture_test_lib.ClientFixture(self.client_id, self.token) self.RequestAndGrantClientApproval("C.0000000000000001") self.email_descriptor = output_plugin.OutputPluginDescriptor( plugin_name=email_plugin.EmailOutputPlugin.__name__, plugin_args=email_plugin.EmailOutputPluginArgs( email_address="test@localhost", emails_limit=42))
def Run(self): with test_lib.FakeTime(42): with self.CreateHunt( description="the hunt", output_plugins=[ output_plugin.OutputPluginDescriptor( plugin_name=DummyHuntTestOutputPlugin.__name__, plugin_args=DummyHuntTestOutputPlugin.args_type( filename_regex="blah!", fetch_binaries=True)) ]) as hunt_obj: pass self.Check("GET", "/api/hunts/%s/output-plugins" % hunt_obj.urn.Basename(), replace={hunt_obj.urn.Basename(): "H:123456"})
def testListOfCSVFilesIsNotShownWhenHuntProducedNoResults(self): with self.ACLChecksDisabled(): self.client_ids = self.SetupClients(10) # Create hunt without results. self.CreateSampleHunt(output_plugins=[ output_plugin.OutputPluginDescriptor( plugin_name=csv_plugin.CSVOutputPlugin.__name__)]) self.Open("/#main=ManageHunts") self.Click("css=td:contains('GenericHunt')") # Click the Results tab. self.Click("css=li[heading=Results]") self.WaitUntil(self.IsTextPresent, "CSV Output") self.WaitUntil(self.IsTextPresent, "Nothing was written yet")
def Run(self): email_descriptor = output_plugin.OutputPluginDescriptor( plugin_name=email_plugin.EmailOutputPlugin.__name__, plugin_args=email_plugin.EmailOutputPluginArgs( email_address="test@localhost", emails_limit=42)) with test_lib.FakeTime(42): flow_urn = flow.GRRFlow.StartFlow( flow_name=processes.ListProcesses.__name__, client_id=self.client_id, output_plugins=[email_descriptor], token=self.token) self.Check("GET", "/api/clients/%s/flows/%s/output-plugins" % ( self.client_id.Basename(), flow_urn.Basename()), replace={flow_urn.Basename(): "W:ABCDEF"})