tree_diff_test.go 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. package plumbing
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/assert"
  5. "gopkg.in/src-d/go-git.v4/plumbing"
  6. "gopkg.in/src-d/go-git.v4/plumbing/object"
  7. "gopkg.in/src-d/go-git.v4/utils/merkletrie"
  8. "gopkg.in/src-d/hercules.v10/internal/core"
  9. "gopkg.in/src-d/hercules.v10/internal/test"
  10. )
  11. func fixtureTreeDiff() *TreeDiff {
  12. td := TreeDiff{}
  13. td.Configure(nil)
  14. td.Initialize(test.Repository)
  15. return &td
  16. }
  17. func TestTreeDiffMeta(t *testing.T) {
  18. td := fixtureTreeDiff()
  19. assert.Equal(t, td.Name(), "TreeDiff")
  20. assert.Equal(t, len(td.Requires()), 0)
  21. assert.Equal(t, len(td.Provides()), 1)
  22. assert.Equal(t, td.Provides()[0], DependencyTreeChanges)
  23. opts := td.ListConfigurationOptions()
  24. assert.Len(t, opts, 4)
  25. }
  26. func TestTreeDiffConfigure(t *testing.T) {
  27. td := fixtureTreeDiff()
  28. facts := map[string]interface{}{
  29. ConfigTreeDiffEnableBlacklist: true,
  30. ConfigTreeDiffBlacklistedPrefixes: []string{"vendor"},
  31. ConfigTreeDiffLanguages: []string{"go"},
  32. ConfigTreeDiffFilterRegexp: "_.*",
  33. }
  34. assert.Nil(t, td.Configure(facts))
  35. assert.Equal(t, td.Languages, map[string]bool{"go": true})
  36. assert.Equal(t, td.SkipFiles, []string{"vendor"})
  37. assert.Equal(t, td.NameFilter.String(), "_.*")
  38. delete(facts, ConfigTreeDiffLanguages)
  39. td.Languages = nil
  40. assert.Nil(t, td.Configure(facts))
  41. assert.Equal(t, td.Languages, map[string]bool{"all": true})
  42. td.SkipFiles = []string{"test"}
  43. delete(facts, ConfigTreeDiffEnableBlacklist)
  44. assert.Nil(t, td.Configure(facts))
  45. assert.Equal(t, td.SkipFiles, []string{"test"})
  46. }
  47. func TestTreeDiffRegistration(t *testing.T) {
  48. summoned := core.Registry.Summon((&TreeDiff{}).Name())
  49. assert.Len(t, summoned, 1)
  50. assert.Equal(t, summoned[0].Name(), "TreeDiff")
  51. summoned = core.Registry.Summon((&TreeDiff{}).Provides()[0])
  52. assert.True(t, len(summoned) >= 1)
  53. matched := false
  54. for _, tp := range summoned {
  55. matched = matched || tp.Name() == "TreeDiff"
  56. }
  57. assert.True(t, matched)
  58. }
  59. func TestTreeDiffConsume(t *testing.T) {
  60. td := fixtureTreeDiff()
  61. commit, _ := test.Repository.CommitObject(plumbing.NewHash(
  62. "2b1ed978194a94edeabbca6de7ff3b5771d4d665"))
  63. deps := map[string]interface{}{}
  64. deps[core.DependencyCommit] = commit
  65. prevCommit, _ := test.Repository.CommitObject(plumbing.NewHash(
  66. "fbe766ffdc3f87f6affddc051c6f8b419beea6a2"))
  67. td.previousTree, _ = prevCommit.Tree()
  68. res, err := td.Consume(deps)
  69. assert.Nil(t, err)
  70. assert.Equal(t, len(res), 1)
  71. changes := res[DependencyTreeChanges].(object.Changes)
  72. assert.Equal(t, len(changes), 12)
  73. baseline := map[string]merkletrie.Action{
  74. "analyser.go": merkletrie.Delete,
  75. "cmd/hercules/main.go": merkletrie.Modify,
  76. "blob_cache.go": merkletrie.Insert,
  77. "burndown.go": merkletrie.Insert,
  78. "day.go": merkletrie.Insert,
  79. "dummies.go": merkletrie.Insert,
  80. "identity.go": merkletrie.Insert,
  81. "pipeline.go": merkletrie.Insert,
  82. "renames.go": merkletrie.Insert,
  83. "toposort/toposort.go": merkletrie.Insert,
  84. "toposort/toposort_test.go": merkletrie.Insert,
  85. "tree_diff.go": merkletrie.Insert,
  86. }
  87. for _, change := range changes {
  88. action, err := change.Action()
  89. assert.Nil(t, err)
  90. if change.From.Name != "" {
  91. assert.Contains(t, baseline, change.From.Name)
  92. assert.Equal(t, baseline[change.From.Name], action)
  93. } else {
  94. assert.Contains(t, baseline, change.To.Name)
  95. assert.Equal(t, baseline[change.To.Name], action)
  96. }
  97. }
  98. }
  99. func TestTreeDiffConsumeFirst(t *testing.T) {
  100. td := fixtureTreeDiff()
  101. commit, _ := test.Repository.CommitObject(plumbing.NewHash(
  102. "2b1ed978194a94edeabbca6de7ff3b5771d4d665"))
  103. deps := map[string]interface{}{}
  104. deps[core.DependencyCommit] = commit
  105. res, err := td.Consume(deps)
  106. assert.Nil(t, err)
  107. assert.Equal(t, len(res), 1)
  108. changes := res[DependencyTreeChanges].(object.Changes)
  109. assert.Equal(t, len(changes), 21)
  110. for _, change := range changes {
  111. action, err := change.Action()
  112. assert.Nil(t, err)
  113. assert.Equal(t, action, merkletrie.Insert)
  114. }
  115. }
  116. func TestTreeDiffBadCommit(t *testing.T) {
  117. td := fixtureTreeDiff()
  118. commit, _ := test.Repository.CommitObject(plumbing.NewHash(
  119. "2b1ed978194a94edeabbca6de7ff3b5771d4d665"))
  120. commit.TreeHash = plumbing.NewHash("0000000000000000000000000000000000000000")
  121. deps := map[string]interface{}{}
  122. deps[core.DependencyCommit] = commit
  123. res, err := td.Consume(deps)
  124. assert.Nil(t, res)
  125. assert.NotNil(t, err)
  126. }
  127. func TestTreeDiffConsumeSkip(t *testing.T) {
  128. // consume without skipping
  129. td := fixtureTreeDiff()
  130. assert.Contains(t, td.Languages, allLanguages)
  131. commit, _ := test.Repository.CommitObject(plumbing.NewHash(
  132. "aefdedf7cafa6ee110bae9a3910bf5088fdeb5a9"))
  133. deps := map[string]interface{}{}
  134. deps[core.DependencyCommit] = commit
  135. prevCommit, _ := test.Repository.CommitObject(plumbing.NewHash(
  136. "1e076dc56989bc6aa1ef5f55901696e9e01423d4"))
  137. td.previousTree, _ = prevCommit.Tree()
  138. res, err := td.Consume(deps)
  139. assert.Nil(t, err)
  140. assert.Equal(t, len(res), 1)
  141. changes := res[DependencyTreeChanges].(object.Changes)
  142. assert.Equal(t, 37, len(changes))
  143. // consume with skipping
  144. td = fixtureTreeDiff()
  145. td.previousTree, _ = prevCommit.Tree()
  146. td.Configure(map[string]interface{}{
  147. ConfigTreeDiffEnableBlacklist: true,
  148. ConfigTreeDiffBlacklistedPrefixes: []string{"vendor/"},
  149. })
  150. res, err = td.Consume(deps)
  151. assert.Nil(t, err)
  152. assert.Equal(t, len(res), 1)
  153. changes = res[DependencyTreeChanges].(object.Changes)
  154. assert.Equal(t, 31, len(changes))
  155. }
  156. func TestTreeDiffConsumeOnlyFilesThatMatchFilter(t *testing.T) {
  157. // consume without skipping
  158. td := fixtureTreeDiff()
  159. assert.Contains(t, td.Languages, allLanguages)
  160. commit, _ := test.Repository.CommitObject(plumbing.NewHash(
  161. "aefdedf7cafa6ee110bae9a3910bf5088fdeb5a9"))
  162. deps := map[string]interface{}{}
  163. deps[core.DependencyCommit] = commit
  164. prevCommit, _ := test.Repository.CommitObject(plumbing.NewHash(
  165. "1e076dc56989bc6aa1ef5f55901696e9e01423d4"))
  166. td.previousTree, _ = prevCommit.Tree()
  167. res, err := td.Consume(deps)
  168. assert.Nil(t, err)
  169. assert.Equal(t, len(res), 1)
  170. changes := res[DependencyTreeChanges].(object.Changes)
  171. assert.Equal(t, 37, len(changes))
  172. // consume with skipping
  173. td = fixtureTreeDiff()
  174. td.previousTree, _ = prevCommit.Tree()
  175. td.Configure(map[string]interface{}{
  176. ConfigTreeDiffFilterRegexp: ".*go",
  177. })
  178. res, err = td.Consume(deps)
  179. assert.Nil(t, err)
  180. assert.Equal(t, len(res), 1)
  181. changes = res[DependencyTreeChanges].(object.Changes)
  182. assert.Equal(t, 27, len(changes))
  183. }
  184. func TestTreeDiffConsumeLanguageFilterFirst(t *testing.T) {
  185. td := fixtureTreeDiff()
  186. td.Configure(map[string]interface{}{ConfigTreeDiffLanguages: []string{"Go"}})
  187. commit, _ := test.Repository.CommitObject(plumbing.NewHash(
  188. "fbe766ffdc3f87f6affddc051c6f8b419beea6a2"))
  189. deps := map[string]interface{}{}
  190. deps[core.DependencyCommit] = commit
  191. res, err := td.Consume(deps)
  192. assert.Nil(t, err)
  193. assert.Equal(t, len(res), 1)
  194. changes := res[DependencyTreeChanges].(object.Changes)
  195. assert.Equal(t, len(changes), 6)
  196. assert.Equal(t, changes[0].To.Name, "analyser.go")
  197. assert.Equal(t, changes[1].To.Name, "cmd/hercules/main.go")
  198. assert.Equal(t, changes[2].To.Name, "doc.go")
  199. assert.Equal(t, changes[3].To.Name, "file.go")
  200. assert.Equal(t, changes[4].To.Name, "file_test.go")
  201. assert.Equal(t, changes[5].To.Name, "rbtree.go")
  202. }
  203. func TestTreeDiffConsumeLanguageFilter(t *testing.T) {
  204. td := fixtureTreeDiff()
  205. td.Configure(map[string]interface{}{ConfigTreeDiffLanguages: []string{"Python"}})
  206. commit, _ := test.Repository.CommitObject(plumbing.NewHash(
  207. "e89c1d10fb31e32668ad905eb59dc44d7a4a021e"))
  208. deps := map[string]interface{}{}
  209. deps[core.DependencyCommit] = commit
  210. res, err := td.Consume(deps)
  211. assert.Nil(t, err)
  212. assert.Equal(t, len(res), 1)
  213. commit, _ = test.Repository.CommitObject(plumbing.NewHash(
  214. "fbe766ffdc3f87f6affddc051c6f8b419beea6a2"))
  215. deps[core.DependencyCommit] = commit
  216. res, err = td.Consume(deps)
  217. assert.Nil(t, err)
  218. assert.Equal(t, len(res), 1)
  219. changes := res[DependencyTreeChanges].(object.Changes)
  220. assert.Equal(t, len(changes), 1)
  221. assert.Equal(t, changes[0].To.Name, "labours.py")
  222. }
  223. func TestTreeDiffFork(t *testing.T) {
  224. td1 := fixtureTreeDiff()
  225. td1.SkipFiles = append(td1.SkipFiles, "skip")
  226. clones := td1.Fork(1)
  227. assert.Len(t, clones, 1)
  228. td2 := clones[0].(*TreeDiff)
  229. assert.False(t, td1 == td2)
  230. assert.Equal(t, td1.SkipFiles, td2.SkipFiles)
  231. assert.Equal(t, td1.previousTree, td2.previousTree)
  232. td1.Merge([]core.PipelineItem{td2})
  233. }
  234. func TestTreeDiffCheckLanguage(t *testing.T) {
  235. td := fixtureTreeDiff()
  236. td.Languages["Go"] = true
  237. lang, err := td.checkLanguage(
  238. "version.go", plumbing.NewHash("975f35a1412b8ae79b5ba2558f71f41e707fd5a9"))
  239. assert.Nil(t, err)
  240. assert.True(t, lang)
  241. }
  242. func TestTreeDiffConsumeEnryFilter(t *testing.T) {
  243. diffs := object.Changes{&object.Change{
  244. From: object.ChangeEntry{Name: ""},
  245. To: object.ChangeEntry{Name: "vendor/test.go"},
  246. }, &object.Change{
  247. From: object.ChangeEntry{Name: "vendor/test.go"},
  248. To: object.ChangeEntry{Name: ""},
  249. }}
  250. td := fixtureTreeDiff()
  251. newDiffs := td.filterDiffs(diffs)
  252. assert.Len(t, newDiffs, 2)
  253. td.Configure(map[string]interface{}{
  254. ConfigTreeDiffEnableBlacklist: true,
  255. ConfigTreeDiffBlacklistedPrefixes: []string{"whatever"},
  256. })
  257. newDiffs = td.filterDiffs(diffs)
  258. assert.Len(t, newDiffs, 0)
  259. }