scan_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726
  1. package scan
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "os"
  7. "runtime"
  8. "testing"
  9. "github.com/zricethezav/gitleaks/v7/config"
  10. "github.com/zricethezav/gitleaks/v7/options"
  11. )
  12. const testRepoBase = "../test_data/test_repos/"
  13. func TestScan(t *testing.T) {
  14. moveDotGit("dotGit", ".git")
  15. defer moveDotGit(".git", "dotGit")
  16. tests := []struct {
  17. description string
  18. opts options.Options
  19. wantPath string
  20. wantErr error
  21. wantScanErr error
  22. emptyRepo bool
  23. wantEmpty bool
  24. }{
  25. {
  26. description: "test local repo one aws leak",
  27. opts: options.Options{
  28. Path: "../test_data/test_repos/test_repo_1",
  29. Report: "../test_data/test_local_repo_one_aws_leak.json.got",
  30. ReportFormat: "json",
  31. },
  32. wantPath: "../test_data/test_local_repo_one_aws_leak.json",
  33. },
  34. {
  35. description: "test local repo one aws leak threaded",
  36. opts: options.Options{
  37. Threads: runtime.GOMAXPROCS(0),
  38. Path: "../test_data/test_repos/test_repo_1",
  39. Report: "../test_data/test_local_repo_one_aws_leak.json.got",
  40. ReportFormat: "json",
  41. },
  42. wantPath: "../test_data/test_local_repo_one_aws_leak.json",
  43. },
  44. {
  45. description: "test non existent repo",
  46. opts: options.Options{
  47. Path: "../test_data/test_repos/no_repo_here",
  48. ReportFormat: "json",
  49. },
  50. wantErr: fmt.Errorf("stat ../test_data/test_repos/no_repo_here: no such file or directory"),
  51. emptyRepo: true,
  52. },
  53. {
  54. description: "test local repo one aws leak allowlisted",
  55. opts: options.Options{
  56. Path: "../test_data/test_repos/test_repo_1",
  57. ReportFormat: "json",
  58. ConfigPath: "../test_data/test_configs/aws_key_allowlist_python_files.toml",
  59. },
  60. wantEmpty: true,
  61. },
  62. {
  63. description: "test local repo two leaks",
  64. opts: options.Options{
  65. Path: "../test_data/test_repos/test_repo_2",
  66. Report: "../test_data/test_local_repo_two_leaks.json.got",
  67. ReportFormat: "json",
  68. },
  69. wantPath: "../test_data/test_local_repo_two_leaks.json",
  70. },
  71. {
  72. description: "test local repo two leaks from Commit",
  73. opts: options.Options{
  74. Path: "../test_data/test_repos/test_repo_2",
  75. Report: "../test_data/test_local_repo_two_leaks_commit_from.json.got",
  76. ReportFormat: "json",
  77. CommitFrom: "996865bb912f3bc45898a370a13aadb315014b55",
  78. },
  79. wantPath: "../test_data/test_local_repo_two_leaks_commit_from.json",
  80. },
  81. {
  82. description: "test local repo two leaks to Commit",
  83. opts: options.Options{
  84. Path: "../test_data/test_repos/test_repo_2",
  85. Report: "../test_data/test_local_repo_two_leaks_commit_to.json.got",
  86. ReportFormat: "json",
  87. CommitTo: "996865bb912f3bc45898a370a13aadb315014b55",
  88. },
  89. wantPath: "../test_data/test_local_repo_two_leaks_commit_to.json",
  90. },
  91. {
  92. description: "test local repo two leaks to from Commit",
  93. opts: options.Options{
  94. Path: "../test_data/test_repos/test_repo_2",
  95. Report: "../test_data/test_local_repo_two_leaks_commit_to_from.json.got",
  96. ReportFormat: "json",
  97. CommitFrom: "d8ac0b73aeeb45843319cdc5ce506516eb49bf7a",
  98. CommitTo: "51f6dcf6b89b93f4075ba92c400b075631a6cc93",
  99. },
  100. wantPath: "../test_data/test_local_repo_two_leaks_commit_to_from.json",
  101. },
  102. {
  103. description: "test local repo two leaks list Commits",
  104. opts: options.Options{
  105. Path: "../test_data/test_repos/test_repo_2",
  106. Report: "../test_data/test_local_repo_two_leaks_commit_range.json.got",
  107. ReportFormat: "json",
  108. Commits: "d8ac0b73aeeb45843319cdc5ce506516eb49bf7a,996865bb912f3bc45898a370a13aadb315014b55,17471a5fda722a9e423f1a0d3f0d267ea009d41c,51f6dcf6b89b93f4075ba92c400b075631a6cc93,b10b3e2cb320a8c211fda94c4567299d37de7776",
  109. },
  110. wantPath: "../test_data/test_local_repo_two_leaks_commit_range.json",
  111. },
  112. {
  113. description: "test local repo two leaks file list commits",
  114. opts: options.Options{
  115. Path: "../test_data/test_repos/test_repo_2",
  116. Report: "../test_data/test_local_repo_two_leaks_file_commit_range.json.got",
  117. ReportFormat: "json",
  118. CommitsFile: "../test_data/test_options/test_local_repo_commits.txt",
  119. },
  120. wantPath: "../test_data/test_local_repo_two_leaks_file_commit_range.json",
  121. },
  122. {
  123. description: "test local repo two leaks globally allowlisted",
  124. opts: options.Options{
  125. Path: "../test_data/test_repos/test_repo_2",
  126. ConfigPath: "../test_data/test_configs/aws_key_global_allowlist_file.toml",
  127. ReportFormat: "json",
  128. },
  129. wantEmpty: true,
  130. },
  131. {
  132. description: "test local repo two leaks allowlisted",
  133. opts: options.Options{
  134. Path: "../test_data/test_repos/test_repo_2",
  135. ConfigPath: "../test_data/test_configs/aws_key_allowlist_files.toml",
  136. ReportFormat: "json",
  137. },
  138. wantEmpty: true,
  139. },
  140. {
  141. description: "test local repo three leaks dev branch with reportGroup set",
  142. opts: options.Options{
  143. Path: "../test_data/test_repos/test_repo_3",
  144. Report: "../test_data/test_local_repo_three_leaks_with_report_groups.json.got",
  145. ConfigPath: "../test_data/test_configs/aws_key_with_report_groups.toml",
  146. Branch: "dev",
  147. ReportFormat: "json",
  148. },
  149. wantPath: "../test_data/test_local_repo_three_leaks_with_report_groups.json",
  150. },
  151. {
  152. description: "test local repo three leaks dev branch",
  153. opts: options.Options{
  154. Path: "../test_data/test_repos/test_repo_3",
  155. Report: "../test_data/test_local_repo_three_leaks.json.got",
  156. ConfigPath: "../test_data/test_configs/aws_key.toml",
  157. Branch: "dev",
  158. ReportFormat: "json",
  159. },
  160. wantPath: "../test_data/test_local_repo_three_leaks.json",
  161. },
  162. {
  163. description: "test local repo branch does not exist",
  164. opts: options.Options{
  165. Path: "../test_data/test_repos/test_repo_3",
  166. Branch: "nobranch",
  167. ReportFormat: "json",
  168. },
  169. wantScanErr: fmt.Errorf("could not find branch nobranch"),
  170. },
  171. {
  172. description: "test local repo one aws leak single Commit",
  173. opts: options.Options{
  174. Path: "../test_data/test_repos/test_repo_1",
  175. Report: "../test_data/test_local_repo_one_aws_leak_commit.json.got",
  176. Commit: "6557c92612d3b35979bd426d429255b3bf9fab74",
  177. ReportFormat: "json",
  178. },
  179. wantPath: "../test_data/test_local_repo_one_aws_leak_commit.json",
  180. },
  181. {
  182. description: "test local repo one aws leak AND leak on python files",
  183. opts: options.Options{
  184. Path: "../test_data/test_repos/test_repo_1",
  185. Report: "../test_data/test_local_repo_one_aws_leak_and_file_leak.json.got",
  186. ConfigPath: "../test_data/test_configs/aws_key_file_regex.toml",
  187. ReportFormat: "json",
  188. },
  189. wantPath: "../test_data/test_local_repo_one_aws_leak_and_file_leak.json",
  190. },
  191. {
  192. description: "test owner path",
  193. opts: options.Options{
  194. Path: "../test_data/test_repos/",
  195. Report: "../test_data/test_local_owner_aws_leak.json.got",
  196. ReportFormat: "json",
  197. Threads: runtime.GOMAXPROCS(0),
  198. },
  199. wantPath: "../test_data/test_local_owner_aws_leak.json",
  200. },
  201. {
  202. description: "test owner path allowlist repo",
  203. opts: options.Options{
  204. Path: "../test_data/test_repos/",
  205. Report: "../test_data/test_local_owner_aws_leak_allowlist_repo.json.got",
  206. ReportFormat: "json",
  207. ConfigPath: "../test_data/test_configs/aws_key_local_owner_allowlist_repo.toml",
  208. },
  209. wantPath: "../test_data/test_local_owner_aws_leak_allowlist_repo.json",
  210. },
  211. {
  212. description: "test entropy and regex",
  213. opts: options.Options{
  214. Path: "../test_data/test_repos/test_repo_1",
  215. Report: "../test_data/test_regex_entropy.json.got",
  216. ConfigPath: "../test_data/test_configs/regex_entropy.toml",
  217. ReportFormat: "json",
  218. },
  219. wantPath: "../test_data/test_regex_entropy.json",
  220. },
  221. {
  222. description: "test local repo four entropy alternative config",
  223. opts: options.Options{
  224. Path: "../test_data/test_repos/test_repo_4",
  225. Report: "../test_data/test_local_repo_four_alt_config_entropy.json.got",
  226. RepoConfigPath: "gitleaks.toml",
  227. ReportFormat: "json",
  228. },
  229. wantPath: "../test_data/test_local_repo_four_alt_config_entropy.json",
  230. },
  231. {
  232. description: "test local repo four entropy alternative config",
  233. opts: options.Options{
  234. Path: "../test_data/test_repos/test_repo_1",
  235. Report: "../test_data/test_regex_allowlist.json.got",
  236. ConfigPath: "../test_data/test_configs/aws_key_aws_allowlisted.toml",
  237. ReportFormat: "json",
  238. },
  239. wantEmpty: true,
  240. },
  241. {
  242. description: "test owner path depth=2",
  243. opts: options.Options{
  244. Path: "../test_data/test_repos/",
  245. Report: "../test_data/test_local_owner_aws_leak_depth_2.json.got",
  246. ReportFormat: "json",
  247. Depth: 2,
  248. },
  249. wantPath: "../test_data/test_local_owner_aws_leak_depth_2.json",
  250. },
  251. {
  252. description: "test local repo five files at Commit",
  253. opts: options.Options{
  254. Path: "../test_data/test_repos/test_repo_5",
  255. Report: "../test_data/test_local_repo_five_files_at_commit.json.got",
  256. FilesAtCommit: "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0",
  257. ReportFormat: "json",
  258. },
  259. wantPath: "../test_data/test_local_repo_five_files_at_commit.json",
  260. },
  261. {
  262. description: "test local repo five files at latest Commit",
  263. opts: options.Options{
  264. Path: "../test_data/test_repos/test_repo_5",
  265. Report: "../test_data/test_local_repo_five_files_at_latest_commit.json.got",
  266. FilesAtCommit: "latest",
  267. ReportFormat: "json",
  268. },
  269. wantPath: "../test_data/test_local_repo_five_files_at_commit.json",
  270. },
  271. {
  272. description: "test local repo five at Commit",
  273. opts: options.Options{
  274. Path: "../test_data/test_repos/test_repo_5",
  275. Report: "../test_data/test_local_repo_five_commit.json.got",
  276. Commit: "a4c9fb737d5552fd96fce5cc7eedb23353ba9ed0",
  277. ReportFormat: "json",
  278. ConfigPath: "../test_data/test_configs/generic.toml",
  279. },
  280. wantPath: "../test_data/test_local_repo_five_commit.json",
  281. },
  282. {
  283. description: "test local repo five at latest Commit",
  284. opts: options.Options{
  285. Path: "../test_data/test_repos/test_repo_5",
  286. Report: "../test_data/test_local_repo_five_at_latest_commit.json.got",
  287. Commit: "latest",
  288. ReportFormat: "json",
  289. ConfigPath: "../test_data/test_configs/generic.toml",
  290. },
  291. wantPath: "../test_data/test_local_repo_five_at_latest_commit.json",
  292. },
  293. {
  294. description: "test local repo six filename",
  295. opts: options.Options{
  296. Path: "../test_data/test_repos/test_repo_6",
  297. Report: "../test_data/test_local_repo_six_filename.json.got",
  298. ConfigPath: "../test_data/test_configs/regex_filename.toml",
  299. ReportFormat: "json",
  300. },
  301. wantPath: "../test_data/test_local_repo_six_filename.json",
  302. },
  303. {
  304. description: "test local repo six filepath",
  305. opts: options.Options{
  306. Path: "../test_data/test_repos/test_repo_6",
  307. Report: "../test_data/test_local_repo_six_filepath.json.got",
  308. ConfigPath: "../test_data/test_configs/regex_filepath.toml",
  309. ReportFormat: "json",
  310. },
  311. wantPath: "../test_data/test_local_repo_six_filepath.json",
  312. },
  313. {
  314. description: "test local repo six filename and filepath",
  315. opts: options.Options{
  316. Path: "../test_data/test_repos/test_repo_6",
  317. Report: "../test_data/test_local_repo_six_filepath_filename.json.got",
  318. ConfigPath: "../test_data/test_configs/regex_filepath_filename.toml",
  319. ReportFormat: "json",
  320. },
  321. wantPath: "../test_data/test_local_repo_six_filepath_filename.json",
  322. },
  323. {
  324. description: "test local repo six path globally allowlisted",
  325. opts: options.Options{
  326. Path: "../test_data/test_repos/test_repo_6",
  327. Report: "../test_data/test_local_repo_six_path_globally_allowlisted.json.got",
  328. ConfigPath: "../test_data/test_configs/aws_key_global_allowlist_path.toml",
  329. ReportFormat: "json",
  330. },
  331. wantPath: "../test_data/test_local_repo_six_path_globally_allowlisted.json",
  332. },
  333. {
  334. description: "test local repo six leaks since date",
  335. opts: options.Options{
  336. Path: "../test_data/test_repos/test_repo_6",
  337. Report: "../test_data/test_local_repo_six_leaks_since_date.json.got",
  338. ReportFormat: "json",
  339. CommitSince: "2019-10-25",
  340. },
  341. wantPath: "../test_data/test_local_repo_six_leaks_since_date.json",
  342. },
  343. {
  344. description: "test local repo two leaks until date",
  345. opts: options.Options{
  346. Path: "../test_data/test_repos/test_repo_6",
  347. Report: "../test_data/test_local_repo_six_leaks_until_date.json.got",
  348. ReportFormat: "json",
  349. CommitUntil: "2019-10-25",
  350. },
  351. wantPath: "../test_data/test_local_repo_six_leaks_until_date.json",
  352. },
  353. {
  354. description: "test local repo four leaks timerange Commit",
  355. opts: options.Options{
  356. Path: "../test_data/test_repos/test_repo_4",
  357. Report: "../test_data/test_local_repo_four_leaks_commit_timerange.json.got",
  358. ReportFormat: "json",
  359. CommitSince: "2019-10-25T13:01:27-0400",
  360. CommitUntil: "2019-10-25T13:12:32-0400",
  361. },
  362. wantPath: "../test_data/test_local_repo_four_leaks_commit_timerange.json",
  363. },
  364. {
  365. description: "test local repo two allowlist Commit config",
  366. opts: options.Options{
  367. Path: "../test_data/test_repos/test_repo_2",
  368. Report: "../test_data/test_local_repo_two_allowlist_commits.json.got",
  369. ConfigPath: "../test_data/test_configs/allowlist_commit.toml",
  370. ReportFormat: "json",
  371. },
  372. wantPath: "../test_data/test_local_repo_two_allowlist_commits.json",
  373. },
  374. {
  375. description: "test local repo eight (merges)",
  376. opts: options.Options{
  377. Path: "../test_data/test_repos/test_repo_8",
  378. Report: "../test_data/test_local_repo_eight.json.got",
  379. ReportFormat: "json",
  380. },
  381. wantPath: "../test_data/test_local_repo_eight.json",
  382. },
  383. {
  384. description: "test local repo nine",
  385. opts: options.Options{
  386. Path: "../test_data/test_repos/test_repo_9",
  387. Report: "../test_data/test_local_repo_nine_aws_leak.json.got",
  388. ConfigPath: "../test_data/test_configs/large_with_global_allowlist_regex.toml",
  389. ReportFormat: "json",
  390. },
  391. wantPath: "../test_data/test_local_repo_nine_aws_leak.json",
  392. },
  393. {
  394. description: "test dir one no git",
  395. opts: options.Options{
  396. Path: "../test_data/test_repos/test_dir_1",
  397. Report: "../test_data/test_dir1_aws_leak.json.got",
  398. ReportFormat: "json",
  399. NoGit: true,
  400. },
  401. wantPath: "../test_data/test_dir1_aws_leak.json",
  402. },
  403. {
  404. description: "test file with leak no git",
  405. opts: options.Options{
  406. Path: "../test_data/test_repos/test_dir_1/server.test.py",
  407. Report: "../test_data/test_file1_aws_leak.json.got",
  408. ReportFormat: "json",
  409. NoGit: true,
  410. },
  411. wantPath: "../test_data/test_file1_aws_leak.json",
  412. },
  413. {
  414. description: "test only md files no git",
  415. opts: options.Options{
  416. Path: "../test_data/test_repos/",
  417. Report: "../test_data/test_only_files_no_git.json.got",
  418. ReportFormat: "json",
  419. ConfigPath: "../test_data/test_configs/onlyFiles.toml",
  420. NoGit: true,
  421. },
  422. wantPath: "../test_data/test_only_files_no_git.json",
  423. },
  424. }
  425. for _, test := range tests {
  426. fmt.Println(test.description)
  427. cfg, err := config.NewConfig(test.opts)
  428. if err != nil {
  429. t.Error(err)
  430. }
  431. scanner, err := NewScanner(test.opts, cfg)
  432. if test.wantErr != nil {
  433. if err == nil {
  434. t.Fatalf("did not receive wantErr: %v", test.wantErr)
  435. }
  436. if err.Error() != test.wantErr.Error() {
  437. t.Fatalf("wantErr does not equal err received: %v", err.Error())
  438. }
  439. continue
  440. }
  441. if err != nil {
  442. t.Fatal(err)
  443. }
  444. scannerReport, err := scanner.Scan()
  445. if test.wantScanErr != nil {
  446. if err == nil {
  447. t.Fatalf("did not receive wantErr: %v", test.wantScanErr)
  448. }
  449. if err.Error() != test.wantScanErr.Error() {
  450. t.Fatalf("wantErr does not equal err received: %v", err.Error())
  451. }
  452. continue
  453. }
  454. if err != nil {
  455. t.Fatal(err)
  456. }
  457. err = WriteReport(scannerReport, test.opts, cfg)
  458. if err != nil {
  459. t.Error(err)
  460. }
  461. if test.wantEmpty {
  462. if len(scannerReport.Leaks) != 0 {
  463. t.Errorf("wanted no leaks but got some instead: %+v", scannerReport.Leaks)
  464. }
  465. continue
  466. }
  467. if test.wantPath != "" {
  468. err := fileCheck(test.wantPath, test.opts.Report)
  469. if err != nil {
  470. t.Error(err)
  471. }
  472. }
  473. }
  474. }
  475. //
  476. func TestScanUncommited(t *testing.T) {
  477. moveDotGit("dotGit", ".git")
  478. defer moveDotGit(".git", "dotGit")
  479. tests := []struct {
  480. description string
  481. opts options.Options
  482. wantPath string
  483. wantErr error
  484. wantScanErr error
  485. emptyRepo bool
  486. wantEmpty bool
  487. fileToChange string
  488. addition string
  489. }{
  490. {
  491. description: "test scan local one leak",
  492. opts: options.Options{
  493. Path: "../test_data/test_repos/test_repo_1",
  494. Report: "../test_data/test_local_repo_one_aws_leak_uncommitted.json.got",
  495. Unstaged: true,
  496. ReportFormat: "json",
  497. },
  498. wantPath: "../test_data/test_local_repo_one_aws_leak_uncommitted.json",
  499. fileToChange: "server.test.py",
  500. addition: " aws_access_key_id='AKIAIO5FODNN7DXAMPLE'\n\n",
  501. },
  502. {
  503. description: "test scan local no leak",
  504. opts: options.Options{
  505. Path: "../test_data/test_repos/test_repo_1",
  506. Unstaged: true,
  507. ReportFormat: "json",
  508. },
  509. wantEmpty: true,
  510. fileToChange: "server.test.py",
  511. addition: "nothing bad",
  512. },
  513. {
  514. description: "test scan repo with no commits",
  515. opts: options.Options{
  516. Path: "../test_data/test_repos/test_repo_7",
  517. Report: "../test_data/test_local_repo_seven_aws_leak_uncommitted.json.got",
  518. Unstaged: true,
  519. ReportFormat: "json",
  520. },
  521. wantPath: "../test_data/test_local_repo_seven_aws_leak_uncommitted.json",
  522. },
  523. }
  524. for _, test := range tests {
  525. var (
  526. old []byte
  527. err error
  528. )
  529. fmt.Println(test.description)
  530. if test.fileToChange != "" {
  531. old, err = ioutil.ReadFile(fmt.Sprintf("%s/%s", test.opts.Path, test.fileToChange))
  532. if err != nil {
  533. t.Error(err)
  534. }
  535. altered, err := os.OpenFile(fmt.Sprintf("%s/%s", test.opts.Path, test.fileToChange),
  536. os.O_WRONLY|os.O_APPEND, 0644)
  537. if err != nil {
  538. t.Error(err)
  539. }
  540. _, err = altered.WriteString(test.addition)
  541. if err != nil {
  542. t.Error(err)
  543. }
  544. }
  545. cfg, err := config.NewConfig(test.opts)
  546. if err != nil {
  547. t.Error(err)
  548. }
  549. scanner, err := NewScanner(test.opts, cfg)
  550. if test.wantErr != nil {
  551. if err == nil {
  552. t.Fatalf("did not receive wantErr: %v", test.wantErr)
  553. }
  554. if err.Error() != test.wantErr.Error() {
  555. t.Fatalf("wantErr does not equal err received: %v", err.Error())
  556. }
  557. continue
  558. }
  559. if err != nil {
  560. t.Fatal(err)
  561. }
  562. scannerReport, err := scanner.Scan()
  563. if test.wantScanErr != nil {
  564. if err == nil {
  565. t.Fatalf("did not receive wantErr: %v", test.wantScanErr)
  566. }
  567. if err.Error() != test.wantScanErr.Error() {
  568. t.Fatalf("wantErr does not equal err received: %v", err.Error())
  569. }
  570. continue
  571. }
  572. if err != nil {
  573. t.Fatal(err)
  574. }
  575. err = WriteReport(scannerReport, test.opts, cfg)
  576. if err != nil {
  577. t.Error(err)
  578. }
  579. if test.fileToChange != "" {
  580. err = ioutil.WriteFile(fmt.Sprintf("%s/%s", test.opts.Path, test.fileToChange), old, 0)
  581. if err != nil {
  582. t.Error(err)
  583. }
  584. }
  585. if test.wantEmpty {
  586. continue
  587. }
  588. if test.wantPath != "" {
  589. err := fileCheck(test.wantPath, test.opts.Report)
  590. if err != nil {
  591. t.Error(err)
  592. }
  593. }
  594. }
  595. }
  596. func fileCheck(wantPath, gotPath string) error {
  597. var (
  598. gotLeaks []Leak
  599. wantLeaks []Leak
  600. )
  601. want, err := ioutil.ReadFile(wantPath)
  602. if err != nil {
  603. return err
  604. }
  605. got, err := ioutil.ReadFile(gotPath)
  606. if err != nil {
  607. return err
  608. }
  609. err = json.Unmarshal(got, &gotLeaks)
  610. if err != nil {
  611. return err
  612. }
  613. err = json.Unmarshal(want, &wantLeaks)
  614. if err != nil {
  615. return err
  616. }
  617. if len(wantLeaks) != len(gotLeaks) {
  618. return fmt.Errorf("got %d leaks, want %d leaks", len(gotLeaks), len(wantLeaks))
  619. }
  620. for _, wantLeak := range wantLeaks {
  621. found := false
  622. for _, gotLeak := range gotLeaks {
  623. if same(gotLeak, wantLeak) {
  624. found = true
  625. }
  626. }
  627. if !found {
  628. return fmt.Errorf("unable to find %+v in got leaks", wantLeak)
  629. }
  630. }
  631. if err := os.Remove(gotPath); err != nil {
  632. return err
  633. }
  634. return nil
  635. }
  636. func same(l1, l2 Leak) bool {
  637. if l1.Commit != l2.Commit {
  638. return false
  639. }
  640. if l1.Offender != l2.Offender {
  641. return false
  642. }
  643. if l1.Line != l2.Line {
  644. return false
  645. }
  646. if l1.Tags != l2.Tags {
  647. return false
  648. }
  649. if l1.LineNumber != l2.LineNumber {
  650. return false
  651. }
  652. if l1.Author != l2.Author {
  653. return false
  654. }
  655. if l1.LeakURL != l2.LeakURL {
  656. return false
  657. }
  658. if l1.RepoURL != l2.RepoURL {
  659. return false
  660. }
  661. if l1.Repo != l2.Repo {
  662. return false
  663. }
  664. return true
  665. }
  666. func moveDotGit(from, to string) error {
  667. repoDirs, err := ioutil.ReadDir("../test_data/test_repos")
  668. if err != nil {
  669. return err
  670. }
  671. for _, dir := range repoDirs {
  672. if !dir.IsDir() {
  673. continue
  674. }
  675. _, err := os.Stat(fmt.Sprintf("%s/%s/%s", testRepoBase, dir.Name(), from))
  676. if os.IsNotExist(err) {
  677. continue
  678. }
  679. err = os.Rename(fmt.Sprintf("%s/%s/%s", testRepoBase, dir.Name(), from),
  680. fmt.Sprintf("%s/%s/%s", testRepoBase, dir.Name(), to))
  681. if err != nil {
  682. return err
  683. }
  684. }
  685. return nil
  686. }