aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/gcc.dg/sarif-output/include-chain-1.py
blob: 87e7627dcbd6db678cb5dc541e4b69b0fa7b7671 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
from sarif import *

import pytest

@pytest.fixture(scope='function', autouse=True)
def sarif():
    return sarif_from_env()

def test_basics(sarif):
    schema = sarif['$schema']
    assert schema == "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json"

    version = sarif['version']
    assert version == "2.1.0"

def test_execution_unsuccessful(sarif):
    runs = sarif['runs']
    run = runs[0]

    invocations = run['invocations']
    assert len(invocations) == 1
    invocation = invocations[0]

    # We expect the errors to make executionSuccessful be false
    assert invocation['executionSuccessful'] == False

def test_location_relationships(sarif):
    runs = sarif['runs']
    run = runs[0]
    results = run['results']

    # We expect a pair of errors, each with a note, and include chains.
    # The textual form of these four diagnostics would look like this:
    #  . In file included from PATH/include-chain-1.h:5,
    #  .                  from PATH/include-chain.c:9:
    #  . PATH/include-chain-1-2.h:1:6: error: conflicting types for 'p'; have 'char'
    #  .     1 | char p;
    #  .       |      ^
    #  . In file included from PATH/include-chain-1.h:2:
    #  . PATH/include-chain-1-1.h:1:5: note: previous declaration of 'p' with type 'int'
    #  .     1 | int p;
    #  .       |     ^
    #  . PATH/include-chain-1-2.h:2:6: error: conflicting types for 'q'; have 'char'
    #  .     2 | char q;
    #  .       |      ^
    #  . PATH/include-chain-1-1.h:2:5: note: previous declaration of 'q' with type 'int'
    #  .     2 | int q;
    #  .       |     ^
    assert len(results) == 2
    
    result = results[0]
    assert result['level'] == 'error'
    assert result['message']['text'] == "conflicting types for 'p'; have 'char'"
    locations = result['locations']
    assert len(locations) == 1

    location = locations[0]
    assert 'id' in location
    assert get_location_artifact_uri(location).endswith('include-chain-1-2.h')
    assert get_location_snippet_text(location) == "char p;\n"

    # We expect 4 related locations: one for the "note"
    # and three for describing include chains
    relatedLocations = result['relatedLocations']
    assert len(relatedLocations) == 4

    # We expect a related location representing the note:
    #  . In file included from PATH/include-chain-1.h:2:
    #  .                  from PATH/include-chain.c:9:
    #  . PATH/include-chain-1-1.h:1:5: note: previous declaration of 'p' with type 'int'
    #  .     1 | int p;
    #  .       |     ^
    note = relatedLocations[0]
    assert 'id' in note
    assert note['message']['text'] == "previous declaration of 'p' with type 'int'"
    assert get_location_artifact_uri(note).endswith('include-chain-1-1.h')
    assert get_location_snippet_text(note) == "int p;\n"

    # We expect three more related locations for the two include chains

    # The "#include "include-chain-1-2.h" line in include-chain-1.h:
    hash_include_1_2_h = relatedLocations[1]
    assert 'id' in hash_include_1_2_h
    assert get_location_snippet_text(hash_include_1_2_h) == '#include "include-chain-1-2.h"\n'
    assert get_location_artifact_uri(hash_include_1_2_h).endswith('include-chain-1.h')

    # The "#include "include-chain-1-1.h" line in include-chain-1.h:
    hash_include_1_1_h = relatedLocations[2]
    assert 'id' in hash_include_1_1_h
    assert get_location_snippet_text(hash_include_1_1_h) == '#include "include-chain-1-1.h"\n'
    assert get_location_artifact_uri(hash_include_1_1_h).endswith('include-chain-1.h')

    # The "#include "include-chain-1.h" line in include-chain-1.c:
    hash_include_1_h = relatedLocations[3]
    assert 'id' in hash_include_1_h
    assert get_location_snippet_text(hash_include_1_h) == '#include "include-chain-1.h"\n'
    assert get_location_artifact_uri(hash_include_1_h).endswith('include-chain-1.c')

    # Check the various relationships; we expect a directed graph of edges
    # representing the various "isIncludedBy" and "includes" relationships.

    # The primary location should be "isIncludedBy" the "#include "include-chain-1-2.h" line
    assert len(location['relationships']) == 1
    assert location['relationships'][0]['target'] == hash_include_1_2_h['id']
    assert location['relationships'][0]['kinds'] == ["isIncludedBy"]

    # The note should be "isIncludedBy" the "#include "include-chain-1-1.h" line
    assert len(note['relationships']) == 1
    assert note['relationships'][0]['target'] == hash_include_1_1_h['id']
    assert note['relationships'][0]['kinds'] == ["isIncludedBy"]

    # The "#include "include-chain-1-2.h" line:
    assert len(hash_include_1_2_h['relationships']) == 2
    assert hash_include_1_2_h['relationships'][0]['target'] == location['id']
    assert hash_include_1_2_h['relationships'][0]['kinds'] == ["includes"]
    assert hash_include_1_2_h['relationships'][1]['target'] == hash_include_1_h['id']
    assert hash_include_1_2_h['relationships'][1]['kinds'] == ["isIncludedBy"]
    
    # The "#include "include-chain-1-1.h" line:
    assert len(hash_include_1_1_h['relationships']) == 2
    assert hash_include_1_1_h['relationships'][0]['target'] == note['id']
    assert hash_include_1_1_h['relationships'][0]['kinds'] == ["includes"]
    assert hash_include_1_1_h['relationships'][1]['target'] == hash_include_1_h['id']
    assert hash_include_1_1_h['relationships'][1]['kinds'] == ["isIncludedBy"]
    
    # The "#include "include-chain-1.h" line in include-chain-1.c:
    assert len(hash_include_1_h['relationships']) == 2
    assert hash_include_1_h['relationships'][0]['target'] == hash_include_1_2_h['id']
    assert hash_include_1_h['relationships'][0]['kinds'] == ["includes"]
    assert hash_include_1_h['relationships'][1]['target'] == hash_include_1_1_h['id']
    assert hash_include_1_h['relationships'][1]['kinds'] == ["includes"]

    # We expect similar for the 2nd error
    assert results[1]['level'] == 'error'
    assert results[1]['message']['text'] == "conflicting types for 'q'; have 'char'"
    assert len(results[1]['relatedLocations']) == 4