set_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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:12345",
  16. "sha256:1234",
  17. "sha256:12346",
  18. "sha256:54321",
  19. "sha256:65431",
  20. "sha256:64321",
  21. "sha256:65421",
  22. "sha256:65321",
  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(err)
  52. }
  53. assertEqualDigests(t, dgst, digests[1])
  54. dgst, err = dset.Lookup("sha256:12345")
  55. if err != nil {
  56. t.Fatal(err)
  57. }
  58. assertEqualDigests(t, dgst, digests[0])
  59. dgst, err = dset.Lookup("sha256:12346")
  60. if err != nil {
  61. t.Fatal(err)
  62. }
  63. assertEqualDigests(t, dgst, digests[2])
  64. dgst, err = dset.Lookup("12346")
  65. if err != nil {
  66. t.Fatal(err)
  67. }
  68. assertEqualDigests(t, dgst, digests[2])
  69. dgst, err = dset.Lookup("12345")
  70. if err != nil {
  71. t.Fatal(err)
  72. }
  73. assertEqualDigests(t, dgst, digests[0])
  74. }
  75. func TestAddDuplication(t *testing.T) {
  76. digests := []Digest{
  77. "sha256:1234",
  78. "sha256:12345",
  79. "sha256:12346",
  80. "sha256:54321",
  81. "sha256:65431",
  82. "sha512:65431",
  83. "sha512:65421",
  84. "sha512:65321",
  85. }
  86. dset := NewSet()
  87. for i := range digests {
  88. if err := dset.Add(digests[i]); err != nil {
  89. t.Fatal(err)
  90. }
  91. }
  92. if len(dset.entries) != 8 {
  93. t.Fatal("Invalid dset size")
  94. }
  95. if err := dset.Add(Digest("sha256:12345")); err != nil {
  96. t.Fatal(err)
  97. }
  98. if len(dset.entries) != 8 {
  99. t.Fatal("Duplicate digest insert allowed")
  100. }
  101. if err := dset.Add(Digest("sha384:12345")); err != nil {
  102. t.Fatal(err)
  103. }
  104. if len(dset.entries) != 9 {
  105. t.Fatal("Insert with different algorithm not allowed")
  106. }
  107. }
  108. func assertEqualShort(t *testing.T, actual, expected string) {
  109. if actual != expected {
  110. t.Fatalf("Unexpected short value:\n\tExpected: %s\n\tActual: %s", expected, actual)
  111. }
  112. }
  113. func TestShortCodeTable(t *testing.T) {
  114. digests := []Digest{
  115. "sha256:1234",
  116. "sha256:12345",
  117. "sha256:12346",
  118. "sha256:54321",
  119. "sha256:65431",
  120. "sha256:64321",
  121. "sha256:65421",
  122. "sha256:65321",
  123. }
  124. dset := NewSet()
  125. for i := range digests {
  126. if err := dset.Add(digests[i]); err != nil {
  127. t.Fatal(err)
  128. }
  129. }
  130. dump := ShortCodeTable(dset, 2)
  131. if len(dump) < len(digests) {
  132. t.Fatalf("Error unexpected size: %d, expecting %d", len(dump), len(digests))
  133. }
  134. assertEqualShort(t, dump[digests[0]], "sha256:1234")
  135. assertEqualShort(t, dump[digests[1]], "sha256:12345")
  136. assertEqualShort(t, dump[digests[2]], "sha256:12346")
  137. assertEqualShort(t, dump[digests[3]], "54")
  138. assertEqualShort(t, dump[digests[4]], "6543")
  139. assertEqualShort(t, dump[digests[5]], "64")
  140. assertEqualShort(t, dump[digests[6]], "6542")
  141. assertEqualShort(t, dump[digests[7]], "653")
  142. }
  143. func createDigests(count int) ([]Digest, error) {
  144. r := rand.New(rand.NewSource(25823))
  145. digests := make([]Digest, count)
  146. for i := range digests {
  147. h := sha256.New()
  148. if err := binary.Write(h, binary.BigEndian, r.Int63()); err != nil {
  149. return nil, err
  150. }
  151. digests[i] = NewDigest("sha256", h)
  152. }
  153. return digests, nil
  154. }
  155. func benchAddNTable(b *testing.B, n int) {
  156. digests, err := createDigests(n)
  157. if err != nil {
  158. b.Fatal(err)
  159. }
  160. b.ResetTimer()
  161. for i := 0; i < b.N; i++ {
  162. dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
  163. for j := range digests {
  164. if err = dset.Add(digests[j]); err != nil {
  165. b.Fatal(err)
  166. }
  167. }
  168. }
  169. }
  170. func benchLookupNTable(b *testing.B, n int, shortLen int) {
  171. digests, err := createDigests(n)
  172. if err != nil {
  173. b.Fatal(err)
  174. }
  175. dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
  176. for i := range digests {
  177. if err := dset.Add(digests[i]); err != nil {
  178. b.Fatal(err)
  179. }
  180. }
  181. shorts := make([]string, 0, n)
  182. for _, short := range ShortCodeTable(dset, shortLen) {
  183. shorts = append(shorts, short)
  184. }
  185. b.ResetTimer()
  186. for i := 0; i < b.N; i++ {
  187. if _, err = dset.Lookup(shorts[i%n]); err != nil {
  188. b.Fatal(err)
  189. }
  190. }
  191. }
  192. func benchShortCodeNTable(b *testing.B, n int, shortLen int) {
  193. digests, err := createDigests(n)
  194. if err != nil {
  195. b.Fatal(err)
  196. }
  197. dset := &Set{entries: digestEntries(make([]*digestEntry, 0, n))}
  198. for i := range digests {
  199. if err := dset.Add(digests[i]); err != nil {
  200. b.Fatal(err)
  201. }
  202. }
  203. b.ResetTimer()
  204. for i := 0; i < b.N; i++ {
  205. ShortCodeTable(dset, shortLen)
  206. }
  207. }
  208. func BenchmarkAdd10(b *testing.B) {
  209. benchAddNTable(b, 10)
  210. }
  211. func BenchmarkAdd100(b *testing.B) {
  212. benchAddNTable(b, 100)
  213. }
  214. func BenchmarkAdd1000(b *testing.B) {
  215. benchAddNTable(b, 1000)
  216. }
  217. func BenchmarkLookup10(b *testing.B) {
  218. benchLookupNTable(b, 10, 12)
  219. }
  220. func BenchmarkLookup100(b *testing.B) {
  221. benchLookupNTable(b, 100, 12)
  222. }
  223. func BenchmarkLookup1000(b *testing.B) {
  224. benchLookupNTable(b, 1000, 12)
  225. }
  226. func BenchmarkShortCode10(b *testing.B) {
  227. benchShortCodeNTable(b, 10, 12)
  228. }
  229. func BenchmarkShortCode100(b *testing.B) {
  230. benchShortCodeNTable(b, 100, 12)
  231. }
  232. func BenchmarkShortCode1000(b *testing.B) {
  233. benchShortCodeNTable(b, 1000, 12)
  234. }