5 @pytest.fixture(scope
='function', autouse
=True)
7 return sarif_from_env()
9 def test_basics(sarif
):
10 schema
= sarif
['$schema']
11 assert schema
== "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"
13 version
= sarif
['version']
14 assert version
== "2.1.0"
16 def test_execution_unsuccessful(sarif
):
20 invocations
= run
['invocations']
21 assert len(invocations
) == 1
22 invocation
= invocations
[0]
24 # We expect the errors to make executionSuccessful be false
25 assert invocation
['executionSuccessful'] == False
27 def test_location_relationships(sarif
):
30 results
= run
['results']
32 # We expect a pair of errors, each with a note, and include chains.
33 # The textual form of these four diagnostics would look like this:
34 # . In file included from PATH/include-chain-1.h:5,
35 # . from PATH/include-chain.c:9:
36 # . PATH/include-chain-1-2.h:1:6: error: conflicting types for 'p'; have 'char'
39 # . In file included from PATH/include-chain-1.h:2:
40 # . PATH/include-chain-1-1.h:1:5: note: previous declaration of 'p' with type 'int'
43 # . PATH/include-chain-1-2.h:2:6: error: conflicting types for 'q'; have 'char'
46 # . PATH/include-chain-1-1.h:2:5: note: previous declaration of 'q' with type 'int'
49 assert len(results
) == 2
52 assert result
['level'] == 'error'
53 assert result
['message']['text'] == "conflicting types for 'p'; have 'char'"
54 locations
= result
['locations']
55 assert len(locations
) == 1
57 location
= locations
[0]
58 assert 'id' in location
59 assert get_location_artifact_uri(location
).endswith('include-chain-1-2.h')
60 assert get_location_snippet_text(location
) == "char p;\n"
62 # We expect 4 related locations: one for the "note"
63 # and three for describing include chains
64 relatedLocations
= result
['relatedLocations']
65 assert len(relatedLocations
) == 4
67 # We expect a related location representing the note:
68 # . In file included from PATH/include-chain-1.h:2:
69 # . from PATH/include-chain.c:9:
70 # . PATH/include-chain-1-1.h:1:5: note: previous declaration of 'p' with type 'int'
73 note
= relatedLocations
[0]
75 assert note
['message']['text'] == "previous declaration of 'p' with type 'int'"
76 assert get_location_artifact_uri(note
).endswith('include-chain-1-1.h')
77 assert get_location_snippet_text(note
) == "int p;\n"
79 # We expect three more related locations for the two include chains
81 # The "#include "include-chain-1-2.h" line in include-chain-1.h:
82 hash_include_1_2_h
= relatedLocations
[1]
83 assert 'id' in hash_include_1_2_h
84 assert get_location_snippet_text(hash_include_1_2_h
) == '#include "include-chain-1-2.h"\n'
85 assert get_location_artifact_uri(hash_include_1_2_h
).endswith('include-chain-1.h')
87 # The "#include "include-chain-1-1.h" line in include-chain-1.h:
88 hash_include_1_1_h
= relatedLocations
[2]
89 assert 'id' in hash_include_1_1_h
90 assert get_location_snippet_text(hash_include_1_1_h
) == '#include "include-chain-1-1.h"\n'
91 assert get_location_artifact_uri(hash_include_1_1_h
).endswith('include-chain-1.h')
93 # The "#include "include-chain-1.h" line in include-chain-1.c:
94 hash_include_1_h
= relatedLocations
[3]
95 assert 'id' in hash_include_1_h
96 assert get_location_snippet_text(hash_include_1_h
) == '#include "include-chain-1.h"\n'
97 assert get_location_artifact_uri(hash_include_1_h
).endswith('include-chain-1.c')
99 # Check the various relationships; we expect a directed graph of edges
100 # representing the various "isIncludedBy" and "includes" relationships.
102 # The primary location should be "isIncludedBy" the "#include "include-chain-1-2.h" line
103 assert len(location
['relationships']) == 1
104 assert location
['relationships'][0]['target'] == hash_include_1_2_h
['id']
105 assert location
['relationships'][0]['kinds'] == ["isIncludedBy"]
107 # The note should be "isIncludedBy" the "#include "include-chain-1-1.h" line
108 assert len(note
['relationships']) == 1
109 assert note
['relationships'][0]['target'] == hash_include_1_1_h
['id']
110 assert note
['relationships'][0]['kinds'] == ["isIncludedBy"]
112 # The "#include "include-chain-1-2.h" line:
113 assert len(hash_include_1_2_h
['relationships']) == 2
114 assert hash_include_1_2_h
['relationships'][0]['target'] == location
['id']
115 assert hash_include_1_2_h
['relationships'][0]['kinds'] == ["includes"]
116 assert hash_include_1_2_h
['relationships'][1]['target'] == hash_include_1_h
['id']
117 assert hash_include_1_2_h
['relationships'][1]['kinds'] == ["isIncludedBy"]
119 # The "#include "include-chain-1-1.h" line:
120 assert len(hash_include_1_1_h
['relationships']) == 2
121 assert hash_include_1_1_h
['relationships'][0]['target'] == note
['id']
122 assert hash_include_1_1_h
['relationships'][0]['kinds'] == ["includes"]
123 assert hash_include_1_1_h
['relationships'][1]['target'] == hash_include_1_h
['id']
124 assert hash_include_1_1_h
['relationships'][1]['kinds'] == ["isIncludedBy"]
126 # The "#include "include-chain-1.h" line in include-chain-1.c:
127 assert len(hash_include_1_h
['relationships']) == 2
128 assert hash_include_1_h
['relationships'][0]['target'] == hash_include_1_2_h
['id']
129 assert hash_include_1_h
['relationships'][0]['kinds'] == ["includes"]
130 assert hash_include_1_h
['relationships'][1]['target'] == hash_include_1_1_h
['id']
131 assert hash_include_1_h
['relationships'][1]['kinds'] == ["includes"]
133 # We expect similar for the 2nd error
134 assert results
[1]['level'] == 'error'
135 assert results
[1]['message']['text'] == "conflicting types for 'q'; have 'char'"
136 assert len(results
[1]['relatedLocations']) == 4