def testNextTraceFramesMultipleRuns(self): runs = [ Run(id=1, date=datetime.now(), status=RunStatus.FINISHED), Run(id=2, date=datetime.now(), status=RunStatus.FINISHED), ] trace_frames_run1 = self._basic_trace_frames() trace_frames_run2 = self._basic_trace_frames() trace_frames_run2[0].id = 3 trace_frames_run2[0].run_id = 2 trace_frames_run2[1].id = 4 trace_frames_run2[1].run_id = 2 sink = SharedText(id=1, contents="sink1", kind=SharedTextKind.SINK) assocs = [ TraceFrameLeafAssoc(trace_frame_id=2, leaf_id=1, trace_length=0), TraceFrameLeafAssoc(trace_frame_id=4, leaf_id=1, trace_length=0), ] with self.db.make_session() as session: self._add_to_session(session, trace_frames_run1) self._add_to_session(session, trace_frames_run2) self._add_to_session(session, runs) self._add_to_session(session, assocs) session.add(sink) session.commit() self.interactive.setup() self.interactive.sinks = {"sink1"} next_frames = self.interactive._next_trace_frames( session, trace_frames_run2[0] ) self.assertEqual(len(next_frames), 1) self.assertEqual(int(next_frames[0].id), int(trace_frames_run2[1].id))
def testListIssuesFromLatestRun(self): issue = self._generic_issue() message = SharedText(id=1, contents="message1") runs = [ Run(id=1, date=datetime.now(), status=RunStatus.FINISHED), Run(id=2, date=datetime.now(), status=RunStatus.FINISHED), ] issue_instances = [ self._generic_issue_instance(id=1, run_id=1), self._generic_issue_instance(id=2, run_id=2), ] with self.db.make_session() as session: session.add(issue) session.add(message) self._add_to_session(session, runs) self._add_to_session(session, issue_instances) session.commit() self.interactive.setup() self.interactive.issues() output = self.stdout.getvalue().strip() self.assertNotIn("Issue 1", output) self.assertIn("Issue 2", output)
def testListIssuesBasic(self): issues = [ self._generic_issue(id=1, callable="module.function1"), self._generic_issue(id=2, callable="module.function2"), ] message = SharedText(id=1, contents="message1") run = Run(id=1, date=datetime.now()) issue_instance = self._generic_issue_instance() with self.db.make_session() as session: self._add_to_session(session, issues) session.add(message) session.add(run) session.add(issue_instance) session.commit() self.interactive.setup() self.interactive.issues() output = self.stdout.getvalue().strip() self.assertIn("Issue 1", output) self.assertIn("Code: 1000", output) self.assertIn("Message: message1", output) self.assertIn("Callable: module.function1", output) self.assertIn("Location: file.py:1|2|3", output) self.assertNotIn("module.function2", output)
def testSetIssue(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) issue = self._generic_issue() issue_instances = [ self._generic_issue_instance(id=1, run_id=1), self._generic_issue_instance(id=2, run_id=2), self._generic_issue_instance(id=3, run_id=3), ] with self.db.make_session() as session: session.add(run) session.add(issue) self._add_to_session(session, issue_instances) session.commit() self.interactive.setup() self.interactive.set_issue(2) self.interactive.show() stdout = self.stdout.getvalue().strip() self.assertNotIn("Issue 1", stdout) self.assertIn("Issue 2", stdout) self.assertNotIn("Issue 3", stdout) self.interactive.set_issue(1) self.interactive.show() stdout = self.stdout.getvalue().strip() self.assertIn("Issue 1", stdout) self.assertNotIn("Issue 3", stdout)
def testPager(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) issue = self._generic_issue() issue_instance = self._generic_issue_instance() with self.db.make_session() as session: session.add(run) session.add(issue) session.add(issue_instance) session.commit() # Default is no pager in tests self.pager_calls = 0 with patch("IPython.core.page.page", self.mock_pager): self.interactive.setup() self.interactive.issues() self.interactive.runs() self.assertEqual(self.pager_calls, 0) self.pager_calls = 0 with patch("IPython.core.page.page", self.mock_pager): self.interactive.setup() self.interactive.issues(use_pager=True) self.interactive.runs(use_pager=True) self.assertEqual(self.pager_calls, 2)
def testSetRunNonExistent(self): runs = [ Run(id=1, date=datetime.now(), status=RunStatus.FINISHED), Run(id=2, date=datetime.now(), status=RunStatus.INCOMPLETE), ] with self.db.make_session() as session: self._add_to_session(session, runs) session.commit() self.interactive.setup() self.interactive.set_run(2) self.interactive.set_run(3) stderr = self.stderr.getvalue().strip() self.assertIn("Run 2 doesn't exist", stderr) self.assertIn("Run 3 doesn't exist", stderr)
def testListRuns(self): runs = [ Run(id=1, date=datetime.now(), status=RunStatus.FINISHED), Run(id=2, date=datetime.now(), status=RunStatus.INCOMPLETE), Run(id=3, date=datetime.now(), status=RunStatus.FINISHED), ] with self.db.make_session() as session: self._add_to_session(session, runs) session.commit() self.interactive.setup() self.interactive.runs() output = self.stdout.getvalue().strip() self.assertIn("Run 1", output) self.assertNotIn("Run 2", output) self.assertIn("Run 3", output)
def testTraceCursorLocation(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) issue = self._generic_issue() issue_instance = self._generic_issue_instance() trace_frames = [ TraceFrame( id=1, kind=TraceKind.POSTCONDITION, caller="call1", caller_port="root", callee="leaf", callee_port="source", callee_location=SourceLocation(1, 1), filename="file.py", run_id=1, ), TraceFrame( id=2, kind=TraceKind.PRECONDITION, caller="call1", caller_port="root", callee="leaf", callee_port="sink", callee_location=SourceLocation(1, 2), filename="file.py", run_id=1, ), ] assocs = [ IssueInstanceTraceFrameAssoc(trace_frame_id=1, issue_instance_id=1), IssueInstanceTraceFrameAssoc(trace_frame_id=2, issue_instance_id=1), TraceFrameLeafAssoc(trace_frame_id=1, leaf_id=1), TraceFrameLeafAssoc(trace_frame_id=2, leaf_id=1), ] with self.db.make_session() as session: session.add(run) session.add(issue) session.add(issue_instance) self._add_to_session(session, trace_frames) self._add_to_session(session, assocs) session.commit() self.interactive.setup() self.interactive.set_issue(1) self.assertEqual(self.interactive.current_trace_frame_index, 1) self.interactive.next_cursor_location() self.assertEqual(self.interactive.current_trace_frame_index, 2) self.interactive.next_cursor_location() self.assertEqual(self.interactive.current_trace_frame_index, 2) self.interactive.prev_cursor_location() self.assertEqual(self.interactive.current_trace_frame_index, 1) self.interactive.prev_cursor_location() self.assertEqual(self.interactive.current_trace_frame_index, 0) self.interactive.prev_cursor_location() self.assertEqual(self.interactive.current_trace_frame_index, 0)
def testTrace(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) issue = self._generic_issue() issue_instance = self._generic_issue_instance() trace_frames = [ TraceFrame( id=1, kind=TraceKind.POSTCONDITION, caller="call1", caller_port="root", callee="leaf", callee_port="source", callee_location=SourceLocation(1, 1, 1), filename="file.py", run_id=1, ), TraceFrame( id=2, kind=TraceKind.PRECONDITION, caller="call1", caller_port="root", callee="leaf", callee_port="sink", callee_location=SourceLocation(1, 1, 2), filename="file.py", run_id=1, ), ] assocs = [ IssueInstanceTraceFrameAssoc(trace_frame_id=1, issue_instance_id=1), IssueInstanceTraceFrameAssoc(trace_frame_id=2, issue_instance_id=1), TraceFrameLeafAssoc(trace_frame_id=1, leaf_id=1), TraceFrameLeafAssoc(trace_frame_id=2, leaf_id=1), ] with self.db.make_session() as session: session.add(run) session.add(issue) session.add(issue_instance) self._add_to_session(session, trace_frames) self._add_to_session(session, assocs) session.commit() self.interactive.setup() self.interactive.trace() stderr = self.stderr.getvalue().strip() self.assertIn("Use 'set_issue(ID)' to select an issue first.", stderr) self.interactive.set_issue(1) self.interactive.trace() output = self.stdout.getvalue().strip() self.assertIn(" leaf source file.py:1|1|1", output) self.assertIn(" --> call1 root file.py:1|2|3", output) self.assertIn(" leaf sink file.py:1|1|2", output)
def testSetIssueNonExistent(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) with self.db.make_session() as session: session.add(run) session.commit() self.interactive.setup() self.interactive.set_issue(1) stderr = self.stderr.getvalue().strip() self.assertIn("Issue 1 doesn't exist", stderr)
def testTraceMissingFrames(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) issue = self._generic_issue() issue_instance = self._generic_issue_instance() trace_frames = [ TraceFrame( id=1, kind=TraceKind.POSTCONDITION, caller="call1", caller_port="root", callee="leaf", callee_port="source", callee_location=SourceLocation(1, 1, 1), filename="file.py", run_id=1, ), TraceFrame( id=2, kind=TraceKind.PRECONDITION, caller="call1", caller_port="root", callee="call2", callee_port="param0", callee_location=SourceLocation(1, 1, 1), filename="file.py", run_id=1, ), ] assocs = [ IssueInstanceTraceFrameAssoc(trace_frame_id=1, issue_instance_id=1), IssueInstanceTraceFrameAssoc(trace_frame_id=2, issue_instance_id=1), TraceFrameLeafAssoc(trace_frame_id=1, leaf_id=1), TraceFrameLeafAssoc(trace_frame_id=2, leaf_id=1), ] with self.db.make_session() as session: session.add(run) session.add(issue) session.add(issue_instance) self._add_to_session(session, trace_frames) self._add_to_session(session, assocs) session.commit() self.interactive.setup() self.interactive.set_issue(1) self.interactive.trace() stdout = self.stdout.getvalue().strip() self.assertIn("Missing trace frame: call2:param0", stdout)
def _create_empty_run(self, status=RunStatus.FINISHED, status_description=None) -> Run: """setting boilerplate when creating a Run object""" run = Run( job_id=self.summary["job_id"], issue_instances=[], date=datetime.datetime.now(), status=status, status_description=status_description, repository=self.summary["repository"], branch=self.summary["branch"], commit_hash=self.summary["commit_hash"], kind=self.summary["run_kind"], ) return run
def testNextTraceFrames(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) trace_frames = self._basic_trace_frames() sink = SharedText(id=1, contents="sink1", kind=SharedTextKind.SINK) assoc = TraceFrameLeafAssoc(trace_frame_id=2, leaf_id=1, trace_length=1) with self.db.make_session() as session: self._add_to_session(session, trace_frames) session.add(run) session.add(sink) session.add(assoc) session.commit() self.interactive.setup() self.interactive.sinks = {"sink1"} next_frames = self.interactive._next_trace_frames(session, trace_frames[0]) self.assertEqual(len(next_frames), 1) self.assertEqual(int(next_frames[0].id), int(trace_frames[1].id))
def testTraceNoSinks(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) issue = self._generic_issue() issue_instance = self._generic_issue_instance() trace_frame = TraceFrame( id=1, kind=TraceKind.POSTCONDITION, caller="call1", caller_port="root", callee="leaf", callee_port="source", callee_location=SourceLocation(1, 1), filename="file.py", run_id=1, ) source = SharedText(id=1, contents="source1", kind=SharedTextKind.SOURCE) assocs = [ IssueInstanceTraceFrameAssoc(trace_frame_id=1, issue_instance_id=1), TraceFrameLeafAssoc(trace_frame_id=1, leaf_id=1), ] with self.db.make_session() as session: session.add(run) session.add(issue) session.add(issue_instance) session.add(trace_frame) session.add(source) self._add_to_session(session, assocs) session.commit() self.interactive.setup() self.interactive.sources = {"source1"} self.interactive.set_issue(1) self._clear_stdout() self.interactive.trace() self.assertEqual( self.stdout.getvalue().split("\n"), [ " [branches] [callable] [port] [location]", " leaf source file.py:1|1|1", " --> call1 root file.py:1|2|3", "", ], )
def _list_issues_filter_setup(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) issues = [ self._generic_issue( id=1, callable="module.sub.function1", filename="module/sub.py" ), self._generic_issue( id=2, callable="module.sub.function2", filename="module/sub.py" ), self._generic_issue( id=3, callable="module.function3", filename="module/__init__.py" ), ] issue_instances = [ self._generic_issue_instance(id=1, issue_id=1), self._generic_issue_instance(id=2, issue_id=2), self._generic_issue_instance(id=3, issue_id=3), ] with self.db.make_session() as session: session.add(run) self._add_to_session(session, issues) self._add_to_session(session, issue_instances) session.commit()
def testBranchPrefixLengthChanges(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) issue = self._generic_issue() issue_instance = self._generic_issue_instance() messages = [ SharedText(id=1, contents="source1", kind=SharedTextKind.SOURCE), SharedText(id=2, contents="sink1", kind=SharedTextKind.SINK), ] trace_frames = [ TraceFrame( id=1, kind=TraceKind.POSTCONDITION, caller="call1", caller_port="root", callee="leaf", callee_port="source", callee_location=SourceLocation(1, 1), filename="file.py", run_id=1, ), TraceFrame( id=2, kind=TraceKind.POSTCONDITION, caller="call1", caller_port="root", callee="prev_call", callee_port="result", callee_location=SourceLocation(1, 1), filename="file.py", run_id=1, ), TraceFrame( id=3, kind=TraceKind.POSTCONDITION, caller="prev_call", caller_port="result", callee="leaf", callee_port="source", callee_location=SourceLocation(1, 1), filename="file.py", run_id=1, ), TraceFrame( id=4, kind=TraceKind.PRECONDITION, caller="call1", caller_port="root", callee="leaf", callee_port="sink", callee_location=SourceLocation(1, 2), filename="file.py", run_id=1, ), ] assocs = [ IssueInstanceSharedTextAssoc(issue_instance_id=1, shared_text_id=1), IssueInstanceSharedTextAssoc(issue_instance_id=1, shared_text_id=2), IssueInstanceTraceFrameAssoc(issue_instance_id=1, trace_frame_id=1), IssueInstanceTraceFrameAssoc(issue_instance_id=1, trace_frame_id=2), IssueInstanceTraceFrameAssoc(issue_instance_id=1, trace_frame_id=4), TraceFrameLeafAssoc(trace_frame_id=1, leaf_id=1, trace_length=0), TraceFrameLeafAssoc(trace_frame_id=2, leaf_id=1, trace_length=1), TraceFrameLeafAssoc(trace_frame_id=3, leaf_id=1, trace_length=0), TraceFrameLeafAssoc(trace_frame_id=4, leaf_id=2, trace_length=0), ] with self.db.make_session() as session: session.add(run) session.add(issue) session.add(issue_instance) self._add_to_session(session, messages) self._add_to_session(session, trace_frames) self._add_to_session(session, assocs) session.commit() self.interactive.setup() self.interactive.set_issue(1) self._clear_stdout() self.interactive.prev_cursor_location() self.assertEqual( self.stdout.getvalue().split("\n"), [ " [branches] [callable] [port] [location]", " --> + 2 leaf source file.py:1|1|1", " call1 root file.py:1|2|3", " leaf sink file.py:1|2|2", "", ], ) self._clear_stdout() self.interactive.branch(1) self.assertEqual( self.stdout.getvalue().split("\n"), [ " [branches] [callable] [port] [location]", " leaf source file.py:1|1|1", " --> + 2 prev_call result file.py:1|1|1", " call1 root file.py:1|2|3", " leaf sink file.py:1|2|2", "", ], ) self._clear_stdout() self.interactive.expand() output = self.stdout.getvalue().strip() self.assertIn("[*] prev_call : result", output) self.assertIn(" [1 hops: source1]", output)
def _set_up_branched_trace(self): run = Run(id=1, date=datetime.now(), status=RunStatus.FINISHED) issue = self._generic_issue() issue_instance = self._generic_issue_instance() messages = [ SharedText(id=1, contents="source1", kind=SharedTextKind.SOURCE), SharedText(id=2, contents="sink1", kind=SharedTextKind.SINK), ] trace_frames = [] assocs = [ IssueInstanceSharedTextAssoc(issue_instance_id=1, shared_text_id=1), IssueInstanceSharedTextAssoc(issue_instance_id=1, shared_text_id=2), ] for i in range(6): trace_frames.append( TraceFrame( id=i + 1, caller="call1", caller_port="root", filename="file.py", callee_location=SourceLocation(i, i, i), run_id=1, ) ) if i < 2: # 2 postconditions trace_frames[i].kind = TraceKind.POSTCONDITION trace_frames[i].callee = "leaf" trace_frames[i].callee_port = "source" assocs.append( TraceFrameLeafAssoc(trace_frame_id=i + 1, leaf_id=1, trace_length=0) ) assocs.append( IssueInstanceTraceFrameAssoc( trace_frame_id=i + 1, issue_instance_id=1 ) ) elif i < 4: trace_frames[i].kind = TraceKind.PRECONDITION trace_frames[i].callee = "call2" trace_frames[i].callee_port = "param2" assocs.append( TraceFrameLeafAssoc(trace_frame_id=i + 1, leaf_id=2, trace_length=1) ) assocs.append( IssueInstanceTraceFrameAssoc( trace_frame_id=i + 1, issue_instance_id=1 ) ) else: trace_frames[i].kind = TraceKind.PRECONDITION trace_frames[i].caller = "call2" trace_frames[i].caller_port = "param2" trace_frames[i].callee = "leaf" trace_frames[i].callee_port = "sink" assocs.append( TraceFrameLeafAssoc(trace_frame_id=i + 1, leaf_id=2, trace_length=0) ) with self.db.make_session() as session: session.add(run) session.add(issue) session.add(issue_instance) self._add_to_session(session, messages) self._add_to_session(session, trace_frames) self._add_to_session(session, assocs) session.commit()