basic_test.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. package diskv
  2. import (
  3. "bytes"
  4. "errors"
  5. "testing"
  6. "time"
  7. )
  8. func cmpBytes(a, b []byte) bool {
  9. if len(a) != len(b) {
  10. return false
  11. }
  12. for i := 0; i < len(a); i++ {
  13. if a[i] != b[i] {
  14. return false
  15. }
  16. }
  17. return true
  18. }
  19. func (d *Diskv) isCached(key string) bool {
  20. d.mu.RLock()
  21. defer d.mu.RUnlock()
  22. _, ok := d.cache[key]
  23. return ok
  24. }
  25. func TestWriteReadErase(t *testing.T) {
  26. d := New(Options{
  27. BasePath: "test-data",
  28. CacheSizeMax: 1024,
  29. })
  30. defer d.EraseAll()
  31. k, v := "a", []byte{'b'}
  32. if err := d.Write(k, v); err != nil {
  33. t.Fatalf("write: %s", err)
  34. }
  35. if readVal, err := d.Read(k); err != nil {
  36. t.Fatalf("read: %s", err)
  37. } else if bytes.Compare(v, readVal) != 0 {
  38. t.Fatalf("read: expected %s, got %s", v, readVal)
  39. }
  40. if err := d.Erase(k); err != nil {
  41. t.Fatalf("erase: %s", err)
  42. }
  43. }
  44. func TestWRECache(t *testing.T) {
  45. d := New(Options{
  46. BasePath: "test-data",
  47. CacheSizeMax: 1024,
  48. })
  49. defer d.EraseAll()
  50. k, v := "xxx", []byte{' ', ' ', ' '}
  51. if d.isCached(k) {
  52. t.Fatalf("key cached before Write and Read")
  53. }
  54. if err := d.Write(k, v); err != nil {
  55. t.Fatalf("write: %s", err)
  56. }
  57. if d.isCached(k) {
  58. t.Fatalf("key cached before Read")
  59. }
  60. if readVal, err := d.Read(k); err != nil {
  61. t.Fatalf("read: %s", err)
  62. } else if bytes.Compare(v, readVal) != 0 {
  63. t.Fatalf("read: expected %s, got %s", v, readVal)
  64. }
  65. for i := 0; i < 10 && !d.isCached(k); i++ {
  66. time.Sleep(10 * time.Millisecond)
  67. }
  68. if !d.isCached(k) {
  69. t.Fatalf("key not cached after Read")
  70. }
  71. if err := d.Erase(k); err != nil {
  72. t.Fatalf("erase: %s", err)
  73. }
  74. if d.isCached(k) {
  75. t.Fatalf("key cached after Erase")
  76. }
  77. }
  78. func TestStrings(t *testing.T) {
  79. d := New(Options{
  80. BasePath: "test-data",
  81. CacheSizeMax: 1024,
  82. })
  83. defer d.EraseAll()
  84. keys := map[string]bool{"a": false, "b": false, "c": false, "d": false}
  85. v := []byte{'1'}
  86. for k := range keys {
  87. if err := d.Write(k, v); err != nil {
  88. t.Fatalf("write: %s: %s", k, err)
  89. }
  90. }
  91. for k := range d.Keys(nil) {
  92. if _, present := keys[k]; present {
  93. t.Logf("got: %s", k)
  94. keys[k] = true
  95. } else {
  96. t.Fatalf("strings() returns unknown key: %s", k)
  97. }
  98. }
  99. for k, found := range keys {
  100. if !found {
  101. t.Errorf("never got %s", k)
  102. }
  103. }
  104. }
  105. func TestZeroByteCache(t *testing.T) {
  106. d := New(Options{
  107. BasePath: "test-data",
  108. CacheSizeMax: 0,
  109. })
  110. defer d.EraseAll()
  111. k, v := "a", []byte{'1', '2', '3'}
  112. if err := d.Write(k, v); err != nil {
  113. t.Fatalf("Write: %s", err)
  114. }
  115. if d.isCached(k) {
  116. t.Fatalf("key cached, expected not-cached")
  117. }
  118. if _, err := d.Read(k); err != nil {
  119. t.Fatalf("Read: %s", err)
  120. }
  121. if d.isCached(k) {
  122. t.Fatalf("key cached, expected not-cached")
  123. }
  124. }
  125. func TestOneByteCache(t *testing.T) {
  126. d := New(Options{
  127. BasePath: "test-data",
  128. CacheSizeMax: 1,
  129. })
  130. defer d.EraseAll()
  131. k1, k2, v1, v2 := "a", "b", []byte{'1'}, []byte{'1', '2'}
  132. if err := d.Write(k1, v1); err != nil {
  133. t.Fatal(err)
  134. }
  135. if v, err := d.Read(k1); err != nil {
  136. t.Fatal(err)
  137. } else if !cmpBytes(v, v1) {
  138. t.Fatalf("Read: expected %s, got %s", string(v1), string(v))
  139. }
  140. for i := 0; i < 10 && !d.isCached(k1); i++ {
  141. time.Sleep(10 * time.Millisecond)
  142. }
  143. if !d.isCached(k1) {
  144. t.Fatalf("expected 1-byte value to be cached, but it wasn't")
  145. }
  146. if err := d.Write(k2, v2); err != nil {
  147. t.Fatal(err)
  148. }
  149. if _, err := d.Read(k2); err != nil {
  150. t.Fatalf("--> %s", err)
  151. }
  152. for i := 0; i < 10 && (!d.isCached(k1) || d.isCached(k2)); i++ {
  153. time.Sleep(10 * time.Millisecond) // just wait for lazy-cache
  154. }
  155. if !d.isCached(k1) {
  156. t.Fatalf("1-byte value was uncached for no reason")
  157. }
  158. if d.isCached(k2) {
  159. t.Fatalf("2-byte value was cached, but cache max size is 1")
  160. }
  161. }
  162. func TestStaleCache(t *testing.T) {
  163. d := New(Options{
  164. BasePath: "test-data",
  165. CacheSizeMax: 1,
  166. })
  167. defer d.EraseAll()
  168. k, first, second := "a", "first", "second"
  169. if err := d.Write(k, []byte(first)); err != nil {
  170. t.Fatal(err)
  171. }
  172. v, err := d.Read(k)
  173. if err != nil {
  174. t.Fatal(err)
  175. }
  176. if string(v) != first {
  177. t.Errorf("expected '%s', got '%s'", first, v)
  178. }
  179. if err := d.Write(k, []byte(second)); err != nil {
  180. t.Fatal(err)
  181. }
  182. v, err = d.Read(k)
  183. if err != nil {
  184. t.Fatal(err)
  185. }
  186. if string(v) != second {
  187. t.Errorf("expected '%s', got '%s'", second, v)
  188. }
  189. }
  190. func TestHas(t *testing.T) {
  191. d := New(Options{
  192. BasePath: "test-data",
  193. CacheSizeMax: 1024,
  194. })
  195. defer d.EraseAll()
  196. for k, v := range map[string]string{
  197. "a": "1",
  198. "foo": "2",
  199. "012345": "3",
  200. } {
  201. d.Write(k, []byte(v))
  202. }
  203. d.Read("foo") // cache one of them
  204. if !d.isCached("foo") {
  205. t.Errorf("'foo' didn't get cached")
  206. }
  207. for _, tuple := range []struct {
  208. key string
  209. expected bool
  210. }{
  211. {"a", true},
  212. {"b", false},
  213. {"foo", true},
  214. {"bar", false},
  215. {"01234", false},
  216. {"012345", true},
  217. {"0123456", false},
  218. } {
  219. if expected, got := tuple.expected, d.Has(tuple.key); expected != got {
  220. t.Errorf("Has(%s): expected %v, got %v", tuple.key, expected, got)
  221. }
  222. }
  223. }
  224. type BrokenReader struct{}
  225. func (BrokenReader) Read(p []byte) (n int, err error) {
  226. return 0, errors.New("failed to read")
  227. }
  228. func TestRemovesIncompleteFiles(t *testing.T) {
  229. opts := Options{
  230. BasePath: "test-data",
  231. CacheSizeMax: 1024,
  232. }
  233. d := New(opts)
  234. defer d.EraseAll()
  235. key, stream, sync := "key", BrokenReader{}, false
  236. if err := d.WriteStream(key, stream, sync); err == nil {
  237. t.Fatalf("Expected i/o copy error, none received.")
  238. }
  239. if _, err := d.Read(key); err == nil {
  240. t.Fatal("Could read the key, but it shouldn't exist")
  241. }
  242. }
  243. func TestTempDir(t *testing.T) {
  244. opts := Options{
  245. BasePath: "test-data",
  246. TempDir: "test-data-temp",
  247. CacheSizeMax: 1024,
  248. }
  249. d := New(opts)
  250. defer d.EraseAll()
  251. k, v := "a", []byte{'b'}
  252. if err := d.Write(k, v); err != nil {
  253. t.Fatalf("write: %s", err)
  254. }
  255. if readVal, err := d.Read(k); err != nil {
  256. t.Fatalf("read: %s", err)
  257. } else if bytes.Compare(v, readVal) != 0 {
  258. t.Fatalf("read: expected %s, got %s", v, readVal)
  259. }
  260. if err := d.Erase(k); err != nil {
  261. t.Fatalf("erase: %s", err)
  262. }
  263. }
  264. type CrashingReader struct{}
  265. func (CrashingReader) Read(p []byte) (n int, err error) {
  266. panic("System has crashed while reading the stream")
  267. }
  268. func TestAtomicWrite(t *testing.T) {
  269. opts := Options{
  270. BasePath: "test-data",
  271. // Test would fail if TempDir is not set here.
  272. TempDir: "test-data-temp",
  273. CacheSizeMax: 1024,
  274. }
  275. d := New(opts)
  276. defer d.EraseAll()
  277. key := "key"
  278. func() {
  279. defer func() {
  280. recover() // Ignore panicking error
  281. }()
  282. stream := CrashingReader{}
  283. d.WriteStream(key, stream, false)
  284. }()
  285. if d.Has(key) {
  286. t.Fatal("Has key, but it shouldn't exist")
  287. }
  288. if _, ok := <-d.Keys(nil); ok {
  289. t.Fatal("Store isn't empty")
  290. }
  291. }