gitleaks_test.go 21 KB

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