github.com/reviewdog/reviewdog@v0.17.5-0.20240516205324-0cd103a83d58/parser/sarif_test.go (about) 1 package parser 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strings" 7 "testing" 8 9 "github.com/google/go-cmp/cmp" 10 "github.com/reviewdog/reviewdog/service/serviceutil" 11 "google.golang.org/protobuf/encoding/protojson" 12 ) 13 14 func TestExampleSarifParser(t *testing.T) { 15 p := NewSarifParser() 16 for i, fixture := range fixtures { 17 diagnostics, err := p.Parse(strings.NewReader(fixture[0])) 18 if err != nil { 19 panic(err) 20 } 21 if len(diagnostics) == 0 { 22 t.Errorf("empty diagnostics") 23 } 24 for _, d := range diagnostics { 25 rdjson, err := protojson.MarshalOptions{Indent: " "}.Marshal(d) 26 if err != nil { 27 t.Fatal(err) 28 } 29 var actualJSON map[string]any 30 var expectJSON map[string]any 31 if err := json.Unmarshal(rdjson, &actualJSON); err != nil { 32 t.Fatal(err) 33 } 34 if err := json.Unmarshal([]byte(fixture[1]), &expectJSON); err != nil { 35 t.Fatal(err) 36 } 37 expectJSON["originalOutput"] = actualJSON["originalOutput"] 38 if diff := cmp.Diff(actualJSON, expectJSON); diff != "" { 39 t.Errorf("fixtures[%d] (-got, +want):\n%s", i, diff) 40 } 41 } 42 } 43 } 44 45 func basedir() string { 46 root, err := serviceutil.GetGitRoot() 47 if err != nil { 48 panic(err) 49 } 50 return root 51 } 52 53 var fixtures = [][]string{{ 54 fmt.Sprintf(`{ 55 "$schema": "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json", 56 "version": "2.1.0", 57 "runs": [ 58 { 59 "originalUriBaseIds": { 60 "SRCROOT": { 61 "uri": "file://%s" 62 } 63 }, 64 "results": [ 65 { 66 "level": "warning", 67 "locations": [ 68 { 69 "physicalLocation": { 70 "artifactLocation": { 71 "uri": "src/MyClass.kt", 72 "uriBaseId": "SRCROOT" 73 }, 74 "region": { 75 "startLine": 10, 76 "startColumn": 5, 77 "endLine": 12, 78 "endColumn": 15 79 } 80 } 81 } 82 ], 83 "message": { 84 "text": "result message" 85 }, 86 "ruleId": "rule_id" 87 } 88 ], 89 "tool": { 90 "driver": { 91 "informationUri": "https://example.com", 92 "name": "driver_name", 93 "rules": [ 94 { 95 "helpUri": "https://example.com", 96 "id": "rule_id", 97 "name": "My Rule", 98 "shortDescription": { 99 "text": "Rule description" 100 } 101 } 102 ] 103 } 104 } 105 } 106 ] 107 }`, basedir()), `{ 108 "message": "result message", 109 "location": { 110 "path": "src/MyClass.kt", 111 "range": { 112 "start": { 113 "line": 10, 114 "column": 5 115 }, 116 "end": { 117 "line": 12, 118 "column": 15 119 } 120 } 121 }, 122 "severity": "WARNING", 123 "source": { 124 "name": "driver_name", 125 "url": "https://example.com" 126 }, 127 "code": { 128 "value": "rule_id", 129 "url": "https://example.com" 130 } 131 }`}, 132 {`{ 133 "runs": [ 134 { 135 "originalUriBaseIds": { 136 "SRCROOT": { 137 "description": "uri deleted root" 138 } 139 }, 140 "results": [ 141 { 142 "locations": [ 143 { 144 "physicalLocation": { 145 "artifactLocation": { 146 "uri": "src/MyClass.kt", 147 "uriBaseId": "SRCROOT" 148 }, 149 "region": { 150 "startLine": 10 151 } 152 } 153 } 154 ], 155 "message": { 156 "text": "message" 157 }, 158 "ruleId": "rule_id" 159 } 160 ], 161 "tool": { 162 "driver": { 163 "name": "driver_name", 164 "rules": [ 165 { 166 "id": "rule_id", 167 "defaultConfiguration": { 168 "level": "error" 169 } 170 } 171 ] 172 } 173 } 174 } 175 ] 176 }`, `{ 177 "message": "message", 178 "location": { 179 "path": "src/MyClass.kt", 180 "range": { 181 "start": { 182 "line": 10 183 } 184 } 185 }, 186 "severity": "ERROR", 187 "source": { 188 "name": "driver_name" 189 }, 190 "code": { 191 "value": "rule_id" 192 } 193 }`}, 194 {`{ 195 "runs": [ 196 { 197 "results": [ 198 { 199 "locations": [ 200 { 201 "physicalLocation": { 202 "artifactLocation": { 203 "uri": "src/MyClass.kt" 204 }, 205 "region": { 206 "startLine": 10 207 } 208 } 209 } 210 ], 211 "fixes": [ 212 { 213 "artifactChanges": [ 214 { 215 "artifactLocation": { 216 "uri": "src/MyClass.kt" 217 }, 218 "replacements": [ 219 { 220 "deletedRegion": { 221 "startLine": 10, 222 "startColumn": 1, 223 "endColumn": 1 224 }, 225 "insertedContent": { 226 "text": "// " 227 } 228 } 229 ] 230 } 231 ] 232 } 233 ], 234 "message": { 235 "markdown": "message" 236 }, 237 "ruleId": "rule_id" 238 } 239 ], 240 "tool": { 241 "driver": { 242 "name": "driver_name" 243 } 244 } 245 } 246 ] 247 }`, `{ 248 "message": "message", 249 "location": { 250 "path": "src/MyClass.kt", 251 "range": { 252 "start": { 253 "line": 10 254 } 255 } 256 }, 257 "source": { 258 "name": "driver_name" 259 }, 260 "code": { 261 "value": "rule_id" 262 }, 263 "suggestions": [ 264 { 265 "range": { 266 "start": { 267 "line": 10, 268 "column": 1 269 }, 270 "end": { 271 "line": 10, 272 "column": 1 273 } 274 }, 275 "text": "// " 276 } 277 ] 278 }`}, 279 {fmt.Sprintf(`{ 280 "runs": [ 281 { 282 "originalUriBaseIds": { 283 "ROOTPATH": { 284 "uri": "%s" 285 } 286 }, 287 "tool": { 288 "driver": { 289 "name": "Trivy", 290 "informationUri": "https://github.com/aquasecurity/trivy", 291 "fullName": "Trivy Vulnerability Scanner", 292 "version": "0.15.0", 293 "rules": [ 294 { 295 "id": "CVE-2018-14618/curl", 296 "name": "OS Package Vulnerability (Alpine)", 297 "shortDescription": { 298 "text": "CVE-2018-14618 Package: curl" 299 }, 300 "fullDescription": { 301 "text": "curl: NTLM password overflow via integer overflow." 302 }, 303 "defaultConfiguration": { 304 "level": "error" 305 }, 306 "helpUri": "https://avd.aquasec.com/nvd/cve-2018-14618", 307 "help": { 308 "text": "Vulnerability CVE-2018-14618\nSeverity: CRITICAL\n...", 309 "markdown": "**Vulnerability CVE-2018-14618**\n| Severity..." 310 }, 311 "properties": { 312 "tags": [ 313 "vulnerability", 314 "CRITICAL", 315 "curl" 316 ], 317 "precision": "very-high" 318 } 319 } 320 ] 321 } 322 }, 323 "results": [ 324 { 325 "ruleId": "CVE-2018-14618/curl", 326 "ruleIndex": 0, 327 "level": "error", 328 "message": { 329 "text": "curl before version 7.61.1 is..." 330 }, 331 "locations": [{ 332 "physicalLocation": { 333 "artifactLocation": { 334 "uri": "knqyf263/vuln-image (alpine 3.7.1)", 335 "uriBaseId": "ROOTPATH" 336 } 337 } 338 }] 339 }] 340 } 341 ] 342 } 343 `, basedir()), `{ 344 "message": "curl before version 7.61.1 is...", 345 "location": { 346 "path": "knqyf263/vuln-image (alpine 3.7.1)" 347 }, 348 "severity": "ERROR", 349 "source": { 350 "name": "Trivy", 351 "url": "https://github.com/aquasecurity/trivy" 352 }, 353 "code": { 354 "value": "CVE-2018-14618/curl", 355 "url": "https://avd.aquasec.com/nvd/cve-2018-14618" 356 } 357 }`}, 358 }