You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
3.6 KiB

  1. // Copyright (c) 2012, Suryandaru Triandana <syndtr@gmail.com>
  2. // All rights reserved.
  3. //
  4. // Use of this source code is governed by a BSD-style license that can be
  5. // found in the LICENSE file.
  6. package leveldb
  7. import (
  8. "bytes"
  9. "fmt"
  10. "testing"
  11. "testing/quick"
  12. "github.com/syndtr/goleveldb/leveldb/testutil"
  13. )
  14. func TestBatchHeader(t *testing.T) {
  15. f := func(seq uint64, length uint32) bool {
  16. encoded := encodeBatchHeader(nil, seq, int(length))
  17. decSeq, decLength, err := decodeBatchHeader(encoded)
  18. return err == nil && decSeq == seq && decLength == int(length)
  19. }
  20. config := &quick.Config{
  21. Rand: testutil.NewRand(),
  22. }
  23. if err := quick.Check(f, config); err != nil {
  24. t.Error(err)
  25. }
  26. }
  27. type batchKV struct {
  28. kt keyType
  29. k, v []byte
  30. }
  31. func TestBatch(t *testing.T) {
  32. var (
  33. kvs []batchKV
  34. internalLen int
  35. )
  36. batch := new(Batch)
  37. rbatch := new(Batch)
  38. abatch := new(Batch)
  39. testBatch := func(i int, kt keyType, k, v []byte) error {
  40. kv := kvs[i]
  41. if kv.kt != kt {
  42. return fmt.Errorf("invalid key type, index=%d: %d vs %d", i, kv.kt, kt)
  43. }
  44. if !bytes.Equal(kv.k, k) {
  45. return fmt.Errorf("invalid key, index=%d", i)
  46. }
  47. if !bytes.Equal(kv.v, v) {
  48. return fmt.Errorf("invalid value, index=%d", i)
  49. }
  50. return nil
  51. }
  52. f := func(ktr uint8, k, v []byte) bool {
  53. kt := keyType(ktr % 2)
  54. if kt == keyTypeVal {
  55. batch.Put(k, v)
  56. rbatch.Put(k, v)
  57. kvs = append(kvs, batchKV{kt: kt, k: k, v: v})
  58. internalLen += len(k) + len(v) + 8
  59. } else {
  60. batch.Delete(k)
  61. rbatch.Delete(k)
  62. kvs = append(kvs, batchKV{kt: kt, k: k})
  63. internalLen += len(k) + 8
  64. }
  65. if batch.Len() != len(kvs) {
  66. t.Logf("batch.Len: %d vs %d", len(kvs), batch.Len())
  67. return false
  68. }
  69. if batch.internalLen != internalLen {
  70. t.Logf("abatch.internalLen: %d vs %d", internalLen, batch.internalLen)
  71. return false
  72. }
  73. if len(kvs)%1000 == 0 {
  74. if err := batch.replayInternal(testBatch); err != nil {
  75. t.Logf("batch.replayInternal: %v", err)
  76. return false
  77. }
  78. abatch.append(rbatch)
  79. rbatch.Reset()
  80. if abatch.Len() != len(kvs) {
  81. t.Logf("abatch.Len: %d vs %d", len(kvs), abatch.Len())
  82. return false
  83. }
  84. if abatch.internalLen != internalLen {
  85. t.Logf("abatch.internalLen: %d vs %d", internalLen, abatch.internalLen)
  86. return false
  87. }
  88. if err := abatch.replayInternal(testBatch); err != nil {
  89. t.Logf("abatch.replayInternal: %v", err)
  90. return false
  91. }
  92. nbatch := new(Batch)
  93. if err := nbatch.Load(batch.Dump()); err != nil {
  94. t.Logf("nbatch.Load: %v", err)
  95. return false
  96. }
  97. if nbatch.Len() != len(kvs) {
  98. t.Logf("nbatch.Len: %d vs %d", len(kvs), nbatch.Len())
  99. return false
  100. }
  101. if nbatch.internalLen != internalLen {
  102. t.Logf("nbatch.internalLen: %d vs %d", internalLen, nbatch.internalLen)
  103. return false
  104. }
  105. if err := nbatch.replayInternal(testBatch); err != nil {
  106. t.Logf("nbatch.replayInternal: %v", err)
  107. return false
  108. }
  109. }
  110. if len(kvs)%10000 == 0 {
  111. nbatch := new(Batch)
  112. if err := batch.Replay(nbatch); err != nil {
  113. t.Logf("batch.Replay: %v", err)
  114. return false
  115. }
  116. if nbatch.Len() != len(kvs) {
  117. t.Logf("nbatch.Len: %d vs %d", len(kvs), nbatch.Len())
  118. return false
  119. }
  120. if nbatch.internalLen != internalLen {
  121. t.Logf("nbatch.internalLen: %d vs %d", internalLen, nbatch.internalLen)
  122. return false
  123. }
  124. if err := nbatch.replayInternal(testBatch); err != nil {
  125. t.Logf("nbatch.replayInternal: %v", err)
  126. return false
  127. }
  128. }
  129. return true
  130. }
  131. config := &quick.Config{
  132. MaxCount: 40000,
  133. Rand: testutil.NewRand(),
  134. }
  135. if err := quick.Check(f, config); err != nil {
  136. t.Error(err)
  137. }
  138. t.Logf("length=%d internalLen=%d", len(kvs), internalLen)
  139. }