blob: 85943a279e4c654cf9a9345ba095f4278533cfc1 [file] [log] [blame]
Manish R Jain02eca142018-12-30 19:35:111/*
2 * Copyright 2018 Dgraph Labs, Inc. and Contributors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package badger
18
19import (
20 "context"
21 "fmt"
22 "io/ioutil"
23 "math"
24 "os"
25 "strconv"
26 "strings"
27 "testing"
28
Francesc Campoye051fef2019-06-20 17:35:2629 bpb "github.com/dgraph-io/badger/v2/pb"
30 "github.com/dgraph-io/badger/v2/y"
Manish R Jain02eca142018-12-30 19:35:1131 "github.com/stretchr/testify/require"
32)
33
34func openManaged(dir string) (*DB, error) {
35 opt := DefaultOptions
36 opt.Dir = dir
37 opt.ValueDir = dir
38
39 return OpenManaged(opt)
40}
41
42func keyWithPrefix(prefix string, k int) []byte {
43 return []byte(fmt.Sprintf("%s-%d", prefix, k))
44}
45
46func keyToInt(k []byte) (string, int) {
47 splits := strings.Split(string(k), "-")
48 key, err := strconv.Atoi(splits[1])
49 y.Check(err)
50 return splits[0], key
51}
52
53func value(k int) []byte {
54 return []byte(fmt.Sprintf("%08d", k))
55}
56
57type collector struct {
58 kv []*bpb.KV
59}
60
61func (c *collector) Send(list *bpb.KVList) error {
62 c.kv = append(c.kv, list.Kv...)
63 return nil
64}
65
66var ctxb = context.Background()
67
68func TestStream(t *testing.T) {
Ashish Goswami8c85c272019-06-19 08:21:2269 dir, err := ioutil.TempDir("", "badger-test")
Manish R Jain02eca142018-12-30 19:35:1170 require.NoError(t, err)
71 defer os.RemoveAll(dir)
72
73 db, err := openManaged(dir)
74 require.NoError(t, err)
75
76 var count int
77 for _, prefix := range []string{"p0", "p1", "p2"} {
78 txn := db.NewTransactionAt(math.MaxUint64, true)
79 for i := 1; i <= 100; i++ {
Ashish Goswamie9447c92019-05-28 05:28:3780 require.NoError(t, txn.SetEntry(NewEntry(keyWithPrefix(prefix, i), value(i))))
Manish R Jain02eca142018-12-30 19:35:1181 count++
82 }
83 require.NoError(t, txn.CommitAt(5, nil))
84 }
85
86 stream := db.NewStreamAt(math.MaxUint64)
87 stream.LogPrefix = "Testing"
88 c := &collector{}
89 stream.Send = func(list *bpb.KVList) error {
90 return c.Send(list)
91 }
92
93 // Test case 1. Retrieve everything.
94 err = stream.Orchestrate(ctxb)
95 require.NoError(t, err)
96 require.Equal(t, 300, len(c.kv), "Expected 300. Got: %d", len(c.kv))
97
98 m := make(map[string]int)
99 for _, kv := range c.kv {
100 prefix, ki := keyToInt(kv.Key)
101 expected := value(ki)
102 require.Equal(t, expected, kv.Value)
103 m[prefix]++
104 }
105 require.Equal(t, 3, len(m))
106 for pred, count := range m {
107 require.Equal(t, 100, count, "Count mismatch for pred: %s", pred)
108 }
109
110 // Test case 2. Retrieve only 1 predicate.
111 stream.Prefix = []byte("p1")
112 c.kv = c.kv[:0]
113 err = stream.Orchestrate(ctxb)
114 require.NoError(t, err)
115 require.Equal(t, 100, len(c.kv), "Expected 100. Got: %d", len(c.kv))
116
117 m = make(map[string]int)
118 for _, kv := range c.kv {
119 prefix, ki := keyToInt(kv.Key)
120 expected := value(ki)
121 require.Equal(t, expected, kv.Value)
122 m[prefix]++
123 }
124 require.Equal(t, 1, len(m))
125 for pred, count := range m {
126 require.Equal(t, 100, count, "Count mismatch for pred: %s", pred)
127 }
128
129 // Test case 3. Retrieve select keys within the predicate.
130 c.kv = c.kv[:0]
131 stream.ChooseKey = func(item *Item) bool {
132 _, k := keyToInt(item.Key())
133 return k%2 == 0
134 }
135 err = stream.Orchestrate(ctxb)
136 require.NoError(t, err)
137 require.Equal(t, 50, len(c.kv), "Expected 50. Got: %d", len(c.kv))
138
139 m = make(map[string]int)
140 for _, kv := range c.kv {
141 prefix, ki := keyToInt(kv.Key)
142 expected := value(ki)
143 require.Equal(t, expected, kv.Value)
144 m[prefix]++
145 }
146 require.Equal(t, 1, len(m))
147 for pred, count := range m {
148 require.Equal(t, 50, count, "Count mismatch for pred: %s", pred)
149 }
150
151 // Test case 4. Retrieve select keys from all predicates.
152 c.kv = c.kv[:0]
153 stream.Prefix = []byte{}
154 err = stream.Orchestrate(ctxb)
155 require.NoError(t, err)
156 require.Equal(t, 150, len(c.kv), "Expected 150. Got: %d", len(c.kv))
157
158 m = make(map[string]int)
159 for _, kv := range c.kv {
160 prefix, ki := keyToInt(kv.Key)
161 expected := value(ki)
162 require.Equal(t, expected, kv.Value)
163 m[prefix]++
164 }
165 require.Equal(t, 3, len(m))
166 for pred, count := range m {
167 require.Equal(t, 50, count, "Count mismatch for pred: %s", pred)
168 }
169}