issues_test.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package diskv
  2. import (
  3. "bytes"
  4. "io/ioutil"
  5. "sync"
  6. "testing"
  7. "time"
  8. )
  9. // ReadStream from cache shouldn't panic on a nil dereference from a nonexistent
  10. // Compression :)
  11. func TestIssue2A(t *testing.T) {
  12. d := New(Options{
  13. BasePath: "test-issue-2a",
  14. Transform: func(string) []string { return []string{} },
  15. CacheSizeMax: 1024,
  16. })
  17. defer d.EraseAll()
  18. input := "abcdefghijklmnopqrstuvwxy"
  19. key, writeBuf, sync := "a", bytes.NewBufferString(input), false
  20. if err := d.WriteStream(key, writeBuf, sync); err != nil {
  21. t.Fatal(err)
  22. }
  23. for i := 0; i < 2; i++ {
  24. began := time.Now()
  25. rc, err := d.ReadStream(key, false)
  26. if err != nil {
  27. t.Fatal(err)
  28. }
  29. buf, err := ioutil.ReadAll(rc)
  30. if err != nil {
  31. t.Fatal(err)
  32. }
  33. if !cmpBytes(buf, []byte(input)) {
  34. t.Fatalf("read #%d: '%s' != '%s'", i+1, string(buf), input)
  35. }
  36. rc.Close()
  37. t.Logf("read #%d in %s", i+1, time.Since(began))
  38. }
  39. }
  40. // ReadStream on a key that resolves to a directory should return an error.
  41. func TestIssue2B(t *testing.T) {
  42. blockTransform := func(s string) []string {
  43. transformBlockSize := 3
  44. sliceSize := len(s) / transformBlockSize
  45. pathSlice := make([]string, sliceSize)
  46. for i := 0; i < sliceSize; i++ {
  47. from, to := i*transformBlockSize, (i*transformBlockSize)+transformBlockSize
  48. pathSlice[i] = s[from:to]
  49. }
  50. return pathSlice
  51. }
  52. d := New(Options{
  53. BasePath: "test-issue-2b",
  54. Transform: blockTransform,
  55. CacheSizeMax: 0,
  56. })
  57. defer d.EraseAll()
  58. v := []byte{'1', '2', '3'}
  59. if err := d.Write("abcabc", v); err != nil {
  60. t.Fatal(err)
  61. }
  62. _, err := d.ReadStream("abc", false)
  63. if err == nil {
  64. t.Fatal("ReadStream('abc') should return error")
  65. }
  66. t.Logf("ReadStream('abc') returned error: %v", err)
  67. }
  68. // Ensure ReadStream with direct=true isn't racy.
  69. func TestIssue17(t *testing.T) {
  70. var (
  71. basePath = "test-data"
  72. )
  73. dWrite := New(Options{
  74. BasePath: basePath,
  75. CacheSizeMax: 0,
  76. })
  77. defer dWrite.EraseAll()
  78. dRead := New(Options{
  79. BasePath: basePath,
  80. CacheSizeMax: 50,
  81. })
  82. cases := map[string]string{
  83. "a": `1234567890`,
  84. "b": `2345678901`,
  85. "c": `3456789012`,
  86. "d": `4567890123`,
  87. "e": `5678901234`,
  88. }
  89. for k, v := range cases {
  90. if err := dWrite.Write(k, []byte(v)); err != nil {
  91. t.Fatalf("during write: %s", err)
  92. }
  93. dRead.Read(k) // ensure it's added to cache
  94. }
  95. var wg sync.WaitGroup
  96. start := make(chan struct{})
  97. for k, v := range cases {
  98. wg.Add(1)
  99. go func(k, v string) {
  100. <-start
  101. dRead.ReadStream(k, true)
  102. wg.Done()
  103. }(k, v)
  104. }
  105. close(start)
  106. wg.Wait()
  107. }