set_test.go 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. package digest
  2. import (
  3. "crypto/sha256"
  4. "encoding/binary"
  5. "math/rand"
  6. "testing"
  7. )
  8. func assertEqualDigests(t *testing.T, d1, d2 Digest) {
  9. if d1 != d2 {
  10. t.Fatalf("Digests do not match:\n\tActual: %s\n\tExpected: %s", d1, d2)
  11. }
  12. }
  13. func TestLookup(t *testing.T) {
  14. digests := []Digest{
  15. "sha256:1234511111111111111111111111111111111111111111111111111111111111",
  16. "sha256:1234111111111111111111111111111111111111111111111111111111111111",
  17. "sha256:1234611111111111111111111111111111111111111111111111111111111111",
  18. "sha256:5432111111111111111111111111111111111111111111111111111111111111",
  19. "sha256:6543111111111111111111111111111111111111111111111111111111111111",
  20. "sha256:6432111111111111111111111111111111111111111111111111111111111111",
  21. "sha256:6542111111111111111111111111111111111111111111111111111111111111",
  22. "sha256:6532111111111111111111111111111111111111111111111111111111111111",
  23. }
  24. dset := NewSet()
  25. for i := range digests {
  26. if err := dset.Add(digests[i]); err != nil {
  27. t.Fatal(err)
  28. }
  29. }
  30. dgst, err := dset.Lookup("54")
  31. if err != nil {
  32. t.Fatal(err)
  33. }
  34. assertEqualDigests(t, dgst, digests[3])
  35. dgst, err = dset.Lookup("1234")
  36. if err == nil {
  37. t.Fatal("Expected ambiguous error looking up: 1234")
  38. }
  39. if err != ErrDigestAmbiguous {
  40. t.Fatal(err)
  41. }
  42. dgst, err = dset.Lookup("9876")
  43. if err == nil {
  44. t.Fatal("Expected ambiguous error looking up: 9876")
  45. }
  46. if err != ErrDigestNotFound {
  47. t.Fatal(err)
  48. }
  49. dgst, err = dset.Lookup("sha256:1234")
  50. if err == nil {
  51. t.Fatal("Expected ambiguous error looking up: sha256:1234")
  52. }
  53. if err != ErrDigestAmbiguous {
  54. t.Fatal(err)
  55. }
  56. dgst, err = dset.Lookup("sha256:12345")
  57. if err != nil {
  58. t.Fatal(err)
  59. }
  60. assertEqualDigests(t, dgst, digests[0])
  61. dgst, err = dset.Lookup("sha256:12346")
  62. if err != nil {
  63. t.Fatal(err)
  64. }
  65. assertEqualDigests(t, dgst, digests[2])
  66. dgst, err = dset.Lookup("12346")
  67. if err != nil {
  68. t.Fatal(err)
  69. }
  70. assertEqualDigests(t, dgst, digests[2])
  71. dgst, err = dset.Lookup("12345")
  72. if err != nil {
  73. t.Fatal(err)
  74. }
  75. assertEqualDigests(t, dgst, digests[0])
  76. }
  77. func TestAddDuplication(t *testing.T) {
  78. digests := []Digest{
  79. "sha256:1234111111111111111111111111111111111111111111111111111111111111",
  80. "sha256:1234511111111111111111111111111111111111111111111111111111111111",
  81. "sha256:1234611111111111111111111111111111111111111111111111111111111111",
  82. "sha256:5432111111111111111111111111111111111111111111111111111111111111",
  83. "sha256:6543111111111111111111111111111111111111111111111111111111111111",
  84. "sha512:65431111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
  85. "sha512:65421111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
  86. "sha512:65321111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111",
  87. }
  88. dset := NewSet()
  89. for i := range digests {
  90. if err := dset.Add(digests[i]); err != nil {
  91. t.Fatal(err)
  92. }
  93. }
  94. if len(dset.entries) != 8 {
  95. t.Fatal("Invalid dset size")
  96. }
  97. if err := dset.Add(Digest("sha256:1234511111111111111111111111111111111111111111111111111111111111")); err != nil {
  98. t.Fatal(err)
  99. }
  100. if len(dset.entries) != 8 {
  101. t.Fatal("Duplicate digest insert allowed")
  102. }
  103. if err := dset.Add(Digest("sha384:123451111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111")); err != nil {
  104. t.Fatal(err)
  105. }
  106. if len(dset.entries) != 9 {
  107. t.Fatal("Insert with different algorithm not allowed")
  108. }
  109. }
  110. func TestRemove(t *testing.T) {
  111. digests, err := createDigests(10)
  112. if err != nil {
  113. t.Fatal(err)
  114. }
  115. dset := NewSet()
  116. for i := range digests {
  117. if err := dset.Add(digests[i]); err != nil {
  118. t.Fatal(err)
  119. }
  120. }
  121. dgst, err := dset.Lookup(digests[0].String())
  122. if err != nil {
  123. t.Fatal(err)
  124. }
  125. if dgst != digests[0] {
  126. t.Fatalf("Unexpected digest value:\n\tExpected: %s\n\tActual: %s", digests[0], dgst)
  127. }
  128. if err := dset.Remove(digests[0]); err != nil {
  129. t.Fatal(err)
  130. }
  131. if _, err := dset.Lookup(digests[0].String()); err != ErrDigestNotFound {
  132. t.Fatalf("Expected error %v when looking up removed digest, got %v", ErrDigestNotFound, err)
  133. }
  134. }
  135. func TestAll(t *testing.T) {
  136. digests, err := createDigests(100)
  137. if err != nil {
  138. t.Fatal(err)
  139. }
  140. dset := NewSet()
  141. for i := range digests {
  142. if err := dset.Add(digests[i]); err != nil {
  143. t.Fatal(err)
  144. }
  145. }
  146. all := map[Digest]struct{}{}
  147. for _, dgst := range dset.All() {
  148. all[dgst] = struct{}{}
  149. }
  150. if len(all) != len(digests) {
  151. t.Fatalf("Unexpected number of unique digests found:\n\tExpected: %d\n\tActual: %d", len(digests), len(all))
  152. }
  153. for i, dgst := range digests {
  154. if _, ok := all[dgst]; !ok {
  155. t.Fatalf("Missing element at position %d: %s", i, dgst)
  156. }
  157. }
  158. }
  159. func assertEqualShort(t *testing.T, actual, expected string) {
  160. if actual != expected {
  161. t.Fatalf("Unexpected short value:\n\tExpected: %s\n\tActual: %s", expected, actual)
  162. }
  163. }
  164. func TestShortCodeTable(t *testing.T) {
  165. digests := []Digest{
  166. "sha256:1234111111111111111111111111111111111111111111111111111111111111",
  167. "sha256:1234511111111111111111111111111111111111111111111111111111111111",
  168. "sha256:1234611111111111111111111111111111111111111111111111111111111111",
  169. "sha256:5432111111111111111111111111111111111111111111111111111111111111",
  170. "sha256:6543111111111111111111111111111111111111111111111111111111111111",
  171. "sha256:6432111111111111111111111111111111111111111111111111111111111111",
  172. "sha256:6542111111111111111111111111111111111111111111111111111111111111",
  173. "sha256:6532111111111111111111111111111111111111111111111111111111111111",
  174. }
  175. dset := NewSet()
  176. for i := range digests {
  177. if err := dset.Add(digests[i]); err != nil {
  178. t.Fatal(err)
  179. }
  180. }
  181. dump := ShortCodeTable(dset, 2)
  182. if len(dump) < len(digests) {
  183. t.Fatalf("Error unexpected size: %d, expecting %d", len(dump), len(digests))
  184. }
  185. assertEqualShort(t, dump[digests[0]], "12341")
  186. assertEqualShort(t, dump[digests[1]], "12345")
  187. assertEqualShort(t, dump[digests[2]], "12346")
  188. assertEqualShort(t, dump[digests[3]], "54")
  189. assertEqualShort(t, dump[digests[4]], "6543")
  190. assertEqualShort(t, dump[digests[5]], "64")
  191. assertEqualShort(t, dump[digests[6]], "6542")
  192. assertEqualShort(t, dump[digests[7]], "653")
  193. }
  194. func createDigests(count int) ([]Digest, error) {
  195. r := rand.New(rand.NewSource(25823))
  196. digests := make([]Digest, count)
  197. for i := range digests {
  198. h := sha256.New()
  199. if err := binary.Write(h, binary.BigEndian, r.Int63()); err != nil {
  200. return nil, err
  201. }
  202. digests[i] = NewDigest("sha256", h)
  203. }
  204. return digests, nil
  205. }
  206. func benchAddNTable(b *testing.B, n int) {
  207. digests, err := createDigests(n)
  208. if err != nil {
  209. b.Fatal(err)
  210. }
  211. b.ResetTimer()
  212. for i := 0; i < b.N; i++ {
  213. dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
  214. for j := range digests {
  215. if err = dset.Add(digests[j]); err != nil {
  216. b.Fatal(err)
  217. }
  218. }
  219. }
  220. }
  221. func benchLookupNTable(b *testing.B, n int, shortLen int) {
  222. digests, err := createDigests(n)
  223. if err != nil {
  224. b.Fatal(err)
  225. }
  226. dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
  227. for i := range digests {
  228. if err := dset.Add(digests[i]); err != nil {
  229. b.Fatal(err)
  230. }
  231. }
  232. shorts := make([]string, 0, n)
  233. for _, short := range ShortCodeTable(dset, shortLen) {
  234. shorts = append(shorts, short)
  235. }
  236. b.ResetTimer()
  237. for i := 0; i < b.N; i++ {
  238. if _, err = dset.Lookup(shorts[i%n]); err != nil {
  239. b.Fatal(err)
  240. }
  241. }
  242. }
  243. func benchRemoveNTable(b *testing.B, n int) {
  244. digests, err := createDigests(n)
  245. if err != nil {
  246. b.Fatal(err)
  247. }
  248. b.ResetTimer()
  249. for i := 0; i < b.N; i++ {
  250. dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
  251. b.StopTimer()
  252. for j := range digests {
  253. if err = dset.Add(digests[j]); err != nil {
  254. b.Fatal(err)
  255. }
  256. }
  257. b.StartTimer()
  258. for j := range digests {
  259. if err = dset.Remove(digests[j]); err != nil {
  260. b.Fatal(err)
  261. }
  262. }
  263. }
  264. }
  265. func benchShortCodeNTable(b *testing.B, n int, shortLen int) {
  266. digests, err := createDigests(n)
  267. if err != nil {
  268. b.Fatal(err)
  269. }
  270. dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
  271. for i := range digests {
  272. if err := dset.Add(digests[i]); err != nil {
  273. b.Fatal(err)
  274. }
  275. }
  276. b.ResetTimer()
  277. for i := 0; i < b.N; i++ {
  278. ShortCodeTable(dset, shortLen)
  279. }
  280. }
  281. func BenchmarkAdd10(b *testing.B) {
  282. benchAddNTable(b, 10)
  283. }
  284. func BenchmarkAdd100(b *testing.B) {
  285. benchAddNTable(b, 100)
  286. }
  287. func BenchmarkAdd1000(b *testing.B) {
  288. benchAddNTable(b, 1000)
  289. }
  290. func BenchmarkRemove10(b *testing.B) {
  291. benchRemoveNTable(b, 10)
  292. }
  293. func BenchmarkRemove100(b *testing.B) {
  294. benchRemoveNTable(b, 100)
  295. }
  296. func BenchmarkRemove1000(b *testing.B) {
  297. benchRemoveNTable(b, 1000)
  298. }
  299. func BenchmarkLookup10(b *testing.B) {
  300. benchLookupNTable(b, 10, 12)
  301. }
  302. func BenchmarkLookup100(b *testing.B) {
  303. benchLookupNTable(b, 100, 12)
  304. }
  305. func BenchmarkLookup1000(b *testing.B) {
  306. benchLookupNTable(b, 1000, 12)
  307. }
  308. func BenchmarkShortCode10(b *testing.B) {
  309. benchShortCodeNTable(b, 10, 12)
  310. }
  311. func BenchmarkShortCode100(b *testing.B) {
  312. benchShortCodeNTable(b, 100, 12)
  313. }
  314. func BenchmarkShortCode1000(b *testing.B) {
  315. benchShortCodeNTable(b, 1000, 12)
  316. }