batch_tx_test.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. package backend
  2. import (
  3. "reflect"
  4. "testing"
  5. "time"
  6. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/boltdb/bolt"
  7. )
  8. func TestBatchTxPut(t *testing.T) {
  9. b := newBackend(tmpPath, time.Hour, 10000)
  10. defer cleanup(b, tmpPath)
  11. tx := b.batchTx
  12. tx.Lock()
  13. defer tx.Unlock()
  14. // create bucket
  15. tx.UnsafeCreateBucket([]byte("test"))
  16. // put
  17. v := []byte("bar")
  18. tx.UnsafePut([]byte("test"), []byte("foo"), v)
  19. // check put result before and after tx is committed
  20. for k := 0; k < 2; k++ {
  21. _, gv := tx.UnsafeRange([]byte("test"), []byte("foo"), nil, 0)
  22. if !reflect.DeepEqual(gv[0], v) {
  23. t.Errorf("v = %s, want %s", string(gv[0]), string(v))
  24. }
  25. tx.commit(false)
  26. }
  27. }
  28. func TestBatchTxRange(t *testing.T) {
  29. b := newBackend(tmpPath, time.Hour, 10000)
  30. defer cleanup(b, tmpPath)
  31. tx := b.batchTx
  32. tx.Lock()
  33. defer tx.Unlock()
  34. tx.UnsafeCreateBucket([]byte("test"))
  35. // put keys
  36. allKeys := [][]byte{[]byte("foo"), []byte("foo1"), []byte("foo2")}
  37. allVals := [][]byte{[]byte("bar"), []byte("bar1"), []byte("bar2")}
  38. for i := range allKeys {
  39. tx.UnsafePut([]byte("test"), allKeys[i], allVals[i])
  40. }
  41. tests := []struct {
  42. key []byte
  43. endKey []byte
  44. limit int64
  45. wkeys [][]byte
  46. wvals [][]byte
  47. }{
  48. // single key
  49. {
  50. []byte("foo"), nil, 0,
  51. allKeys[:1], allVals[:1],
  52. },
  53. // single key, bad
  54. {
  55. []byte("doo"), nil, 0,
  56. nil, nil,
  57. },
  58. // key range
  59. {
  60. []byte("foo"), []byte("foo1"), 0,
  61. allKeys[:1], allVals[:1],
  62. },
  63. // key range, get all keys
  64. {
  65. []byte("foo"), []byte("foo3"), 0,
  66. allKeys, allVals,
  67. },
  68. // key range, bad
  69. {
  70. []byte("goo"), []byte("goo3"), 0,
  71. nil, nil,
  72. },
  73. // key range with effective limit
  74. {
  75. []byte("foo"), []byte("foo3"), 1,
  76. allKeys[:1], allVals[:1],
  77. },
  78. // key range with limit
  79. {
  80. []byte("foo"), []byte("foo3"), 4,
  81. allKeys, allVals,
  82. },
  83. }
  84. for i, tt := range tests {
  85. keys, vals := tx.UnsafeRange([]byte("test"), tt.key, tt.endKey, tt.limit)
  86. if !reflect.DeepEqual(keys, tt.wkeys) {
  87. t.Errorf("#%d: keys = %+v, want %+v", i, keys, tt.wkeys)
  88. }
  89. if !reflect.DeepEqual(vals, tt.wvals) {
  90. t.Errorf("#%d: vals = %+v, want %+v", i, vals, tt.wvals)
  91. }
  92. }
  93. }
  94. func TestBatchTxDelete(t *testing.T) {
  95. b := newBackend(tmpPath, time.Hour, 10000)
  96. defer cleanup(b, tmpPath)
  97. tx := b.batchTx
  98. tx.Lock()
  99. defer tx.Unlock()
  100. tx.UnsafeCreateBucket([]byte("test"))
  101. tx.UnsafePut([]byte("test"), []byte("foo"), []byte("bar"))
  102. tx.UnsafeDelete([]byte("test"), []byte("foo"))
  103. // check put result before and after tx is committed
  104. for k := 0; k < 2; k++ {
  105. ks, _ := tx.UnsafeRange([]byte("test"), []byte("foo"), nil, 0)
  106. if len(ks) != 0 {
  107. t.Errorf("keys on foo = %v, want nil", ks)
  108. }
  109. tx.commit(false)
  110. }
  111. }
  112. func TestBatchTxCommit(t *testing.T) {
  113. b := newBackend(tmpPath, time.Hour, 10000)
  114. defer cleanup(b, tmpPath)
  115. tx := b.batchTx
  116. tx.Lock()
  117. tx.UnsafeCreateBucket([]byte("test"))
  118. tx.UnsafePut([]byte("test"), []byte("foo"), []byte("bar"))
  119. tx.Unlock()
  120. tx.Commit()
  121. // check whether put happens via db view
  122. b.db.View(func(tx *bolt.Tx) error {
  123. bucket := tx.Bucket([]byte("test"))
  124. if bucket == nil {
  125. t.Errorf("bucket test does not exit")
  126. return nil
  127. }
  128. v := bucket.Get([]byte("foo"))
  129. if v == nil {
  130. t.Errorf("foo key failed to written in backend")
  131. }
  132. return nil
  133. })
  134. }
  135. func TestBatchTxBatchLimitCommit(t *testing.T) {
  136. // start backend with batch limit 1
  137. b := newBackend(tmpPath, time.Hour, 1)
  138. defer cleanup(b, tmpPath)
  139. tx := b.batchTx
  140. tx.Lock()
  141. tx.UnsafeCreateBucket([]byte("test"))
  142. tx.UnsafePut([]byte("test"), []byte("foo"), []byte("bar"))
  143. tx.Unlock()
  144. // batch limit commit should have been triggered
  145. // check whether put happens via db view
  146. b.db.View(func(tx *bolt.Tx) error {
  147. bucket := tx.Bucket([]byte("test"))
  148. if bucket == nil {
  149. t.Errorf("bucket test does not exit")
  150. return nil
  151. }
  152. v := bucket.Get([]byte("foo"))
  153. if v == nil {
  154. t.Errorf("foo key failed to written in backend")
  155. }
  156. return nil
  157. })
  158. }