def test_nr_of_warnings_and_report_is_requested(self): """Test that the number of security warnings is returned.""" get_response = Mock() get_response.json.side_effect = [[dict(name="project", id="id")], [dict(id=1000)], dict(status=dict(value="In Process")), dict(highSeverity=1, mediumSeverity=2, lowSeverity=3, infoSeverity=4), [dict(name="project", id="id")]] post_response = Mock() post_response.json.side_effect = [ dict(access_token="token"), dict(access_token="token"), dict(reportId=1) ] with patch("requests.post", return_value=post_response): with patch("requests.get", return_value=get_response): collector = MetricCollector(self.metric) response = collector.get() self.assertEqual("10", response["sources"][0]["value"]) self.assertEqual([], response["sources"][0]["entities"]) self.assertEqual(1, CxSASTSecurityWarnings.CXSAST_SCAN_REPORTS[1000]) self.assertEqual(datetime.min, collector.next_collection())
def test_no_issues(self): """Test zero issues.""" self.mock_response.json.return_value = dict(workItems=[]) with patch("requests.post", return_value=self.mock_response): with patch("requests.get", return_value=self.mock_entity_response): response = MetricCollector(self.metric).get() self.assertEqual("0", response["sources"][0]["value"])
def test_source_up_to_dateness(self): """Test the number of days since the user-specified date.""" metric = dict( type="source_up_to_dateness", addition="max", sources=dict(a=dict(type="calendar", parameters=dict(date="2019-01-01")))) response = MetricCollector(metric).get() self.assertEqual(str((datetime.now() - datetime(2019, 1, 1)).days), response["sources"][0]["value"])
def test_uncovered_branches(self): """Test that the number of uncovered branches is returned.""" self.mock_response.text = "<report><counter type='BRANCH' missed='4' /></report>" metric = dict(type="uncovered_branches", sources=self.sources, addition="sum") with patch("requests.get", return_value=self.mock_response): response = MetricCollector(metric).get() self.assertEqual("4", response["sources"][0]["value"])
def test_unmerged_branches(self): """Test that the number of unmerged branches can be measured.""" sources = dict(source_id=dict(type="gitlab", parameters=dict(url="http://gitlab/", private_token="token", project="project", inactive_days="7"))) metric = dict(type="unmerged_branches", sources=sources, addition="sum") mock_response = Mock() mock_response.json.return_value = [ dict(name="master", merged=False), dict(name="unmerged_branch", merged=False, commit=dict(committed_date="2019-04-02T11:33:04.000+02:00")), dict(name="active_unmerged_branch", merged=False, commit=dict( committed_date=datetime.now(timezone.utc).isoformat())), dict(name="merged_branch", merged=True) ] with patch("requests.get", return_value=mock_response): response = MetricCollector(metric).get() self.assertEqual("1", response["sources"][0]["value"]) expected_age = str( (datetime.now(timezone.utc) - datetime(2019, 4, 2, 9, 33, 4, tzinfo=(timezone.utc))).days) self.assertEqual([ dict(key="unmerged_branch", name="unmerged_branch", commit_age=expected_age, commit_date="2019-04-02") ], response["sources"][0]["entities"])
def test_age(self): """Test that the source up to dateness is the number of days since the most recent change.""" metric = dict( type="source_up_to_dateness", addition="max", sources=dict(source_id=dict(type="trello", parameters=dict(url="http://trello", board="board1", api_key="abcdef123", token="4533dea")))) mock_get_response = Mock() cards = dict(id="board1", url="http://trello/board1", dateLastActivity="2019-02-10", cards=[ dict(id="card1", name="Card 1", dateLastActivity="2019-03-03"), dict(id="card2", name="Card 2", dateLastActivity="2019-01-01") ]) mock_get_response.json.side_effect = [[ dict(id="board1", name="Board1") ], cards, cards] with patch("requests.get", return_value=mock_get_response): response = MetricCollector(metric).get() self.assertEqual(str((datetime.now() - datetime(2019, 1, 1)).days), response["sources"][0]["value"])
def test_low_warnings(self): """Test that the number of warnings is returned.""" self.mock_response.text = """<?xml version="1.0"?> <analysis xmlns="https://jeremylong.github.io/DependencyCheck/dependency-check.2.0.xsd"> <dependency isVirtual="false"> <sha1>12345</sha1> <fileName>jquery.min.js</fileName> <filePath>/home/jenkins/workspace/hackazon-owaspdep/hackazon/js/jquery.min.js</filePath> <vulnerabilities> <vulnerability source="NVD"> <cvssV2> <severity>LOW</severity> </cvssV2> </vulnerability> </vulnerabilities> </dependency> </analysis>""" metric = dict(type="security_warnings", addition="sum", sources=self.sources) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(metric).get() self.assertEqual([ dict( key="12345", url="http://owasp_dependency_check.html#l1_12345", highest_severity="Low", nr_vulnerabilities=1, file_path= "/home/jenkins/workspace/hackazon-owaspdep/hackazon/js/jquery.min.js" ) ], response["sources"][0]["entities"]) self.assertEqual("1", response["sources"][0]["value"])
def test_unbuild_job(self): """Test that jobs without builds are ignored.""" self.mock_response.json.return_value = dict( jobs=[dict(name="job", url="http://job", buildable=True, color="red")]) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(self.metric).get() self.assertEqual("0", response["sources"][0]["value"])
def test_warnings(self): """Test that the number of warnings is returned.""" self.mock_response.text = """<?xml version="1.0"?> <report> <results> <result id="id"> <name>Name</name> <description>Description</description> <threat>Low</threat> <host>1.2.3.4</host> <port>80/tcp</port> </result> </results> </report>""" metric = dict(type="security_warnings", addition="sum", sources=self.sources) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(metric).get() self.assertEqual([ dict(key="id", severity="Low", name="Name", description="Description", host="1.2.3.4", port="80/tcp") ], response["sources"][0]["entities"]) self.assertEqual("1", response["sources"][0]["value"])
def test_source_up_to_dateness(self): """Test that the age of a file in a repo can be measured.""" sources = dict(source_id=dict(type="gitlab", parameters=dict(url="http://gitlab/", private_token="token", project="project", file_path="file", branch="branch"))) metric = dict(type="source_up_to_dateness", sources=sources, addition="sum") get_response = Mock() get_response.json.return_value = dict( committed_date="2019-01-01T09:06:12+00:00") head_response = Mock() head_response.headers = {"X-Gitlab-Last-Commit-Id": "commit-sha"} with patch("requests.head", return_value=head_response): with patch("requests.get", return_value=get_response): response = MetricCollector(metric).get() expected_age = ( datetime.now(timezone.utc) - datetime(2019, 1, 1, 9, 6, 9, tzinfo=timezone.utc)).days self.assertEqual(str(expected_age), response["sources"][0]["value"]) self.assertEqual("http://gitlab/project/blob/branch/file", response["sources"][0]["landing_url"])
def test_filter_violations(self): """Test that violations of types the user doesn't want to see are not included.""" mock_response = Mock() mock_response.text = """<audit xmlns="http://xmlns.oracle.com/jdeveloper/1013/audit"> <violation-count>1</violation-count> <high-count>0</high-count> <medium-count>1</medium-count> <models> <model id="a"> <file> <path>a</path> </file> </model> </models> <construct> <violation> <message>a</message> <location model="a"> <line-number>20</line-number> <column-offset>4</column-offset> </location> <values> <value>medium</value> </values> </violation> </construct> </audit>""" self.metric["sources"]["a"]["parameters"]["severities"] = ["high"] with patch("requests.get", return_value=mock_response): response = MetricCollector(self.metric).get() self.assertEqual("0", response["sources"][0]["value"]) self.assertEqual([], response["sources"][0]["entities"])
def test_missing_location(self): """Test that an exception is raised if the violation location is missing.""" mock_response = Mock() mock_response.text = """<audit xmlns="http://xmlns.oracle.com/jdeveloper/1013/audit"> <violation-count>2</violation-count> <models> <model id="a"> <file> <path>a</path> </file> </model> <model id="b"> <file> <path>b</path> </file> </model> </models> <construct> <violation> <message>a</message> <values> <value>medium</value> </values> </violation> </construct> </audit>""" with patch("requests.get", return_value=mock_response): self.assertTrue("has no location element" in MetricCollector( self.metric).get()["sources"][0]["parse_error"])
def test_no_builds(self): """Test no builds.""" self.mock_response.json.return_value = dict( jobs=[dict(name="job", url="http://job", buildable=True, color="notbuilt", builds=[])]) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(self.metric).get() self.assertEqual([], response["sources"][0]["entities"])
def test_issues(self): """Test that the number of issues and the individual issues are returned.""" cards = dict(id="board1", url="http://trello/board1", cards=[ dict(id="card1", name="Card 1", idList="list1", due=None, dateLastActivity="2019-01-01", url="http://trello/card1") ], lists=[dict(id="list1", name="List 1")]) self.mock_get_response.json.side_effect = [[ dict(id="board1", name="Board1") ], cards, cards, cards] with patch("requests.get", return_value=self.mock_get_response): response = MetricCollector(self.metric).get() self.assertEqual("1", response["sources"][0]["value"]) self.assertEqual([ dict(key="card1", url="http://trello/card1", title="Card 1", list="List 1", due_date=None, date_last_activity="2019-01-01") ], response["sources"][0]["entities"])
def test_violations(self): """Test that the number of violations is returned.""" mock_response = Mock() mock_response.text = """<audit xmlns="http://xmlns.oracle.com/jdeveloper/1013/audit"> <violation-count>2</violation-count> <models> <model id="a"> <file> <path>a</path> </file> </model> <model id="b"> <file> <path>b</path> </file> </model> </models> <construct> <children> <construct> <children> <violation> <message>a</message> <location model="a"> <line-number>20</line-number> <column-offset>4</column-offset> </location> <values> <value>warning</value> </values> </violation> </children> </construct> <violation> <message>b</message> <location model="b"> <line-number>10</line-number> <column-offset>2</column-offset> </location> <values> <value>exception</value> </values> </violation> </children> </construct> </audit>""" with patch("requests.get", return_value=mock_response): response = MetricCollector(self.metric).get() self.assertEqual([ dict(component="a:20:4", key="894756a0231a17f66b33d0ac18570daa193beea3", message="a", severity="warning"), dict(component="b:10:2", key="2bdb532d49f0bf2252e85dc2d41e034c8c3e1af3", message="b", severity="exception") ], response["sources"][0]["entities"]) self.assertEqual("2", response["sources"][0]["value"])
def test_violations(self): """Test the number of violations.""" metric = dict(type="violations", addition="sum", sources=dict(a=dict(type="random"))) response = MetricCollector(metric).get() self.assertTrue( Random.min <= int(response["sources"][0]["value"]) <= Random.max)
def test_story_points_without_stories(self): """Test that the number of story points is zero when there are no work items.""" self.mock_response.json.return_value = dict(workItems=[]) self.mock_entity_response.json.return_value = dict(value=[]) with patch("requests.post", return_value=self.mock_response): with patch("requests.get", return_value=self.mock_entity_response): response = MetricCollector(self.metric).get() self.assertEqual("0", response["sources"][0]["value"])
def test_long_units(self): """Test that the number of long units is returned.""" self.sources["a"]["parameters"]["rules"] = ["rule1"] self.mock_response.json.return_value = dict(total="2", issues=[]) metric = dict(type="long_units", addition="sum", sources=self.sources) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(metric).get() self.assertEqual("2", response["sources"][0]["value"])
def test_uncovered_branches(self): """Test that the number of uncovered branches is returned.""" self.mock_response.json.return_value = dict( component=dict(measures=[dict(metric="uncovered_conditions", value="10")])) metric = dict(type="uncovered_branches", addition="sum", sources=self.sources) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(metric).get() self.assertEqual("10", response["sources"][0]["value"])
def test_parse_error(self): """Test that an error retrieving the data is handled.""" mock_response = Mock() mock_response.text = "1" with patch("requests.get", return_value=mock_response): response = MetricCollector(self.metric).get() self.assertTrue( response["sources"][0]["parse_error"].startswith("Traceback"))
def test_nr_of_failed_jobs_without_failed_jobs(self): """Test that the number of failed jobs is returned.""" self.mock_response.json.return_value = [ dict(name="job", url="http://job", status="success") ] with patch("requests.get", return_value=self.mock_response): response = MetricCollector(self.metric).get() self.assertEqual("0", response["sources"][0]["value"])
def test_unused_jobs(self): """Test that the number of unused jobs is returned.""" self.mock_response.json.return_value = dict( jobs=[dict( name="job", url="http://job", buildable=True, color="red", builds=[dict(timestamp="1548311610349")])]) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(self.metric).get() self.assertEqual("1", response["sources"][0]["value"])
def test_nr_story_points(self): """Test that the number of story points is returned.""" self.mock_response.json.return_value = dict(issues=[ dict(key="1", id="1", fields=dict(summary="summary 1", field=10)), dict(key="2", id="2", fields=dict(summary="summary 2", field=32)) ]) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(self.metric).get() self.assertEqual("42", response["sources"][0]["value"])
def test_source_up_to_dateness(self): """Test that the number of days since the last analysis is returned.""" self.mock_response.json.return_value = dict(analyses=[dict(date="2019-03-29T14:20:15+0100")]) metric = dict(type="source_up_to_dateness", addition="max", sources=self.sources) tzinfo = timezone(timedelta(hours=1)) expected_age = (datetime.now(tzinfo) - datetime(2019, 3, 29, 14, 20, 15, tzinfo=tzinfo)).days with patch("requests.get", return_value=self.mock_response): response = MetricCollector(metric).get() self.assertEqual(str(expected_age), response["sources"][0]["value"])
def test_no_transactions(self): """Test that the number of slow transactions is 0 if there are no transactions in the details table.""" self.mock_response.text = '<html><table class="details"><tr></tr></table></html>' metric = dict(type="slow_transactions", sources=self.sources, addition="sum") with patch("requests.get", return_value=self.mock_response): response = MetricCollector(metric).get() self.assertEqual("0", response["sources"][0]["value"])
def test_failed_tests_entities(self): """Test that the failed tests are returned as entities.""" self.mock_response.text = """<testsuites><testsuite failures="1"><testcase name="tc" classname="cn"><failure/> </testcase></testsuite></testsuites>""" with patch("requests.get", return_value=self.mock_response): response = MetricCollector(self.metric).get() self.assertEqual([ dict(key="tc", name="tc", class_name="cn", failure_type="failed") ], response["sources"][0]["entities"])
def test_nr_of_failed_jobs(self): """Test that the number of failed jobs is returned.""" self.mock_response.json.return_value = dict( jobs=[dict(name="job", url="http://job", buildable=True, color="red", builds=[dict(result="red")], jobs=[dict(name="child_job", url="http://child_job", buildable=True, color="red", builds=[dict(result="red")])])]) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(self.metric).get() self.assertEqual("2", response["sources"][0]["value"])
def test_source_up_to_dateness(self): """Test that the source age in days is returned.""" self.mock_response.text = """<?xml version="1.0"?> <OWASPZAPReport version="2.7.0" generated="Thu, 28 Mar 2019 13:20:20"> </OWASPZAPReport>""" metric = dict(type="source_up_to_dateness", addition="max", sources=self.sources) with patch("requests.get", return_value=self.mock_response): response = MetricCollector(metric).get() expected_age = (datetime.now() - datetime(2019, 3, 28, 13, 20, 20)).days self.assertEqual(str(expected_age), response["sources"][0]["value"])
def test_nr_of_tests(self): """Test that the number of tests is returned.""" mock_response = Mock() mock_response.json = Mock(return_value=dict(passCount=4, failCount=2)) metric = dict( type="tests", addition="sum", sources=dict(source_id=dict(type="jenkins_test_report", parameters=dict(url="http://jenkins/jobjob")))) with patch("requests.get", return_value=mock_response): response = MetricCollector(metric).get() self.assertEqual("6", response["sources"][0]["value"])
def test_story_points(self): """Test that the number of story points are returned.""" self.mock_response.json.return_value = dict( workItems=[dict(id="id1"), dict(id="id2")]) self.mock_entity_response.json.return_value = dict( value=[self.work_item, self.work_item]) with patch("requests.post", return_value=self.mock_response): with patch("requests.get", return_value=self.mock_entity_response): response = MetricCollector(self.metric).get() self.assertEqual("4", response["sources"][0]["value"])