def testCheckFlowRequestLimit(self): # Create a flow with test_lib.FakeTime(self.BASE_TIME): api_regression_test_lib.StartFlow( client_id=self.client_id, flow_cls=flow_test_lib.DummyLogFlow, token=self.token) # One day + 1s later with test_lib.FakeTime(self.BASE_TIME + 86400 + 1): api_regression_test_lib.StartFlow( client_id=self.client_id, flow_cls=flow_test_lib.DummyLogFlow, token=self.token) # Disable the dup interval checking by setting it to 0. throttler = throttle.FlowThrottler( daily_req_limit=2, dup_interval=rdfvalue.Duration("0s")) # Should succeeed, only one flow present in the 1 day window. throttler.EnforceLimits(self.client_id, self.token.username, flow_test_lib.DummyLogFlow.__name__, None, token=self.token) # Start some more flows with a different user token2 = access_control.ACLToken(username="******", reason="Running tests") api_regression_test_lib.StartFlow( client_id=self.client_id, flow_cls=flow_test_lib.DummyLogFlow, token=token2) api_regression_test_lib.StartFlow( client_id=self.client_id, flow_cls=flow_test_lib.DummyLogFlow, token=token2) # Should still succeed, since we count per-user throttler.EnforceLimits(self.client_id, self.token.username, flow_test_lib.DummyLogFlow.__name__, None, token=self.token) # Add another flow at current time api_regression_test_lib.StartFlow( client_id=self.client_id, flow_cls=flow_test_lib.DummyLogFlow, token=self.token) with self.assertRaises( throttle.DailyFlowRequestLimitExceededError): throttler.EnforceLimits(self.client_id, self.token.username, flow_test_lib.DummyLogFlow.__name__, None, token=self.token)
def Run(self): acl_test_lib.CreateUser(self.token.username) client_id = self.SetupClient(0).Basename() # Create a running mock refresh operation. flow_args = filesystem.RecursiveListDirectoryArgs() running_flow_id = api_regression_test_lib.StartFlow( client_id, filesystem.RecursiveListDirectory, flow_args=flow_args, token=self.token) # Create a mock refresh operation and complete it. finished_flow_id = api_regression_test_lib.StartFlow( client_id, filesystem.RecursiveListDirectory, flow_args=flow_args, token=self.token) # Kill flow. rdf_flow = data_store.REL_DB.LeaseFlowForProcessing( client_id, finished_flow_id, rdfvalue.DurationSeconds("5m")) flow_cls = registry.FlowRegistry.FlowClassByName( rdf_flow.flow_class_name) flow_obj = flow_cls(rdf_flow) flow_obj.Error("Fake error") data_store.REL_DB.ReleaseProcessedFlow(rdf_flow) # Create an arbitrary flow to check on 404s. non_refresh_flow_id = api_regression_test_lib.StartFlow( client_id, discovery.Interrogate, token=self.token) # Unkonwn flow ids should also cause 404s. unknown_flow_id = "F:12345678" # Check both operations. self.Check("GetVfsRefreshOperationState", args=vfs_plugin.ApiGetVfsRefreshOperationStateArgs( client_id=client_id, operation_id=running_flow_id), replace={running_flow_id: "W:ABCDEF"}) self.Check("GetVfsRefreshOperationState", args=vfs_plugin.ApiGetVfsRefreshOperationStateArgs( client_id=client_id, operation_id=finished_flow_id), replace={finished_flow_id: "W:ABCDEF"}) self.Check("GetVfsRefreshOperationState", args=vfs_plugin.ApiGetVfsRefreshOperationStateArgs( client_id=client_id, operation_id=non_refresh_flow_id), replace={non_refresh_flow_id: "W:ABCDEF"}) self.Check("GetVfsRefreshOperationState", args=vfs_plugin.ApiGetVfsRefreshOperationStateArgs( client_id=client_id, operation_id=unknown_flow_id), replace={unknown_flow_id: "W:ABCDEF"})
def Run(self): acl_test_lib.CreateUser(self.token.username) client_id = self.SetupClient(0).Basename() # Create a running mock refresh operation. flow_args = filesystem.RecursiveListDirectoryArgs() running_flow_id = api_regression_test_lib.StartFlow( client_id, filesystem.RecursiveListDirectory, flow_args=flow_args, token=self.token) # Create a mock refresh operation and complete it. finished_flow_id = api_regression_test_lib.StartFlow( client_id, filesystem.RecursiveListDirectory, flow_args=flow_args, token=self.token) self._KillFlow(client_id, finished_flow_id) # Create an arbitrary flow to check on 404s. non_refresh_flow_id = api_regression_test_lib.StartFlow( client_id, discovery.Interrogate, token=self.token) # Unkonwn flow ids should also cause 404s. unknown_flow_id = "F:12345678" # Check both operations. self.Check( "GetVfsRefreshOperationState", args=vfs_plugin.ApiGetVfsRefreshOperationStateArgs( client_id=client_id, operation_id=running_flow_id), replace={running_flow_id: "W:ABCDEF"}) self.Check( "GetVfsRefreshOperationState", args=vfs_plugin.ApiGetVfsRefreshOperationStateArgs( client_id=client_id, operation_id=finished_flow_id), replace={finished_flow_id: "W:ABCDEF"}) self.Check( "GetVfsRefreshOperationState", args=vfs_plugin.ApiGetVfsRefreshOperationStateArgs( client_id=client_id, operation_id=non_refresh_flow_id), replace={non_refresh_flow_id: "W:ABCDEF"}) self.Check( "GetVfsRefreshOperationState", args=vfs_plugin.ApiGetVfsRefreshOperationStateArgs( client_id=client_id, operation_id=unknown_flow_id), replace={unknown_flow_id: "W:ABCDEF"})
def Run(self): # Fix the time to avoid regressions. with test_lib.FakeTime(42): client_id = self.SetupClient(0).Basename() if data_store.AFF4Enabled(): # Delete the certificates as it's being regenerated every time the # client is created. with aff4.FACTORY.Open(client_id, mode="rw", token=self.token) as client_obj: client_obj.DeleteAttribute(client_obj.Schema.CERT) flow_id = api_regression_test_lib.StartFlow(client_id, discovery.Interrogate, token=self.token) replace = api_regression_test_lib.GetFlowTestReplaceDict( client_id, flow_id, "F:ABCDEF12") self.Check("GetFlow", args=flow_plugin.ApiGetFlowArgs(client_id=client_id, flow_id=flow_id), replace=replace) self._TerminateFlow(client_id, flow_id) replace = api_regression_test_lib.GetFlowTestReplaceDict( client_id, flow_id, "F:ABCDEF13") # Fetch the same flow which is now should be marked as pending # termination. self.Check("GetFlow", args=flow_plugin.ApiGetFlowArgs(client_id=client_id, flow_id=flow_id), replace=replace)
def Run(self): client_id = self.SetupClient(0).Basename() flow_id = api_regression_test_lib.StartFlow(client_id, processes.ListProcesses, token=self.token) with test_lib.FakeTime(52): self._AddLogToFlow(client_id, flow_id, "Sample message: foo.") with test_lib.FakeTime(55): self._AddLogToFlow(client_id, flow_id, "Sample message: bar.") replace = {flow_id: "W:ABCDEF"} self.Check("ListFlowLogs", args=flow_plugin.ApiListFlowLogsArgs(client_id=client_id, flow_id=flow_id), replace=replace) self.Check("ListFlowLogs", args=flow_plugin.ApiListFlowLogsArgs(client_id=client_id, flow_id=flow_id, count=1), replace=replace) self.Check("ListFlowLogs", args=flow_plugin.ApiListFlowLogsArgs(client_id=client_id, flow_id=flow_id, count=1, offset=1), replace=replace)
def testDirectLinksToFlowsTabsWorkCorrectly(self): flow_id = api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneStatEntryResult, token=self.token) base_url = "/#/clients/%s/flows/%s" % (self.client_id, flow_id) self.Open(base_url + "/requests") self.WaitUntil(self.IsElementPresent, "css=li.active[heading=Requests]") self.Open(base_url + "/results") self.WaitUntil(self.IsElementPresent, "css=li.active[heading=Results]") self.Open(base_url + "/log") self.WaitUntil(self.IsElementPresent, "css=li.active[heading=Log]") # Check that both clients/.../flows/... and clients/.../flows/.../ URLs # work. self.Open(base_url) self.WaitUntil(self.IsElementPresent, "css=li.active[heading='Flow Information']") self.Open(base_url + "/") self.WaitUntil(self.IsElementPresent, "css=li.active[heading='Flow Information']")
def testFlowOverviewGetsUpdatedWhenFlowChanges(self): f = api_regression_test_lib.StartFlow(self.client_id, gui_test_lib.RecursiveTestFlow, token=self.token) self.Open("/#/clients/%s" % self.client_id) # Ensure auto-refresh updates happen every second. self.GetJavaScriptValue( "grrUi.flow.flowOverviewDirective.setAutoRefreshInterval(1000);") # Go to the flows page without refreshing the page, so that # AUTO_REFRESH_INTERVAL_MS setting is not reset. self.Click("css=a[grrtarget='client.flows']") self.Click("css=tr:contains('%s')" % f) # Check that the flow is running. self.WaitUntil(self.IsElementPresent, "css=grr-flow-inspector dd:contains('RUNNING')") # Cancel the flow and check that the flow state gets updated. self._TerminateFlow(f) self.WaitUntil(self.IsElementPresent, "css=grr-flow-inspector dd:contains('ERROR')") self.WaitUntil( self.IsElementPresent, "css=grr-flow-inspector " "tr:contains('Status'):contains('Because I said so')")
def testDownloadFilesPanelIsShownWhenNewResultsAreAdded(self): flow_id = api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.RecursiveTestFlow, token=self.token) self._AddResultToFlow(flow_id, rdfvalue.RDFString("foo-result")) self.Open("/#/clients/%s" % self.client_id) # Ensure auto-refresh updates happen every second. self.GetJavaScriptValue( "grrUi.core.resultsCollectionDirective.setAutoRefreshInterval(1000);" ) # Go to the flows page without refreshing the page, so that # AUTO_REFRESH_INTERVAL_MS setting is not reset. self.Click("css=a[grrtarget='client.flows']") self.Click("css=tr:contains('%s')" % flow_id) self.Click("css=li[heading=Results]:not([disabled]") self.WaitUntil(self.IsElementPresent, "css=grr-results-collection td:contains('foo-result')") self.WaitUntilNot( self.IsElementPresent, "css=grr-results-collection grr-download-collection-files") stat_entry = rdf_client_fs.StatEntry(pathspec=rdf_paths.PathSpec( path="/foo/bar", pathtype=rdf_paths.PathSpec.PathType.OS)) self._AddResultToFlow(flow_id, stat_entry) self.WaitUntil( self.IsElementPresent, "css=grr-results-collection grr-download-collection-files")
def testFlowResultsTabGetsUpdatedWhenNewResultsAreAdded(self): flow_id = api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.RecursiveTestFlow, token=self.token) self._AddResultToFlow(flow_id, rdfvalue.RDFString("foo-result")) self.Open("/#/clients/%s" % self.client_id) # Ensure auto-refresh updates happen every second. self.GetJavaScriptValue( "grrUi.core.resultsCollectionDirective.setAutoRefreshInterval(1000);" ) # Go to the flows page without refreshing the page, so that # AUTO_REFRESH_INTERVAL_MS setting is not reset. self.Click("css=a[grrtarget='client.flows']") self.Click("css=tr:contains('%s')" % flow_id) self.Click("css=li[heading=Results]:not([disabled]") self.WaitUntil(self.IsElementPresent, "css=grr-results-collection td:contains('foo-result')") self.WaitUntilNot( self.IsElementPresent, "css=grr-results-collection td:contains('bar-result')") self._AddResultToFlow(flow_id, rdfvalue.RDFString("bar-result")) self.WaitUntil(self.IsElementPresent, "css=grr-results-collection td:contains('bar-result')")
def testNestedFlowsAppearCorrectlyAfterAutoRefresh(self): self.Open("/#/clients/%s" % self.client_id) # Ensure auto-refresh updates happen every second. self.GetJavaScriptValue( "grrUi.flow.flowsListDirective.setAutoRefreshInterval(1000);") flow_1 = api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneLogStatement, token=self.token) # Go to the flows page without refreshing the page, so that # AUTO_REFRESH_INTERVAL_MS setting is not reset and wait # until flow_1 is visible. self.Click("css=a[grrtarget='client.flows']") self.WaitUntil(self.IsElementPresent, "css=tr:contains('%s')" % flow_1) # Create a recursive flow_2 that will appear after auto-refresh. flow_2 = api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.RecursiveTestFlow, token=self.token) # Check that the flow we started in the background appears in the list. self.WaitUntil(self.IsElementPresent, "css=tr:contains('%s')" % flow_2) # Check that flow_2 is the row 1 (row 0 is the table header). self.WaitUntil( self.IsElementPresent, "css=grr-client-flows-list tr:nth(1):contains('%s')" % flow_2) # Click on a nested flow. self.Click("css=tr:contains('%s') span.tree_branch" % flow_2) # Check that flow_2 is still row 1 and that nested flows occupy next # rows. self.WaitUntil( self.IsElementPresent, "css=grr-client-flows-list tr:nth(1):contains('%s')" % flow_2) flow_data = api_flow.ApiGetFlowHandler().Handle( api_flow.ApiGetFlowArgs(client_id=self.client_id, flow_id=flow_2), token=self.token) for index, nested_flow in enumerate(flow_data.nested_flows): self.WaitUntil( self.IsElementPresent, "css=grr-client-flows-list tr:nth(%d):contains('%s')" % (index + 2, nested_flow.flow_id))
def testLogsCanBeOpenedByClickingOnLogsTab(self): api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneLogStatement, token=self.token) self.Open("/#/clients/%s" % self.client_id) self.Click("css=a[grrtarget='client.flows']") self.Click("css=td:contains('FlowWithOneLogStatement')") self.Click("css=li[heading=Log]") self.WaitUntil(self.IsTextPresent, "I do log.")
def testFlowListGetsUpdatedWithNewFlows(self): flow_1 = api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.RecursiveTestFlow, token=self.token) self.Open("/#/clients/%s" % self.client_id) # Ensure auto-refresh updates happen every second. self.GetJavaScriptValue( "grrUi.flow.flowsListDirective.setAutoRefreshInterval(1000);") # Go to the flows page without refreshing the page, so that # AUTO_REFRESH_INTERVAL_MS setting is not reset. self.Click("css=a[grrtarget='client.flows']") # Check that the flow list is correctly loaded. self.WaitUntil(self.IsElementPresent, "css=tr:contains('%s')" % flow_1) flow_2 = api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneLogStatement, token=self.token) # Check that the flow we started in the background appears in the list. self.WaitUntil(self.IsElementPresent, "css=tr:contains('%s')" % flow_2)
def testResultsAreDisplayedInResultsTab(self): api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneStatEntryResult, token=self.token) self.Open("/#/clients/%s" % self.client_id) self.Click("css=a[grrtarget='client.flows']") self.Click("css=td:contains('FlowWithOneStatEntryResult')") self.Click("css=li[heading=Results]") self.WaitUntil(self.IsTextPresent, "aff4:/%s/fs/os/some/unique/path" % self.client_id)
def testLogTimestampsArePresentedInUTC(self): with test_lib.FakeTime(42): api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneLogStatement, token=self.token) self.Open("/#/clients/%s" % self.client_id) self.Click("css=a[grrtarget='client.flows']") self.Click("css=td:contains('FlowWithOneLogStatement')") self.Click("css=li[heading=Log]") self.WaitUntil(self.IsTextPresent, "1970-01-01 00:00:42 UTC")
def Run(self): acl_test_lib.CreateUser(self.token.username) with test_lib.FakeTime(42): client_id = self.SetupClient(0).Basename() with test_lib.FakeTime(43): flow_id_1 = api_regression_test_lib.StartFlow( client_id, discovery.Interrogate, token=self.token) with test_lib.FakeTime(44): flow_id_2 = api_regression_test_lib.StartFlow( client_id, processes.ListProcesses, token=self.token) replace = api_regression_test_lib.GetFlowTestReplaceDict( client_id, flow_id_1, "F:ABCDEF10") replace.update( api_regression_test_lib.GetFlowTestReplaceDict( client_id, flow_id_2, "F:ABCDEF11")) self.Check("ListFlows", args=flow_plugin.ApiListFlowsArgs(client_id=client_id), replace=replace)
def testEmptyTableIsDisplayedInResultsWhenNoResults(self): # TODO(amoser): This was sync=false. api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneStatEntryResult, token=self.token) self.Open("/#/clients/%s" % self.client_id) self.Click("css=a[grrtarget='client.flows']") self.Click("css=td:contains('FlowWithOneStatEntryResult')") self.Click("css=li[heading=Results]") self.WaitUntil(self.IsElementPresent, "css=#main_bottomPane table thead " "th:contains('Value')")
def testApiExampleIsShown(self): flow_id = api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneStatEntryResult, token=self.token) self.Open("/#/clients/%s/flows/%s/api" % (self.client_id, flow_id)) self.WaitUntil(self.IsTextPresent, "HTTP (authentication details are omitted)") self.WaitUntil(self.IsTextPresent, 'curl -X POST -H "Content-Type: application/json"') self.WaitUntil(self.IsTextPresent, '"@type": "type.googleapis.com/') self.WaitUntil( self.IsTextPresent, '"name": "%s"' % gui_test_lib.FlowWithOneStatEntryResult.__name__)
def testPageTitleReflectsSelectedFlow(self): pathspec = rdf_paths.PathSpec(path=os.path.join( self.base_path, "test.plist"), pathtype=rdf_paths.PathSpec.PathType.OS) args = flows_transfer.GetFileArgs(pathspec=pathspec) flow_id = api_regression_test_lib.StartFlow(self.client_id, flows_transfer.GetFile, flow_args=args, token=self.token) self.Open("/#/clients/%s/flows/" % self.client_id) self.WaitUntilEqual("GRR | %s | Flows" % self.client_id, self.GetPageTitle) self.Click("css=td:contains('GetFile')") self.WaitUntilEqual("GRR | %s | %s" % (self.client_id, flow_id), self.GetPageTitle)
def testHashesAreDisplayedCorrectly(self): api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneHashEntryResult, token=self.token) self.Open("/#/clients/%s" % self.client_id) self.Click("css=a[grrtarget='client.flows']") self.Click("css=td:contains('FlowWithOneHashEntryResult')") self.Click("css=li[heading=Results]") self.WaitUntil( self.IsTextPresent, "9e8dc93e150021bb4752029ebbff51394aa36f069cf19901578" "e4f06017acdb5") self.WaitUntil(self.IsTextPresent, "6dd6bee591dfcb6d75eb705405302c3eab65e21a") self.WaitUntil(self.IsTextPresent, "8b0a15eefe63fd41f8dc9dee01c5cf9a")
def testOverviewIsShownForNestedFlows(self): api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.RecursiveTestFlow, token=self.token) self.Open("/#/clients/%s" % self.client_id) self.Click("css=a[grrtarget='client.flows']") # There should be a RecursiveTestFlow in the list. Expand nested flows. self.Click("css=tr:contains('RecursiveTestFlow') span.tree_branch") # Click on a nested flow. self.Click("css=tr:contains('RecursiveTestFlow'):nth(2)") # Nested flow should have Depth argument set to 1. self.WaitUntil(self.IsElementPresent, "css=td:contains('Depth') ~ td:nth(0):contains('1')") self.WaitUntil(self.IsTextPresent, "Flow ID") flow_id = self.GetText("css=dt:contains('Flow ID') ~ dd:nth(0)") self.assertGreaterEqual(len(flow_id), 8)
def testCancelFlowWorksCorrectly(self): """Tests that cancelling flows works.""" api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.RecursiveTestFlow, token=self.token) # Open client and find the flow self.Open("/") self.Type("client_query", self.client_id) self.Click("client_query_submit") self.WaitUntilEqual(self.client_id, self.GetText, "css=span[type=subject]") self.Click("css=td:contains('0001')") self.Click("css=a[grrtarget='client.flows']") self.Click("css=td:contains('RecursiveTestFlow')") self.Click("css=button[name=cancel_flow]") # The window should be updated now self.WaitUntil(self.IsTextPresent, "Cancelled in GUI")
def Run(self): client_urn = self.SetupClient(0) client_id = client_urn.Basename() with test_lib.FakeTime(42): flow_id = api_regression_test_lib.StartFlow( client_id, processes.ListProcesses, token=self.token) test_process = rdf_client.Process(name="test_process") mock = flow_test_lib.MockClient(client_id, action_mocks.ListProcessesMock( [test_process]), token=self.token) mock.Next() replace = api_regression_test_lib.GetFlowTestReplaceDict( client_id, flow_id) self.Check("ListFlowRequests", args=flow_plugin.ApiListFlowRequestsArgs( client_id=client_id, flow_id=flow_id), replace=replace)
def testChangingTabUpdatesUrl(self): flow_id = api_regression_test_lib.StartFlow( self.client_id, gui_test_lib.FlowWithOneStatEntryResult, token=self.token) base_url = "/#/clients/%s/flows/%s" % (self.client_id, flow_id) self.Open(base_url) self.Click("css=li[heading=Requests]") self.WaitUntilEqual(base_url + "/requests", self.GetCurrentUrlPath) self.Click("css=li[heading=Results]") self.WaitUntilEqual(base_url + "/results", self.GetCurrentUrlPath) self.Click("css=li[heading=Log]") self.WaitUntilEqual(base_url + "/log", self.GetCurrentUrlPath) self.Click("css=li[heading='Flow Information']") self.WaitUntilEqual(base_url, self.GetCurrentUrlPath) self.Click("css=li[heading=API]") self.WaitUntilEqual(base_url + "/api", self.GetCurrentUrlPath)
def testFlowManagement(self): """Test that scheduling flows works.""" self.Open("/") self.Type("client_query", self.client_id) self.Click("client_query_submit") self.WaitUntilEqual(self.client_id, self.GetText, "css=span[type=subject]") # Choose client 1 self.Click("css=td:contains('%s')" % self.client_id) # First screen should be the Host Information already. self.WaitUntil(self.IsTextPresent, "Host000011112222") self.Click("css=a[grrtarget='client.launchFlows']") self.Click("css=#_Processes a") self.Click("link=" + flows_processes.ListProcesses.__name__) self.WaitUntil(self.IsTextPresent, "List running processes on a system.") self.Click("css=button.Launch") self.WaitUntil(self.IsTextPresent, "Launched Flow ListProcesses") self.Click("css=#_Browser a") # Wait until the tree has expanded. self.WaitUntil(self.IsTextPresent, flows_webhistory.FirefoxHistory.__name__) # Check that we can get a file in chinese self.Click("css=#_Filesystem a") # Wait until the tree has expanded. self.WaitUntil(self.IsTextPresent, flows_filesystem.UpdateSparseImageChunks.__name__) self.Click("link=" + flows_transfer.GetFile.__name__) self.Select("css=.form-group:has(> label:contains('Pathtype')) select", "OS") self.Type("css=.form-group:has(> label:contains('Path')) input", u"/dev/c/msn[1].exe") self.Click("css=button.Launch") self.WaitUntil(self.IsTextPresent, "Launched Flow GetFile") # Test that recursive tests are shown in a tree table. api_regression_test_lib.StartFlow(self.client_id, gui_test_lib.RecursiveTestFlow, token=self.token) self.Click("css=a[grrtarget='client.flows']") # Some rows are present in the DOM but hidden because parent flow row # wasn't expanded yet. Due to this, we have to explicitly filter rows # with "visible" jQuery filter. self.WaitUntilEqual( gui_test_lib.RecursiveTestFlow.__name__, self.GetText, "css=grr-client-flows-list tr:visible:nth(1) td:nth(2)") self.WaitUntilEqual( flows_transfer.GetFile.__name__, self.GetText, "css=grr-client-flows-list tr:visible:nth(2) td:nth(2)") # Click on the first tree_closed to open it. self.Click("css=grr-client-flows-list tr:visible:nth(1) .tree_closed") self.WaitUntilEqual( gui_test_lib.RecursiveTestFlow.__name__, self.GetText, "css=grr-client-flows-list tr:visible:nth(2) td:nth(2)") # Select the requests tab self.Click("css=td:contains(GetFile)") self.Click("css=li[heading=Requests]") self.WaitUntil(self.IsElementPresent, "css=td:contains(1)") # Check that a StatFile client action was issued as part of the GetFile # flow. "Stat" matches the next state that is called. self.WaitUntil(self.IsElementPresent, "css=.tab-content td.proto_value:contains(Stat)")
def testFlowDuplicateLimit(self): # Disable the request limit checking by setting it to 0. throttler = throttle.FlowThrottler( daily_req_limit=0, dup_interval=rdfvalue.Duration("1200s")) # Running the same flow immediately should fail with test_lib.FakeTime(self.BASE_TIME): throttler.EnforceLimits(self.client_id, self.token.username, flow_test_lib.DummyLogFlow.__name__, None, token=self.token) api_regression_test_lib.StartFlow( client_id=self.client_id, flow_cls=flow_test_lib.DummyLogFlow, token=self.token) with self.assertRaises(throttle.DuplicateFlowError): throttler.EnforceLimits(self.client_id, self.token.username, flow_test_lib.DummyLogFlow.__name__, None, token=self.token) # Doing the same outside the window should work with test_lib.FakeTime(self.BASE_TIME + 1200 + 1): throttler.EnforceLimits(self.client_id, self.token.username, flow_test_lib.DummyLogFlow.__name__, None, token=self.token) api_regression_test_lib.StartFlow( client_id=self.client_id, flow_cls=flow_test_lib.DummyLogFlow, token=self.token) with self.assertRaises(throttle.DuplicateFlowError): throttler.EnforceLimits(self.client_id, self.token.username, flow_test_lib.DummyLogFlow.__name__, None, token=self.token) # Now try a flow with more complicated args args = rdf_file_finder.FileFinderArgs( paths=["/tmp/1", "/tmp/2"], action=rdf_file_finder.FileFinderAction(action_type="STAT")) with test_lib.FakeTime(self.BASE_TIME): throttler.EnforceLimits(self.client_id, self.token.username, file_finder.FileFinder.__name__, args, token=self.token) new_args = rdf_file_finder.FileFinderArgs( paths=["/tmp/1", "/tmp/2"], action=rdf_file_finder.FileFinderAction(action_type="STAT")) api_regression_test_lib.StartFlow(client_id=self.client_id, flow_cls=file_finder.FileFinder, token=self.token, flow_args=new_args) with self.assertRaises(throttle.DuplicateFlowError): throttler.EnforceLimits(self.client_id, self.token.username, file_finder.FileFinder.__name__, args, token=self.token) # Different args should succeed. args = rdf_file_finder.FileFinderArgs( paths=["/tmp/1", "/tmp/3"], action=rdf_file_finder.FileFinderAction(action_type="STAT")) throttler.EnforceLimits(self.client_id, self.token.username, file_finder.FileFinder.__name__, args, token=self.token)