github.com/SAP/jenkins-library@v1.362.0/cmd/codeqlExecuteScan_test.go (about) 1 //go:build unit 2 // +build unit 3 4 package cmd 5 6 import ( 7 "os" 8 "strings" 9 "testing" 10 11 "github.com/SAP/jenkins-library/pkg/codeql" 12 "github.com/SAP/jenkins-library/pkg/mock" 13 "github.com/stretchr/testify/assert" 14 ) 15 16 type codeqlExecuteScanMockUtils struct { 17 *mock.ExecMockRunner 18 *mock.FilesMock 19 *mock.HttpClientMock 20 } 21 22 func newCodeqlExecuteScanTestsUtils() codeqlExecuteScanMockUtils { 23 utils := codeqlExecuteScanMockUtils{ 24 ExecMockRunner: &mock.ExecMockRunner{}, 25 FilesMock: &mock.FilesMock{}, 26 HttpClientMock: &mock.HttpClientMock{}, 27 } 28 return utils 29 } 30 31 func TestGetMavenSettings(t *testing.T) { 32 t.Parallel() 33 t.Run("No maven", func(t *testing.T) { 34 config := codeqlExecuteScanOptions{BuildTool: "npm"} 35 buildCmd := "mvn clean install" 36 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 37 assert.Equal(t, "", params) 38 }) 39 40 t.Run("No build command", func(t *testing.T) { 41 config := codeqlExecuteScanOptions{BuildTool: "maven"} 42 params := getMavenSettings("", &config, newCodeqlExecuteScanTestsUtils()) 43 assert.Equal(t, "", params) 44 }) 45 46 t.Run("Project Settings file", func(t *testing.T) { 47 config := codeqlExecuteScanOptions{BuildTool: "maven", ProjectSettingsFile: "test.xml"} 48 buildCmd := "mvn clean install" 49 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 50 assert.Equal(t, " --settings=test.xml", params) 51 }) 52 53 t.Run("Skip Project Settings file in case already used", func(t *testing.T) { 54 config := codeqlExecuteScanOptions{BuildTool: "maven", ProjectSettingsFile: "test.xml"} 55 buildCmd := "mvn clean install --settings=project.xml" 56 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 57 assert.Equal(t, "", params) 58 }) 59 60 t.Run("Global Settings file", func(t *testing.T) { 61 config := codeqlExecuteScanOptions{BuildTool: "maven", GlobalSettingsFile: "global.xml"} 62 buildCmd := "mvn clean install" 63 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 64 assert.Equal(t, " --global-settings=global.xml", params) 65 }) 66 67 t.Run("Project and Global Settings file", func(t *testing.T) { 68 config := codeqlExecuteScanOptions{BuildTool: "maven", ProjectSettingsFile: "test.xml", GlobalSettingsFile: "global.xml"} 69 buildCmd := "mvn clean install" 70 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 71 assert.Equal(t, " --global-settings=global.xml --settings=test.xml", params) 72 }) 73 74 t.Run("ProjectSettingsFile https url", func(t *testing.T) { 75 config := codeqlExecuteScanOptions{BuildTool: "maven", ProjectSettingsFile: "https://jenkins-sap-test.com/test.xml"} 76 buildCmd := "mvn clean install" 77 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 78 assert.Equal(t, " --settings=.pipeline/mavenProjectSettings.xml", params) 79 }) 80 81 t.Run("ProjectSettingsFile http url", func(t *testing.T) { 82 config := codeqlExecuteScanOptions{BuildTool: "maven", ProjectSettingsFile: "http://jenkins-sap-test.com/test.xml"} 83 buildCmd := "mvn clean install" 84 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 85 assert.Equal(t, " --settings=.pipeline/mavenProjectSettings.xml", params) 86 }) 87 88 t.Run("GlobalSettingsFile https url", func(t *testing.T) { 89 config := codeqlExecuteScanOptions{BuildTool: "maven", GlobalSettingsFile: "https://jenkins-sap-test.com/test.xml"} 90 buildCmd := "mvn clean install" 91 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 92 assert.Equal(t, " --global-settings=.pipeline/mavenGlobalSettings.xml", params) 93 }) 94 95 t.Run("GlobalSettingsFile http url", func(t *testing.T) { 96 config := codeqlExecuteScanOptions{BuildTool: "maven", GlobalSettingsFile: "http://jenkins-sap-test.com/test.xml"} 97 buildCmd := "mvn clean install" 98 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 99 assert.Equal(t, " --global-settings=.pipeline/mavenGlobalSettings.xml", params) 100 }) 101 102 t.Run("ProjectSettingsFile and GlobalSettingsFile https url", func(t *testing.T) { 103 config := codeqlExecuteScanOptions{BuildTool: "maven", GlobalSettingsFile: "https://jenkins-sap-test.com/test.xml", ProjectSettingsFile: "http://jenkins-sap-test.com/test.xml"} 104 buildCmd := "mvn clean install" 105 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 106 assert.Equal(t, " --global-settings=.pipeline/mavenGlobalSettings.xml --settings=.pipeline/mavenProjectSettings.xml", params) 107 }) 108 109 t.Run("ProjectSettingsFile and GlobalSettingsFile http url", func(t *testing.T) { 110 config := codeqlExecuteScanOptions{BuildTool: "maven", GlobalSettingsFile: "http://jenkins-sap-test.com/test.xml", ProjectSettingsFile: "http://jenkins-sap-test.com/test.xml"} 111 buildCmd := "mvn clean install" 112 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 113 assert.Equal(t, " --global-settings=.pipeline/mavenGlobalSettings.xml --settings=.pipeline/mavenProjectSettings.xml", params) 114 }) 115 116 t.Run("ProjectSettingsFile file and GlobalSettingsFile https url", func(t *testing.T) { 117 config := codeqlExecuteScanOptions{BuildTool: "maven", GlobalSettingsFile: "https://jenkins-sap-test.com/test.xml", ProjectSettingsFile: "test.xml"} 118 buildCmd := "mvn clean install" 119 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 120 assert.Equal(t, " --global-settings=.pipeline/mavenGlobalSettings.xml --settings=test.xml", params) 121 }) 122 123 t.Run("ProjectSettingsFile file and GlobalSettingsFile https url", func(t *testing.T) { 124 config := codeqlExecuteScanOptions{BuildTool: "maven", GlobalSettingsFile: "http://jenkins-sap-test.com/test.xml", ProjectSettingsFile: "test.xml"} 125 buildCmd := "mvn clean install" 126 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 127 assert.Equal(t, " --global-settings=.pipeline/mavenGlobalSettings.xml --settings=test.xml", params) 128 }) 129 130 t.Run("ProjectSettingsFile https url and GlobalSettingsFile file", func(t *testing.T) { 131 config := codeqlExecuteScanOptions{BuildTool: "maven", GlobalSettingsFile: "global.xml", ProjectSettingsFile: "http://jenkins-sap-test.com/test.xml"} 132 buildCmd := "mvn clean install" 133 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 134 assert.Equal(t, " --global-settings=global.xml --settings=.pipeline/mavenProjectSettings.xml", params) 135 }) 136 137 t.Run("ProjectSettingsFile http url and GlobalSettingsFile file", func(t *testing.T) { 138 config := codeqlExecuteScanOptions{BuildTool: "maven", GlobalSettingsFile: "global.xml", ProjectSettingsFile: "http://jenkins-sap-test.com/test.xml"} 139 buildCmd := "mvn clean install" 140 params := getMavenSettings(buildCmd, &config, newCodeqlExecuteScanTestsUtils()) 141 assert.Equal(t, " --global-settings=global.xml --settings=.pipeline/mavenProjectSettings.xml", params) 142 }) 143 } 144 145 func TestUpdateCmdFlag(t *testing.T) { 146 t.Parallel() 147 148 t.Run("No maven", func(t *testing.T) { 149 config := codeqlExecuteScanOptions{BuildTool: "npm"} 150 customFlags := map[string]string{ 151 "--command": "mvn clean install", 152 } 153 updateCmdFlag(&config, customFlags, newCodeqlExecuteScanTestsUtils()) 154 assert.Equal(t, "mvn clean install", customFlags["--command"]) 155 assert.Equal(t, "", customFlags["-c"]) 156 }) 157 158 t.Run("No custom flags with build command provided", func(t *testing.T) { 159 config := codeqlExecuteScanOptions{BuildTool: "maven", ProjectSettingsFile: "test.xml", GlobalSettingsFile: "global.xml"} 160 customFlags := map[string]string{} 161 updateCmdFlag(&config, customFlags, newCodeqlExecuteScanTestsUtils()) 162 assert.Equal(t, "", customFlags["--command"]) 163 assert.Equal(t, "", customFlags["-c"]) 164 }) 165 166 t.Run("Both --command and -c flags are set, no settings file provided", func(t *testing.T) { 167 config := codeqlExecuteScanOptions{BuildTool: "maven"} 168 customFlags := map[string]string{ 169 "--command": "mvn clean install", 170 "-c": "mvn clean install -DskipTests", 171 } 172 updateCmdFlag(&config, customFlags, newCodeqlExecuteScanTestsUtils()) 173 assert.Equal(t, "mvn clean install", customFlags["--command"]) 174 assert.Equal(t, "", customFlags["-c"]) 175 }) 176 177 t.Run("Only -c flag is set, no settings file provided", func(t *testing.T) { 178 config := codeqlExecuteScanOptions{BuildTool: "maven"} 179 customFlags := map[string]string{ 180 "-c": "mvn clean install -DskipTests", 181 } 182 updateCmdFlag(&config, customFlags, newCodeqlExecuteScanTestsUtils()) 183 assert.Equal(t, "mvn clean install -DskipTests", customFlags["--command"]) 184 assert.Equal(t, "", customFlags["-c"]) 185 }) 186 187 t.Run("Update custom command with GlobalSettingsFile and ProjectSettingsFile", func(t *testing.T) { 188 config := codeqlExecuteScanOptions{BuildTool: "maven", ProjectSettingsFile: "test.xml", GlobalSettingsFile: "global.xml"} 189 customFlags := map[string]string{ 190 "--command": "mvn clean install", 191 } 192 updateCmdFlag(&config, customFlags, newCodeqlExecuteScanTestsUtils()) 193 assert.Equal(t, "mvn clean install --global-settings=global.xml --settings=test.xml", customFlags["--command"]) 194 assert.Equal(t, "", customFlags["-c"]) 195 }) 196 197 t.Run("Custom command has --global-settings and --settings", func(t *testing.T) { 198 config := codeqlExecuteScanOptions{BuildTool: "maven", ProjectSettingsFile: "test.xml", GlobalSettingsFile: "global.xml"} 199 customFlags := map[string]string{ 200 "--command": "mvn clean install --settings=test1.xml --global-settings=global1.xml", 201 } 202 updateCmdFlag(&config, customFlags, newCodeqlExecuteScanTestsUtils()) 203 assert.Equal(t, "mvn clean install --settings=test1.xml --global-settings=global1.xml", customFlags["--command"]) 204 assert.Equal(t, "", customFlags["-c"]) 205 }) 206 } 207 208 func TestAddDataToInfluxDB(t *testing.T) { 209 repoUrl := "https://github.htllo.test/Testing/codeql" 210 repoRef := "https://github.htllo.test/Testing/codeql/tree/branch" 211 repoScanUrl := "https://github.htllo.test/Testing/codeql/security/code-scanning" 212 querySuite := "security.ql" 213 214 repoInfo := &codeql.RepoInfo{ 215 FullUrl: repoUrl, 216 FullRef: repoRef, 217 ScanUrl: repoScanUrl, 218 } 219 220 t.Run("No findings", func(t *testing.T) { 221 scanResults := []codeql.CodeqlFindings{} 222 influx := &codeqlExecuteScanInflux{} 223 addDataToInfluxDB(repoInfo, querySuite, scanResults, influx) 224 assert.Equal(t, repoUrl, influx.codeql_data.fields.repositoryURL) 225 assert.Equal(t, repoRef, influx.codeql_data.fields.repositoryReferenceURL) 226 assert.Equal(t, repoScanUrl, influx.codeql_data.fields.codeScanningLink) 227 assert.Equal(t, querySuite, influx.codeql_data.fields.querySuite) 228 assert.Equal(t, 0, influx.codeql_data.fields.auditAllTotal) 229 assert.Equal(t, 0, influx.codeql_data.fields.auditAllAudited) 230 assert.Equal(t, 0, influx.codeql_data.fields.optionalTotal) 231 assert.Equal(t, 0, influx.codeql_data.fields.optionalAudited) 232 }) 233 234 t.Run("Audit All findings category only", func(t *testing.T) { 235 scanResults := []codeql.CodeqlFindings{ 236 { 237 ClassificationName: codeql.AuditAll, 238 Total: 100, 239 Audited: 50, 240 }, 241 } 242 influx := &codeqlExecuteScanInflux{} 243 addDataToInfluxDB(repoInfo, querySuite, scanResults, influx) 244 assert.Equal(t, repoUrl, influx.codeql_data.fields.repositoryURL) 245 assert.Equal(t, repoRef, influx.codeql_data.fields.repositoryReferenceURL) 246 assert.Equal(t, repoScanUrl, influx.codeql_data.fields.codeScanningLink) 247 assert.Equal(t, querySuite, influx.codeql_data.fields.querySuite) 248 assert.Equal(t, scanResults[0].Total, influx.codeql_data.fields.auditAllTotal) 249 assert.Equal(t, scanResults[0].Audited, influx.codeql_data.fields.auditAllAudited) 250 assert.Equal(t, 0, influx.codeql_data.fields.optionalTotal) 251 assert.Equal(t, 0, influx.codeql_data.fields.optionalAudited) 252 }) 253 254 t.Run("Optional findings category only", func(t *testing.T) { 255 scanResults := []codeql.CodeqlFindings{ 256 { 257 ClassificationName: codeql.Optional, 258 Total: 100, 259 Audited: 50, 260 }, 261 } 262 influx := &codeqlExecuteScanInflux{} 263 addDataToInfluxDB(repoInfo, querySuite, scanResults, influx) 264 assert.Equal(t, repoUrl, influx.codeql_data.fields.repositoryURL) 265 assert.Equal(t, repoRef, influx.codeql_data.fields.repositoryReferenceURL) 266 assert.Equal(t, repoScanUrl, influx.codeql_data.fields.codeScanningLink) 267 assert.Equal(t, querySuite, influx.codeql_data.fields.querySuite) 268 assert.Equal(t, 0, influx.codeql_data.fields.auditAllTotal) 269 assert.Equal(t, 0, influx.codeql_data.fields.auditAllAudited) 270 assert.Equal(t, scanResults[0].Total, influx.codeql_data.fields.optionalTotal) 271 assert.Equal(t, scanResults[0].Audited, influx.codeql_data.fields.optionalAudited) 272 }) 273 274 t.Run("Both findings category", func(t *testing.T) { 275 scanResults := []codeql.CodeqlFindings{ 276 { 277 ClassificationName: codeql.AuditAll, 278 Total: 100, 279 Audited: 50, 280 }, 281 { 282 ClassificationName: codeql.Optional, 283 Total: 100, 284 Audited: 50, 285 }, 286 } 287 influx := &codeqlExecuteScanInflux{} 288 addDataToInfluxDB(repoInfo, querySuite, scanResults, influx) 289 assert.Equal(t, repoUrl, influx.codeql_data.fields.repositoryURL) 290 assert.Equal(t, repoRef, influx.codeql_data.fields.repositoryReferenceURL) 291 assert.Equal(t, repoScanUrl, influx.codeql_data.fields.codeScanningLink) 292 assert.Equal(t, querySuite, influx.codeql_data.fields.querySuite) 293 assert.Equal(t, scanResults[0].Total, influx.codeql_data.fields.auditAllTotal) 294 assert.Equal(t, scanResults[0].Audited, influx.codeql_data.fields.auditAllAudited) 295 assert.Equal(t, scanResults[1].Total, influx.codeql_data.fields.optionalTotal) 296 assert.Equal(t, scanResults[1].Audited, influx.codeql_data.fields.optionalAudited) 297 }) 298 } 299 300 func TestPrepareCmdForDatabaseCreate(t *testing.T) { 301 t.Parallel() 302 303 t.Run("No custom flags", func(t *testing.T) { 304 config := &codeqlExecuteScanOptions{ 305 Database: "codeqlDB", 306 ModulePath: "./", 307 BuildTool: "maven", 308 BuildCommand: "mvn clean install", 309 } 310 cmd, err := prepareCmdForDatabaseCreate(map[string]string{}, config, newCodeqlExecuteScanTestsUtils()) 311 assert.NoError(t, err) 312 assert.NotEmpty(t, cmd) 313 assert.Equal(t, 10, len(cmd)) 314 assert.Equal(t, "database create codeqlDB --overwrite --source-root . --working-dir ./ --language=java --command=mvn clean install", 315 strings.Join(cmd, " ")) 316 }) 317 318 t.Run("No custom flags, custom build tool", func(t *testing.T) { 319 config := &codeqlExecuteScanOptions{ 320 Database: "codeqlDB", 321 ModulePath: "./", 322 BuildTool: "custom", 323 Language: "javascript", 324 } 325 cmd, err := prepareCmdForDatabaseCreate(map[string]string{}, config, newCodeqlExecuteScanTestsUtils()) 326 assert.NoError(t, err) 327 assert.NotEmpty(t, cmd) 328 assert.Equal(t, 9, len(cmd)) 329 assert.Equal(t, "database create codeqlDB --overwrite --source-root . --working-dir ./ --language=javascript", 330 strings.Join(cmd, " ")) 331 }) 332 333 t.Run("No custom flags, custom build tool, no language specified", func(t *testing.T) { 334 config := &codeqlExecuteScanOptions{ 335 Database: "codeqlDB", 336 ModulePath: "./", 337 BuildTool: "custom", 338 } 339 _, err := prepareCmdForDatabaseCreate(map[string]string{}, config, newCodeqlExecuteScanTestsUtils()) 340 assert.Error(t, err) 341 }) 342 343 t.Run("No custom flags, invalid build tool, no language specified", func(t *testing.T) { 344 config := &codeqlExecuteScanOptions{ 345 Database: "codeqlDB", 346 ModulePath: "./", 347 BuildTool: "test", 348 } 349 _, err := prepareCmdForDatabaseCreate(map[string]string{}, config, newCodeqlExecuteScanTestsUtils()) 350 assert.Error(t, err) 351 }) 352 353 t.Run("No custom flags, invalid build tool, language specified", func(t *testing.T) { 354 config := &codeqlExecuteScanOptions{ 355 Database: "codeqlDB", 356 ModulePath: "./", 357 BuildTool: "test", 358 Language: "javascript", 359 } 360 cmd, err := prepareCmdForDatabaseCreate(map[string]string{}, config, newCodeqlExecuteScanTestsUtils()) 361 assert.NoError(t, err) 362 assert.NotEmpty(t, cmd) 363 assert.Equal(t, 9, len(cmd)) 364 assert.Equal(t, "database create codeqlDB --overwrite --source-root . --working-dir ./ --language=javascript", 365 strings.Join(cmd, " ")) 366 }) 367 368 t.Run("Custom flags, overwriting source-root", func(t *testing.T) { 369 config := &codeqlExecuteScanOptions{ 370 Database: "codeqlDB", 371 ModulePath: "./", 372 Language: "javascript", 373 } 374 customFlags := map[string]string{ 375 "--source-root": "--source-root=customSrcRoot/", 376 } 377 cmd, err := prepareCmdForDatabaseCreate(customFlags, config, newCodeqlExecuteScanTestsUtils()) 378 assert.NoError(t, err) 379 assert.NotEmpty(t, cmd) 380 assert.Equal(t, 8, len(cmd)) 381 assert.Equal(t, "database create codeqlDB --overwrite --working-dir ./ --language=javascript --source-root=customSrcRoot/", 382 strings.Join(cmd, " ")) 383 }) 384 385 t.Run("Custom flags, overwriting threads from config", func(t *testing.T) { 386 config := &codeqlExecuteScanOptions{ 387 Database: "codeqlDB", 388 ModulePath: "./", 389 Language: "javascript", 390 Threads: "0", 391 Ram: "2000", 392 } 393 customFlags := map[string]string{ 394 "--source-root": "--source-root=customSrcRoot/", 395 "-j": "-j=1", 396 } 397 cmd, err := prepareCmdForDatabaseCreate(customFlags, config, newCodeqlExecuteScanTestsUtils()) 398 assert.NoError(t, err) 399 assert.NotEmpty(t, cmd) 400 assert.Equal(t, 10, len(cmd)) 401 assert.True(t, "database create codeqlDB --overwrite --working-dir ./ --language=javascript --ram=2000 -j=1 --source-root=customSrcRoot/" == strings.Join(cmd, " ") || 402 "database create codeqlDB --overwrite --working-dir ./ --language=javascript --ram=2000 --source-root=customSrcRoot/ -j=1" == strings.Join(cmd, " ")) 403 }) 404 405 } 406 407 func TestPrepareCmdForDatabaseAnalyze(t *testing.T) { 408 t.Parallel() 409 410 t.Run("No additional flags, no querySuite, sarif format", func(t *testing.T) { 411 config := &codeqlExecuteScanOptions{ 412 Database: "codeqlDB", 413 } 414 cmd, err := prepareCmdForDatabaseAnalyze(map[string]string{}, config, "sarif-latest", "target/codeqlReport.sarif") 415 assert.NoError(t, err) 416 assert.NotEmpty(t, cmd) 417 assert.Equal(t, 5, len(cmd)) 418 assert.Equal(t, "database analyze --format=sarif-latest --output=target/codeqlReport.sarif codeqlDB", strings.Join(cmd, " ")) 419 }) 420 421 t.Run("No additional flags, no querySuite, csv format", func(t *testing.T) { 422 config := &codeqlExecuteScanOptions{ 423 Database: "codeqlDB", 424 } 425 cmd, err := prepareCmdForDatabaseAnalyze(map[string]string{}, config, "csv", "target/codeqlReport.csv") 426 assert.NoError(t, err) 427 assert.NotEmpty(t, cmd) 428 assert.Equal(t, 5, len(cmd)) 429 assert.Equal(t, "database analyze --format=csv --output=target/codeqlReport.csv codeqlDB", strings.Join(cmd, " ")) 430 }) 431 432 t.Run("No additional flags, set querySuite", func(t *testing.T) { 433 config := &codeqlExecuteScanOptions{ 434 Database: "codeqlDB", 435 QuerySuite: "security.ql", 436 } 437 cmd, err := prepareCmdForDatabaseAnalyze(map[string]string{}, config, "sarif-latest", "target/codeqlReport.sarif") 438 assert.NoError(t, err) 439 assert.NotEmpty(t, cmd) 440 assert.Equal(t, 6, len(cmd)) 441 assert.Equal(t, "database analyze --format=sarif-latest --output=target/codeqlReport.sarif codeqlDB security.ql", strings.Join(cmd, " ")) 442 }) 443 444 t.Run("No custom flags, flags from config", func(t *testing.T) { 445 config := &codeqlExecuteScanOptions{ 446 Database: "codeqlDB", 447 QuerySuite: "security.ql", 448 Threads: "1", 449 Ram: "2000", 450 } 451 cmd, err := prepareCmdForDatabaseAnalyze(map[string]string{}, config, "sarif-latest", "target/codeqlReport.sarif") 452 assert.NoError(t, err) 453 assert.NotEmpty(t, cmd) 454 assert.Equal(t, 8, len(cmd)) 455 assert.Equal(t, "database analyze --format=sarif-latest --output=target/codeqlReport.sarif codeqlDB --threads=1 --ram=2000 security.ql", strings.Join(cmd, " ")) 456 }) 457 458 t.Run("Custom flags, overwriting threads", func(t *testing.T) { 459 config := &codeqlExecuteScanOptions{ 460 Database: "codeqlDB", 461 QuerySuite: "security.ql", 462 Threads: "1", 463 Ram: "2000", 464 } 465 customFlags := map[string]string{ 466 "--threads": "--threads=2", 467 } 468 cmd, err := prepareCmdForDatabaseAnalyze(customFlags, config, "sarif-latest", "target/codeqlReport.sarif") 469 assert.NoError(t, err) 470 assert.NotEmpty(t, cmd) 471 assert.Equal(t, 8, len(cmd)) 472 assert.Equal(t, "database analyze --format=sarif-latest --output=target/codeqlReport.sarif codeqlDB --ram=2000 --threads=2 security.ql", strings.Join(cmd, " ")) 473 }) 474 475 t.Run("Custom flags, overwriting threads (-j)", func(t *testing.T) { 476 config := &codeqlExecuteScanOptions{ 477 Database: "codeqlDB", 478 QuerySuite: "security.ql", 479 Threads: "1", 480 Ram: "2000", 481 } 482 customFlags := map[string]string{ 483 "-j": "-j=2", 484 } 485 cmd, err := prepareCmdForDatabaseAnalyze(customFlags, config, "sarif-latest", "target/codeqlReport.sarif") 486 assert.NoError(t, err) 487 assert.NotEmpty(t, cmd) 488 assert.Equal(t, 8, len(cmd)) 489 assert.Equal(t, "database analyze --format=sarif-latest --output=target/codeqlReport.sarif codeqlDB --ram=2000 -j=2 security.ql", strings.Join(cmd, " ")) 490 }) 491 492 t.Run("Custom flags, no overwriting", func(t *testing.T) { 493 config := &codeqlExecuteScanOptions{ 494 Database: "codeqlDB", 495 QuerySuite: "security.ql", 496 Threads: "1", 497 Ram: "2000", 498 } 499 customFlags := map[string]string{ 500 "--no-download": "--no-download", 501 } 502 cmd, err := prepareCmdForDatabaseAnalyze(customFlags, config, "sarif-latest", "target/codeqlReport.sarif") 503 assert.NoError(t, err) 504 assert.NotEmpty(t, cmd) 505 assert.Equal(t, 9, len(cmd)) 506 assert.Equal(t, "database analyze --format=sarif-latest --output=target/codeqlReport.sarif codeqlDB --threads=1 --ram=2000 --no-download security.ql", strings.Join(cmd, " ")) 507 }) 508 } 509 510 func TestPrepareCmdForUploadResults(t *testing.T) { 511 t.Parallel() 512 513 config := &codeqlExecuteScanOptions{ 514 ModulePath: "./", 515 } 516 517 t.Run("All configs are set", func(t *testing.T) { 518 repoInfo := &codeql.RepoInfo{ 519 CommitId: "commitId", 520 ServerUrl: "http://github.com", 521 Repo: "repo", 522 Owner: "owner", 523 AnalyzedRef: "refs/heads/branch", 524 } 525 cmd := prepareCmdForUploadResults(config, repoInfo, "token") 526 assert.NotEmpty(t, cmd) 527 assert.Equal(t, 8, len(cmd)) 528 }) 529 530 t.Run("Configs are set partially", func(t *testing.T) { 531 repoInfo := &codeql.RepoInfo{ 532 CommitId: "commitId", 533 ServerUrl: "http://github.com", 534 Repo: "repo", 535 } 536 cmd := prepareCmdForUploadResults(config, repoInfo, "token") 537 assert.NotEmpty(t, cmd) 538 assert.Equal(t, 6, len(cmd)) 539 }) 540 541 t.Run("Empty token", func(t *testing.T) { 542 repoInfo := &codeql.RepoInfo{ 543 CommitId: "commitId", 544 ServerUrl: "http://github.com", 545 Repo: "repo", 546 Owner: "owner", 547 AnalyzedRef: "refs/heads/branch", 548 } 549 cmd := prepareCmdForUploadResults(config, repoInfo, "") 550 assert.NotEmpty(t, cmd) 551 assert.Equal(t, 7, len(cmd)) 552 }) 553 554 t.Run("Empty configs and token", func(t *testing.T) { 555 repoInfo := &codeql.RepoInfo{} 556 cmd := prepareCmdForUploadResults(config, repoInfo, "") 557 assert.NotEmpty(t, cmd) 558 assert.Equal(t, 3, len(cmd)) 559 }) 560 } 561 562 func TestAppendCodeqlQuery(t *testing.T) { 563 t.Parallel() 564 565 t.Run("Empty query", func(t *testing.T) { 566 cmd := []string{"database", "analyze"} 567 query := "" 568 cmd = appendCodeqlQuery(cmd, query) 569 assert.Equal(t, 2, len(cmd)) 570 }) 571 572 t.Run("Not empty query", func(t *testing.T) { 573 cmd := []string{"database", "analyze"} 574 query := "java-extended.ql" 575 cmd = appendCodeqlQuery(cmd, query) 576 assert.Equal(t, 3, len(cmd)) 577 }) 578 } 579 580 func TestGetLangFromBuildTool(t *testing.T) { 581 t.Parallel() 582 583 t.Run("Build tool Maven", func(t *testing.T) { 584 assert.Equal(t, "java", getLangFromBuildTool("maven")) 585 }) 586 t.Run("Build tool Pip", func(t *testing.T) { 587 assert.Equal(t, "python", getLangFromBuildTool("pip")) 588 }) 589 t.Run("Build tool Npm", func(t *testing.T) { 590 assert.Equal(t, "javascript", getLangFromBuildTool("npm")) 591 }) 592 t.Run("Build tool Yarn", func(t *testing.T) { 593 assert.Equal(t, "javascript", getLangFromBuildTool("yarn")) 594 }) 595 t.Run("Build tool Golang", func(t *testing.T) { 596 assert.Equal(t, "go", getLangFromBuildTool("golang")) 597 }) 598 t.Run("Build tool Unknown", func(t *testing.T) { 599 assert.Equal(t, "", getLangFromBuildTool("unknown")) 600 }) 601 } 602 603 func TestGetToken(t *testing.T) { 604 t.Run("Token is set in config", func(t *testing.T) { 605 config := &codeqlExecuteScanOptions{GithubToken: "token"} 606 os.Setenv("GITHUB_TOKEN", "token_from_env") 607 hasToken, token := getToken(config) 608 os.Clearenv() 609 assert.True(t, hasToken) 610 assert.NotEmpty(t, token) 611 assert.Equal(t, "token", token) 612 }) 613 614 t.Run("Token is set in env", func(t *testing.T) { 615 config := &codeqlExecuteScanOptions{} 616 os.Setenv("GITHUB_TOKEN", "token_from_env") 617 hasToken, token := getToken(config) 618 os.Clearenv() 619 assert.True(t, hasToken) 620 assert.NotEmpty(t, token) 621 assert.Equal(t, "token_from_env", token) 622 }) 623 624 t.Run("Token is not set", func(t *testing.T) { 625 config := &codeqlExecuteScanOptions{} 626 hasToken, token := getToken(config) 627 assert.False(t, hasToken) 628 assert.Empty(t, token) 629 }) 630 } 631 632 func TestCheckForCompliance(t *testing.T) { 633 t.Parallel() 634 635 config := &codeqlExecuteScanOptions{VulnerabilityThresholdTotal: 0} 636 repoInfo := &codeql.RepoInfo{ 637 FullUrl: "http://github.com/Test/repo", 638 AnalyzedRef: "refs/heads/branch", 639 } 640 641 t.Run("Project is compliant", func(t *testing.T) { 642 scanResults := []codeql.CodeqlFindings{ 643 { 644 ClassificationName: codeql.AuditAll, 645 Total: 10, 646 Audited: 10, 647 }, 648 } 649 assert.NoError(t, checkForCompliance(scanResults, config, repoInfo)) 650 }) 651 652 t.Run("Project is not compliant", func(t *testing.T) { 653 scanResults := []codeql.CodeqlFindings{ 654 { 655 ClassificationName: codeql.AuditAll, 656 Total: 20, 657 Audited: 10, 658 }, 659 } 660 assert.Error(t, checkForCompliance(scanResults, config, repoInfo)) 661 }) 662 663 t.Run("Don't check Optional findings", func(t *testing.T) { 664 scanResults := []codeql.CodeqlFindings{ 665 { 666 ClassificationName: codeql.Optional, 667 Total: 10, 668 Audited: 0, 669 }, 670 } 671 assert.NoError(t, checkForCompliance(scanResults, config, repoInfo)) 672 }) 673 }