gitleaks_test.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991
  1. package main
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "path"
  7. "regexp"
  8. "strings"
  9. "testing"
  10. "github.com/franela/goblin"
  11. git "gopkg.in/src-d/go-git.v4"
  12. "gopkg.in/src-d/go-git.v4/storage/memory"
  13. )
  14. const testWhitelistCommit = `
  15. [[regexes]]
  16. description = "AWS"
  17. regex = '''AKIA[0-9A-Z]{16}'''
  18. [whitelist]
  19. commits = [
  20. "eaeffdc65b4c73ccb67e75d96bd8743be2c85973",
  21. ]
  22. `
  23. const testWhitelistFile = `
  24. [[regexes]]
  25. description = "AWS"
  26. regex = '''AKIA[0-9A-Z]{16}'''
  27. [whitelist]
  28. files = [
  29. ".go",
  30. ]
  31. `
  32. const testWhitelistBranch = `
  33. [[regexes]]
  34. description = "AWS"
  35. regex = '''AKIA[0-9A-Z]{16}'''
  36. [whitelist]
  37. branches = [
  38. "origin/master",
  39. ]
  40. `
  41. const testWhitelistRegex = `
  42. [[regexes]]
  43. description = "AWS"
  44. regex = '''AKIA[0-9A-Z]{16}'''
  45. [whitelist]
  46. regexes= [
  47. "AKIA",
  48. ]
  49. `
  50. var benchmarkRepo *Repo
  51. var benchmarkLeaksRepo *Repo
  52. func getBenchmarkLeaksRepo() *Repo {
  53. if benchmarkLeaksRepo != nil {
  54. return benchmarkLeaksRepo
  55. }
  56. leaksR, _ := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
  57. URL: "https://github.com/gitleakstest/gronit.git",
  58. })
  59. benchmarkLeaksRepo = &Repo{
  60. repository: leaksR,
  61. }
  62. return benchmarkLeaksRepo
  63. }
  64. func getBenchmarkRepo() *Repo {
  65. if benchmarkRepo != nil {
  66. return benchmarkRepo
  67. }
  68. bmRepo, _ := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
  69. URL: "https://github.com/apple/swift-package-manager.git",
  70. })
  71. benchmarkRepo = &Repo{
  72. repository: bmRepo,
  73. }
  74. return benchmarkRepo
  75. }
  76. func TestGetRepo(t *testing.T) {
  77. var err error
  78. dir, err = ioutil.TempDir("", "gitleaksTestRepo")
  79. defer os.RemoveAll(dir)
  80. if err != nil {
  81. panic(err)
  82. }
  83. _, err = git.PlainClone(dir, false, &git.CloneOptions{
  84. URL: "https://github.com/gitleakstest/gronit",
  85. })
  86. if err != nil {
  87. panic(err)
  88. }
  89. var tests = []struct {
  90. testOpts Options
  91. description string
  92. expectedErrMsg string
  93. }{
  94. {
  95. testOpts: Options{
  96. Repo: "https://github.com/gitleakstest/gronit",
  97. },
  98. description: "test plain clone remote repo",
  99. expectedErrMsg: "",
  100. },
  101. {
  102. testOpts: Options{
  103. Repo: "https://github.com/gitleakstest/gronit",
  104. Disk: true,
  105. },
  106. description: "test on disk clone remote repo",
  107. expectedErrMsg: "",
  108. },
  109. {
  110. testOpts: Options{
  111. RepoPath: dir,
  112. },
  113. description: "test local clone repo",
  114. expectedErrMsg: "",
  115. },
  116. {
  117. testOpts: Options{
  118. Repo: "https://github.com/gitleakstest/nope",
  119. },
  120. description: "test no repo",
  121. expectedErrMsg: "authentication required",
  122. },
  123. {
  124. testOpts: Options{
  125. Repo: "https://github.com/gitleakstest/private",
  126. IncludePrivate: true,
  127. },
  128. description: "test private repo",
  129. expectedErrMsg: "invalid auth method",
  130. },
  131. {
  132. testOpts: Options{
  133. Repo: "https://github.com/gitleakstest/private",
  134. IncludePrivate: true,
  135. Disk: true,
  136. },
  137. description: "test private repo",
  138. expectedErrMsg: "invalid auth method",
  139. },
  140. }
  141. g := goblin.Goblin(t)
  142. for _, test := range tests {
  143. g.Describe("TestGetRepo", func() {
  144. g.It(test.description, func() {
  145. opts = test.testOpts
  146. _, err := getRepo()
  147. if err != nil {
  148. g.Assert(err.Error()).Equal(test.expectedErrMsg)
  149. }
  150. })
  151. })
  152. }
  153. }
  154. func TestRunAudit(t *testing.T) {
  155. err := loadToml()
  156. configsDir := testTomlLoader()
  157. defer os.RemoveAll(configsDir)
  158. dir, err = ioutil.TempDir("", "gitleaksTestOwner")
  159. defer os.RemoveAll(dir)
  160. if err != nil {
  161. panic(err)
  162. }
  163. git.PlainClone(dir+"/gronit", false, &git.CloneOptions{
  164. URL: "https://github.com/gitleakstest/gronit",
  165. })
  166. git.PlainClone(dir+"/h1domains", false, &git.CloneOptions{
  167. URL: "https://github.com/gitleakstest/h1domains",
  168. })
  169. var tests = []struct {
  170. testOpts Options
  171. description string
  172. expectedErrMsg string
  173. numLeaks int
  174. }{
  175. {
  176. testOpts: Options{
  177. GithubUser: "gitleakstest",
  178. },
  179. description: "test github user",
  180. numLeaks: 2,
  181. expectedErrMsg: "",
  182. },
  183. {
  184. testOpts: Options{
  185. GithubUser: "gitleakstest",
  186. Disk: true,
  187. },
  188. description: "test github user on disk ",
  189. numLeaks: 2,
  190. expectedErrMsg: "",
  191. },
  192. {
  193. testOpts: Options{
  194. GithubOrg: "gitleakstestorg",
  195. },
  196. description: "test github org",
  197. numLeaks: 2,
  198. expectedErrMsg: "",
  199. },
  200. {
  201. testOpts: Options{
  202. GithubOrg: "gitleakstestorg",
  203. Disk: true,
  204. },
  205. description: "test org on disk",
  206. numLeaks: 2,
  207. expectedErrMsg: "",
  208. },
  209. {
  210. testOpts: Options{
  211. OwnerPath: dir,
  212. },
  213. description: "test owner path",
  214. numLeaks: 2,
  215. expectedErrMsg: "",
  216. },
  217. {
  218. testOpts: Options{
  219. GithubOrg: "gitleakstestorg",
  220. IncludePrivate: true,
  221. SSHKey: "reallyreallyreallyreallywrongpath",
  222. },
  223. description: "test private org no ssh",
  224. numLeaks: 0,
  225. expectedErrMsg: "unable to generate ssh key: open reallyreallyreallyreallywrongpath: no such file or directory",
  226. },
  227. {
  228. testOpts: Options{
  229. Repo: "https://github.com/gitleakstest/gronit.git",
  230. },
  231. description: "test leak",
  232. numLeaks: 2,
  233. expectedErrMsg: "",
  234. },
  235. {
  236. testOpts: Options{
  237. Repo: "https://github.com/gitleakstest/h1domains.git",
  238. },
  239. description: "test clean",
  240. numLeaks: 0,
  241. expectedErrMsg: "",
  242. },
  243. {
  244. testOpts: Options{
  245. Repo: "https://github.com/gitleakstest/empty.git",
  246. },
  247. description: "test empty",
  248. numLeaks: 0,
  249. expectedErrMsg: "reference not found",
  250. },
  251. }
  252. g := goblin.Goblin(t)
  253. for _, test := range tests {
  254. g.Describe("TestRunAudit", func() {
  255. g.It(test.description, func() {
  256. opts = test.testOpts
  257. leaks, err := run()
  258. if err != nil {
  259. g.Assert(err.Error()).Equal(test.expectedErrMsg)
  260. }
  261. g.Assert(len(leaks)).Equal(test.numLeaks)
  262. })
  263. })
  264. }
  265. }
  266. func TestStartAudit(t *testing.T) {
  267. err := loadToml()
  268. configsDir := testTomlLoader()
  269. defer os.RemoveAll(configsDir)
  270. dir, err = ioutil.TempDir("", "gitleaksTestOwner")
  271. defer os.RemoveAll(dir)
  272. if err != nil {
  273. panic(err)
  274. }
  275. git.PlainClone(dir+"/gronit", false, &git.CloneOptions{
  276. URL: "https://github.com/gitleakstest/gronit",
  277. })
  278. git.PlainClone(dir+"/h1domains", false, &git.CloneOptions{
  279. URL: "https://github.com/gitleakstest/h1domains",
  280. })
  281. var tests = []struct {
  282. testOpts Options
  283. description string
  284. expectedErrMsg string
  285. numLeaks int
  286. }{
  287. {
  288. testOpts: Options{
  289. GithubUser: "gitleakstest",
  290. },
  291. description: "test github user",
  292. numLeaks: 2,
  293. expectedErrMsg: "",
  294. },
  295. {
  296. testOpts: Options{
  297. GithubUser: "gitleakstest",
  298. Disk: true,
  299. },
  300. description: "test github user on disk ",
  301. numLeaks: 2,
  302. expectedErrMsg: "",
  303. },
  304. {
  305. testOpts: Options{
  306. GithubOrg: "gitleakstestorg",
  307. },
  308. description: "test github org",
  309. numLeaks: 2,
  310. expectedErrMsg: "",
  311. },
  312. {
  313. testOpts: Options{
  314. GithubOrg: "gitleakstestorg",
  315. IncludePrivate: true,
  316. },
  317. description: "test private org no ssh",
  318. numLeaks: 0,
  319. expectedErrMsg: "no ssh auth available",
  320. },
  321. {
  322. testOpts: Options{
  323. GithubOrg: "gitleakstestorg",
  324. Disk: true,
  325. },
  326. description: "test org on disk",
  327. numLeaks: 2,
  328. expectedErrMsg: "",
  329. },
  330. {
  331. testOpts: Options{
  332. GithubOrg: "gitleakstestorg",
  333. IncludePrivate: true,
  334. Disk: true,
  335. },
  336. description: "test private org on disk no ssh",
  337. numLeaks: 0,
  338. expectedErrMsg: "no ssh auth available",
  339. },
  340. {
  341. testOpts: Options{
  342. OwnerPath: dir,
  343. },
  344. description: "test owner path",
  345. numLeaks: 2,
  346. expectedErrMsg: "",
  347. },
  348. }
  349. g := goblin.Goblin(t)
  350. for _, test := range tests {
  351. g.Describe("TestStartAudit", func() {
  352. g.It(test.description, func() {
  353. opts = test.testOpts
  354. leaks, err := startAudits()
  355. if err != nil {
  356. g.Assert(err.Error()).Equal(test.expectedErrMsg)
  357. }
  358. g.Assert(len(leaks)).Equal(test.numLeaks)
  359. })
  360. })
  361. }
  362. }
  363. func TestWriteReport(t *testing.T) {
  364. tmpDir, _ := ioutil.TempDir("", "reportDir")
  365. reportJSON := path.Join(tmpDir, "report.json")
  366. reportCSV := path.Join(tmpDir, "report.csv")
  367. defer os.RemoveAll(tmpDir)
  368. leaks := []Leak{
  369. {
  370. Line: "eat",
  371. Commit: "your",
  372. Offender: "veggies",
  373. Type: "and",
  374. Message: "get",
  375. Author: "some",
  376. File: "sleep",
  377. Branch: "thxu",
  378. },
  379. }
  380. var tests = []struct {
  381. leaks []Leak
  382. reportFile string
  383. fileName string
  384. description string
  385. testOpts Options
  386. }{
  387. {
  388. leaks: leaks,
  389. reportFile: reportJSON,
  390. fileName: "report.json",
  391. description: "can we write a file",
  392. testOpts: Options{
  393. Report: reportJSON,
  394. },
  395. },
  396. {
  397. leaks: leaks,
  398. reportFile: reportCSV,
  399. fileName: "report.csv",
  400. description: "can we write a file",
  401. testOpts: Options{
  402. Report: reportCSV,
  403. CSV: true,
  404. },
  405. },
  406. }
  407. g := goblin.Goblin(t)
  408. for _, test := range tests {
  409. g.Describe("TestWriteReport", func() {
  410. g.It(test.description, func() {
  411. opts = test.testOpts
  412. writeReport(test.leaks)
  413. f, _ := os.Stat(test.reportFile)
  414. g.Assert(f.Name()).Equal(test.fileName)
  415. })
  416. })
  417. }
  418. }
  419. func testTomlLoader() string {
  420. tmpDir, _ := ioutil.TempDir("", "whiteListConfigs")
  421. ioutil.WriteFile(path.Join(tmpDir, "regex"), []byte(testWhitelistRegex), 0644)
  422. ioutil.WriteFile(path.Join(tmpDir, "branch"), []byte(testWhitelistBranch), 0644)
  423. ioutil.WriteFile(path.Join(tmpDir, "commit"), []byte(testWhitelistCommit), 0644)
  424. ioutil.WriteFile(path.Join(tmpDir, "file"), []byte(testWhitelistFile), 0644)
  425. return tmpDir
  426. }
  427. func TestAuditRepo(t *testing.T) {
  428. var leaks []Leak
  429. err := loadToml()
  430. configsDir := testTomlLoader()
  431. defer os.RemoveAll(configsDir)
  432. if err != nil {
  433. panic(err)
  434. }
  435. leaksR, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
  436. URL: "https://github.com/gitleakstest/gronit.git",
  437. })
  438. if err != nil {
  439. panic(err)
  440. }
  441. leaksRepo := Repo{
  442. repository: leaksR,
  443. name: "gronit",
  444. }
  445. cleanR, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
  446. URL: "https://github.com/gitleakstest/h1domains.git",
  447. })
  448. if err != nil {
  449. panic(err)
  450. }
  451. cleanRepo := Repo{
  452. repository: cleanR,
  453. name: "h1domains",
  454. }
  455. var tests = []struct {
  456. testOpts Options
  457. description string
  458. expectedErrMsg string
  459. numLeaks int
  460. repo Repo
  461. whiteListFiles []*regexp.Regexp
  462. whiteListCommits map[string]bool
  463. whiteListBranches []string
  464. whiteListRegexes []*regexp.Regexp
  465. configPath string
  466. }{
  467. {
  468. repo: leaksRepo,
  469. description: "two leaks present",
  470. numLeaks: 2,
  471. },
  472. {
  473. repo: leaksRepo,
  474. description: "two leaks present limit goroutines",
  475. numLeaks: 2,
  476. testOpts: Options{
  477. MaxGoRoutines: 4,
  478. },
  479. },
  480. {
  481. repo: leaksRepo,
  482. description: "audit specific bad branch",
  483. numLeaks: 2,
  484. testOpts: Options{
  485. Branch: "master",
  486. },
  487. },
  488. {
  489. repo: leaksRepo,
  490. description: "audit specific good branch",
  491. numLeaks: 0,
  492. testOpts: Options{
  493. Branch: "dev",
  494. },
  495. },
  496. {
  497. repo: leaksRepo,
  498. description: "audit all branch",
  499. numLeaks: 6,
  500. testOpts: Options{
  501. AuditAllRefs: true,
  502. },
  503. },
  504. {
  505. repo: leaksRepo,
  506. description: "audit all branch whitelist 1",
  507. numLeaks: 4,
  508. testOpts: Options{
  509. AuditAllRefs: true,
  510. },
  511. whiteListBranches: []string{
  512. "origin/master",
  513. },
  514. },
  515. {
  516. repo: leaksRepo,
  517. description: "two leaks present whitelist AWS.. no leaks",
  518. whiteListRegexes: []*regexp.Regexp{
  519. regexp.MustCompile("AKIA"),
  520. },
  521. numLeaks: 0,
  522. },
  523. {
  524. repo: leaksRepo,
  525. description: "two leaks present limit goroutines",
  526. numLeaks: 2,
  527. },
  528. {
  529. repo: cleanRepo,
  530. description: "no leaks present",
  531. numLeaks: 0,
  532. },
  533. {
  534. repo: leaksRepo,
  535. description: "two leaks present whitelist go files",
  536. whiteListFiles: []*regexp.Regexp{
  537. regexp.MustCompile(".go"),
  538. },
  539. numLeaks: 0,
  540. },
  541. {
  542. // note this double counts the first commit since we are whitelisting
  543. // a "bad" first commit
  544. repo: leaksRepo,
  545. description: "two leaks present whitelist bad commit",
  546. whiteListCommits: map[string]bool{
  547. "eaeffdc65b4c73ccb67e75d96bd8743be2c85973": true,
  548. },
  549. numLeaks: 2,
  550. },
  551. {
  552. repo: leaksRepo,
  553. description: "redact",
  554. testOpts: Options{
  555. Redact: true,
  556. },
  557. numLeaks: 2,
  558. },
  559. {
  560. repo: leaksRepo,
  561. description: "toml whitelist regex",
  562. configPath: path.Join(configsDir, "regex"),
  563. numLeaks: 0,
  564. },
  565. {
  566. repo: leaksRepo,
  567. description: "toml whitelist branch",
  568. configPath: path.Join(configsDir, "branch"),
  569. testOpts: Options{
  570. AuditAllRefs: true,
  571. },
  572. numLeaks: 4,
  573. },
  574. {
  575. repo: leaksRepo,
  576. description: "toml whitelist file",
  577. configPath: path.Join(configsDir, "file"),
  578. numLeaks: 0,
  579. },
  580. {
  581. // note this double counts the first commit since we are whitelisting
  582. // a "bad" first commit
  583. repo: leaksRepo,
  584. description: "toml whitelist commit",
  585. configPath: path.Join(configsDir, "commit"),
  586. numLeaks: 2,
  587. },
  588. }
  589. whiteListCommits = make(map[string]bool)
  590. g := goblin.Goblin(t)
  591. for _, test := range tests {
  592. g.Describe("TestAuditRepo", func() {
  593. g.It(test.description, func() {
  594. opts = test.testOpts
  595. // settin da globs
  596. if test.whiteListFiles != nil {
  597. whiteListFiles = test.whiteListFiles
  598. } else {
  599. whiteListFiles = nil
  600. }
  601. if test.whiteListCommits != nil {
  602. whiteListCommits = test.whiteListCommits
  603. } else {
  604. whiteListCommits = nil
  605. }
  606. if test.whiteListBranches != nil {
  607. whiteListBranches = test.whiteListBranches
  608. } else {
  609. whiteListBranches = nil
  610. }
  611. if test.whiteListRegexes != nil {
  612. whiteListRegexes = test.whiteListRegexes
  613. } else {
  614. whiteListRegexes = nil
  615. }
  616. // config paths
  617. if test.configPath != "" {
  618. os.Setenv("GITLEAKS_CONFIG", test.configPath)
  619. loadToml()
  620. }
  621. leaks, err = auditRepo(test.repo)
  622. if opts.Redact {
  623. g.Assert(leaks[0].Offender).Equal("REDACTED")
  624. }
  625. g.Assert(len(leaks)).Equal(test.numLeaks)
  626. })
  627. })
  628. }
  629. }
  630. func TestOptionGuard(t *testing.T) {
  631. var tests = []struct {
  632. testOpts Options
  633. githubToken bool
  634. description string
  635. expectedErrMsg string
  636. expectedErrMsgFuzzy string
  637. }{
  638. {
  639. testOpts: Options{},
  640. description: "default no opts",
  641. expectedErrMsg: "",
  642. },
  643. {
  644. testOpts: Options{
  645. IncludePrivate: true,
  646. GithubOrg: "fakeOrg",
  647. },
  648. description: "private org no githubtoken",
  649. expectedErrMsg: "user/organization private repos require env var GITHUB_TOKEN to be set",
  650. githubToken: false,
  651. },
  652. {
  653. testOpts: Options{
  654. IncludePrivate: true,
  655. GithubUser: "fakeUser",
  656. },
  657. description: "private user no githubtoken",
  658. expectedErrMsg: "user/organization private repos require env var GITHUB_TOKEN to be set",
  659. githubToken: false,
  660. },
  661. {
  662. testOpts: Options{
  663. IncludePrivate: true,
  664. GithubUser: "fakeUser",
  665. GithubOrg: "fakeOrg",
  666. },
  667. description: "double owner",
  668. expectedErrMsg: "github user and organization set",
  669. },
  670. {
  671. testOpts: Options{
  672. IncludePrivate: true,
  673. GithubOrg: "fakeOrg",
  674. OwnerPath: "/dev/null",
  675. },
  676. description: "local and remote target",
  677. expectedErrMsg: "github organization set and local owner path",
  678. },
  679. {
  680. testOpts: Options{
  681. IncludePrivate: true,
  682. GithubUser: "fakeUser",
  683. OwnerPath: "/dev/null",
  684. },
  685. description: "local and remote target",
  686. expectedErrMsg: "github user set and local owner path",
  687. },
  688. {
  689. testOpts: Options{
  690. GithubUser: "fakeUser",
  691. SingleSearch: "*/./....",
  692. },
  693. description: "single search invalid regex gaurd",
  694. expectedErrMsgFuzzy: "unable to compile regex: */./...., ",
  695. },
  696. {
  697. testOpts: Options{
  698. GithubUser: "fakeUser",
  699. SingleSearch: "mystring",
  700. },
  701. description: "single search regex gaurd",
  702. expectedErrMsg: "",
  703. },
  704. }
  705. g := goblin.Goblin(t)
  706. for _, test := range tests {
  707. g.Describe("Test Option Gaurd", func() {
  708. g.It(test.description, func() {
  709. os.Clearenv()
  710. opts = test.testOpts
  711. if test.githubToken {
  712. os.Setenv("GITHUB_TOKEN", "fakeToken")
  713. }
  714. err := optsGuard()
  715. if err != nil {
  716. if test.expectedErrMsgFuzzy != "" {
  717. g.Assert(strings.Contains(err.Error(), test.expectedErrMsgFuzzy)).Equal(true)
  718. } else {
  719. g.Assert(err.Error()).Equal(test.expectedErrMsg)
  720. }
  721. } else {
  722. g.Assert("").Equal(test.expectedErrMsg)
  723. }
  724. })
  725. })
  726. }
  727. }
  728. func TestLoadToml(t *testing.T) {
  729. tmpDir, _ := ioutil.TempDir("", "gitleaksTestConfigDir")
  730. defer os.RemoveAll(tmpDir)
  731. err := ioutil.WriteFile(path.Join(tmpDir, "gitleaksConfig"), []byte(defaultConfig), 0644)
  732. if err != nil {
  733. panic(err)
  734. }
  735. configPath := path.Join(tmpDir, "gitleaksConfig")
  736. noConfigPath := path.Join(tmpDir, "gitleaksConfigNope")
  737. var tests = []struct {
  738. testOpts Options
  739. description string
  740. configPath string
  741. expectedErrMsg string
  742. singleSearch bool
  743. }{
  744. {
  745. testOpts: Options{
  746. ConfigPath: configPath,
  747. },
  748. description: "path to config",
  749. },
  750. {
  751. testOpts: Options{},
  752. description: "env var path to no config",
  753. singleSearch: true,
  754. },
  755. {
  756. testOpts: Options{
  757. ConfigPath: noConfigPath,
  758. },
  759. description: "no path to config",
  760. expectedErrMsg: fmt.Sprintf("no gitleaks config at %s", noConfigPath),
  761. },
  762. {
  763. testOpts: Options{},
  764. description: "env var path to config",
  765. configPath: configPath,
  766. expectedErrMsg: "",
  767. },
  768. {
  769. testOpts: Options{},
  770. description: "env var path to no config",
  771. configPath: noConfigPath,
  772. expectedErrMsg: fmt.Sprintf("problem loading config: open %s: no such file or directory", noConfigPath),
  773. },
  774. }
  775. g := goblin.Goblin(t)
  776. for _, test := range tests {
  777. g.Describe("TestLoadToml", func() {
  778. g.It(test.description, func() {
  779. opts = test.testOpts
  780. if test.singleSearch {
  781. singleSearchRegex = regexp.MustCompile("test")
  782. } else {
  783. singleSearchRegex = nil
  784. }
  785. if test.configPath != "" {
  786. os.Setenv("GITLEAKS_CONFIG", test.configPath)
  787. } else {
  788. os.Clearenv()
  789. }
  790. err := loadToml()
  791. if err != nil {
  792. g.Assert(err.Error()).Equal(test.expectedErrMsg)
  793. } else {
  794. g.Assert("").Equal(test.expectedErrMsg)
  795. }
  796. })
  797. })
  798. }
  799. }
  800. func BenchmarkAuditRepo1Proc(b *testing.B) {
  801. loadToml()
  802. opts.MaxGoRoutines = 1
  803. benchmarkRepo = getBenchmarkRepo()
  804. for n := 0; n < b.N; n++ {
  805. auditRepo(*benchmarkRepo)
  806. }
  807. }
  808. func BenchmarkAuditRepo2Proc(b *testing.B) {
  809. loadToml()
  810. opts.MaxGoRoutines = 2
  811. benchmarkRepo = getBenchmarkRepo()
  812. for n := 0; n < b.N; n++ {
  813. auditRepo(*benchmarkRepo)
  814. }
  815. }
  816. func BenchmarkAuditRepo4Proc(b *testing.B) {
  817. loadToml()
  818. opts.MaxGoRoutines = 4
  819. benchmarkRepo = getBenchmarkRepo()
  820. for n := 0; n < b.N; n++ {
  821. auditRepo(*benchmarkRepo)
  822. }
  823. }
  824. func BenchmarkAuditRepo8Proc(b *testing.B) {
  825. loadToml()
  826. opts.MaxGoRoutines = 8
  827. benchmarkRepo = getBenchmarkRepo()
  828. for n := 0; n < b.N; n++ {
  829. auditRepo(*benchmarkRepo)
  830. }
  831. }
  832. func BenchmarkAuditRepo10Proc(b *testing.B) {
  833. loadToml()
  834. opts.MaxGoRoutines = 10
  835. benchmarkRepo = getBenchmarkRepo()
  836. for n := 0; n < b.N; n++ {
  837. auditRepo(*benchmarkRepo)
  838. }
  839. }
  840. func BenchmarkAuditRepo100Proc(b *testing.B) {
  841. loadToml()
  842. opts.MaxGoRoutines = 100
  843. benchmarkRepo = getBenchmarkRepo()
  844. for n := 0; n < b.N; n++ {
  845. auditRepo(*benchmarkRepo)
  846. }
  847. }
  848. func BenchmarkAuditRepo1000Proc(b *testing.B) {
  849. loadToml()
  850. opts.MaxGoRoutines = 1000
  851. benchmarkRepo = getBenchmarkRepo()
  852. for n := 0; n < b.N; n++ {
  853. auditRepo(*benchmarkRepo)
  854. }
  855. }
  856. func BenchmarkAuditRepo10000Proc(b *testing.B) {
  857. loadToml()
  858. opts.MaxGoRoutines = 10000
  859. benchmarkRepo = getBenchmarkRepo()
  860. for n := 0; n < b.N; n++ {
  861. auditRepo(*benchmarkRepo)
  862. }
  863. }
  864. func BenchmarkAuditRepo100000Proc(b *testing.B) {
  865. loadToml()
  866. opts.MaxGoRoutines = 100000
  867. benchmarkRepo = getBenchmarkRepo()
  868. for n := 0; n < b.N; n++ {
  869. auditRepo(*benchmarkRepo)
  870. }
  871. }
  872. func BenchmarkAuditLeakRepo1Proc(b *testing.B) {
  873. loadToml()
  874. opts.MaxGoRoutines = 1
  875. benchmarkLeaksRepo = getBenchmarkLeaksRepo()
  876. for n := 0; n < b.N; n++ {
  877. auditRepo(*benchmarkLeaksRepo)
  878. }
  879. }
  880. func BenchmarkAuditLeakRepo2Proc(b *testing.B) {
  881. loadToml()
  882. opts.MaxGoRoutines = 2
  883. benchmarkLeaksRepo = getBenchmarkLeaksRepo()
  884. for n := 0; n < b.N; n++ {
  885. auditRepo(*benchmarkLeaksRepo)
  886. }
  887. }
  888. func BenchmarkAuditLeakRepo4Proc(b *testing.B) {
  889. loadToml()
  890. opts.MaxGoRoutines = 4
  891. benchmarkLeaksRepo = getBenchmarkLeaksRepo()
  892. for n := 0; n < b.N; n++ {
  893. auditRepo(*benchmarkLeaksRepo)
  894. }
  895. }
  896. func BenchmarkAuditLeakRepo8Proc(b *testing.B) {
  897. loadToml()
  898. opts.MaxGoRoutines = 8
  899. benchmarkLeaksRepo = getBenchmarkLeaksRepo()
  900. for n := 0; n < b.N; n++ {
  901. auditRepo(*benchmarkLeaksRepo)
  902. }
  903. }
  904. func BenchmarkAuditLeakRepo10Proc(b *testing.B) {
  905. loadToml()
  906. opts.MaxGoRoutines = 10
  907. benchmarkLeaksRepo = getBenchmarkLeaksRepo()
  908. for n := 0; n < b.N; n++ {
  909. auditRepo(*benchmarkLeaksRepo)
  910. }
  911. }
  912. func BenchmarkAuditLeakRepo100Proc(b *testing.B) {
  913. loadToml()
  914. opts.MaxGoRoutines = 100
  915. benchmarkLeaksRepo = getBenchmarkLeaksRepo()
  916. for n := 0; n < b.N; n++ {
  917. auditRepo(*benchmarkLeaksRepo)
  918. }
  919. }
  920. func BenchmarkAuditLeakRepo1000Proc(b *testing.B) {
  921. loadToml()
  922. opts.MaxGoRoutines = 1000
  923. benchmarkLeaksRepo = getBenchmarkLeaksRepo()
  924. for n := 0; n < b.N; n++ {
  925. auditRepo(*benchmarkLeaksRepo)
  926. }
  927. }
  928. func BenchmarkAuditLeakRepo10000Proc(b *testing.B) {
  929. loadToml()
  930. opts.MaxGoRoutines = 10000
  931. benchmarkLeaksRepo = getBenchmarkLeaksRepo()
  932. for n := 0; n < b.N; n++ {
  933. auditRepo(*benchmarkLeaksRepo)
  934. }
  935. }
  936. func BenchmarkAuditLeakRepo100000Proc(b *testing.B) {
  937. loadToml()
  938. opts.MaxGoRoutines = 100000
  939. benchmarkLeaksRepo = getBenchmarkLeaksRepo()
  940. for n := 0; n < b.N; n++ {
  941. auditRepo(*benchmarkLeaksRepo)
  942. }
  943. }