|
4 | 4 | from azure.ai.inference import ChatCompletionsClient
|
5 | 5 | from openai import AzureOpenAI, OpenAI
|
6 | 6 |
|
| 7 | +from codemodder.codetf import ( |
| 8 | + DetectionTool, |
| 9 | + DiffSide, |
| 10 | + Finding, |
| 11 | + Rule, |
| 12 | + UnfixedFinding, |
| 13 | +) |
| 14 | +from codemodder.codetf.common import FixQuality, Rating |
| 15 | +from codemodder.codetf.v2.codetf import ( |
| 16 | + AIMetadata, |
| 17 | +) |
| 18 | +from codemodder.codetf.v2.codetf import Change as V2Change |
| 19 | +from codemodder.codetf.v2.codetf import ChangeSet as V2ChangeSet |
| 20 | +from codemodder.codetf.v2.codetf import ( |
| 21 | + Strategy, |
| 22 | +) |
7 | 23 | from codemodder.context import CodemodExecutionContext as Context
|
8 | 24 | from codemodder.dependency import Security
|
9 | 25 | from codemodder.llm import DEFAULT_AZURE_OPENAI_API_VERSION, MisconfiguredAIClient
|
@@ -298,3 +314,118 @@ def test_no_misconfiguration_ai_client_disabled(self, mocker, env_var):
|
298 | 314 | ai_client=False,
|
299 | 315 | )
|
300 | 316 | assert context.openai_llm_client is None
|
| 317 | + |
| 318 | + def test_compile_results(self, mocker): |
| 319 | + rule = rule = Rule( |
| 320 | + id="roslyn.sonaranalyzer.security.cs:S5131", |
| 321 | + name="Change this code to not reflect user-controlled data.", |
| 322 | + url="https://rules.sonarsource.com/dotnet/RSPEC-5131/", |
| 323 | + ) |
| 324 | + mock_codemod_xss = mocker.Mock() |
| 325 | + mock_codemod_xss.id = "sonar:dotnet/xss" |
| 326 | + mock_codemod_xss.summary = "XSS Codemod Summary" |
| 327 | + mock_codemod_xss.description = "XSS Codemod Description" |
| 328 | + mock_codemod_xss.detection_tool = DetectionTool(name="sonar") |
| 329 | + mock_codemod_xss.references = [] |
| 330 | + mock_codemod_xss.detection_tool_rules = {rule} |
| 331 | + |
| 332 | + codemods_to_run = [mock_codemod_xss] |
| 333 | + |
| 334 | + context = Context( |
| 335 | + mocker.Mock(), |
| 336 | + True, |
| 337 | + False, |
| 338 | + load_registered_codemods(), |
| 339 | + None, |
| 340 | + PythonRepoManager(mocker.Mock()), |
| 341 | + [], |
| 342 | + [], |
| 343 | + ) |
| 344 | + |
| 345 | + fix_quality = FixQuality( |
| 346 | + safetyRating=Rating( |
| 347 | + score=100, |
| 348 | + description="The changes ...", |
| 349 | + ), |
| 350 | + effectivenessRating=Rating( |
| 351 | + score=100, |
| 352 | + description="The changes ...", |
| 353 | + ), |
| 354 | + cleanlinessRating=Rating( |
| 355 | + score=100, |
| 356 | + description="The changes ...", |
| 357 | + ), |
| 358 | + ) |
| 359 | + changeset_data = { |
| 360 | + "sonar:dotnet/xss": [ |
| 361 | + V2ChangeSet( |
| 362 | + path="WebGoat/WebGoatCoins/Autocomplete.ashx.cs", |
| 363 | + diff="diff", |
| 364 | + changes=[ |
| 365 | + V2Change( |
| 366 | + lineNumber=1, |
| 367 | + description="Added import for System.Net namespace to use WebUtility for HTML encoding.", |
| 368 | + diffSide=DiffSide.RIGHT, |
| 369 | + properties=None, |
| 370 | + packageActions=None, |
| 371 | + fixedFindings=[ |
| 372 | + Finding( |
| 373 | + id="AY-cCz4neXIgSHLjbCnv", |
| 374 | + rule=rule, |
| 375 | + ) |
| 376 | + ], |
| 377 | + ), |
| 378 | + V2Change( |
| 379 | + lineNumber=28, |
| 380 | + description="Wrapped Encoder.ToJSONSAutocompleteString with WebUtility.HtmlEncode to safely encode user input for output.", |
| 381 | + diffSide=DiffSide.RIGHT, |
| 382 | + properties=None, |
| 383 | + packageActions=None, |
| 384 | + fixedFindings=[ |
| 385 | + Finding( |
| 386 | + id="AY-cCz4neXIgSHLjbCnv", |
| 387 | + rule=rule, |
| 388 | + ) |
| 389 | + ], |
| 390 | + ), |
| 391 | + ], |
| 392 | + ai=AIMetadata( |
| 393 | + provider="openai", |
| 394 | + model="gpt-4o", |
| 395 | + tokens=86618, |
| 396 | + completion_tokens=12110, |
| 397 | + prompt_tokens=74508, |
| 398 | + ), |
| 399 | + strategy=Strategy.ai, |
| 400 | + provisional=False, |
| 401 | + fixedFindings=[ |
| 402 | + Finding( |
| 403 | + id="AY-cCz4neXIgSHLjbCnv", |
| 404 | + rule=rule, |
| 405 | + ) |
| 406 | + ], |
| 407 | + fixQuality=fix_quality, |
| 408 | + ) |
| 409 | + ] |
| 410 | + } |
| 411 | + context._changesets_by_codemod = changeset_data |
| 412 | + |
| 413 | + context._unfixed_findings_by_codemod = { |
| 414 | + mock_codemod_xss.id: [ |
| 415 | + UnfixedFinding( |
| 416 | + rule=rule, path="some/path.cs", lineNumber=10, reason="unfixed" |
| 417 | + ) |
| 418 | + ] |
| 419 | + } |
| 420 | + context._failures_by_codemod = {mock_codemod_xss.id: ["failed/file.cs"]} |
| 421 | + |
| 422 | + results = context.compile_results(codemods_to_run) |
| 423 | + |
| 424 | + assert len(results) == 1 |
| 425 | + assert results[0].changeset[0].fixQuality == fix_quality |
| 426 | + assert results[0].changeset[0].fixedFindings == [ |
| 427 | + Finding( |
| 428 | + id="AY-cCz4neXIgSHLjbCnv", |
| 429 | + rule=rule, |
| 430 | + ) |
| 431 | + ] |
0 commit comments