github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/pkg/sorted/kvtest/kvtest.go (about) 1 /* 2 Copyright 2013 The Camlistore Authors 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 17 // Package kvtest tests sorted.KeyValue implementations. 18 package kvtest 19 20 import ( 21 "reflect" 22 "testing" 23 24 "camlistore.org/pkg/sorted" 25 "camlistore.org/pkg/test" 26 ) 27 28 func TestSorted(t *testing.T, kv sorted.KeyValue) { 29 defer test.TLog(t)() 30 if !isEmpty(t, kv) { 31 t.Fatal("kv for test is expected to be initially empty") 32 } 33 set := func(k, v string) { 34 if err := kv.Set(k, v); err != nil { 35 t.Fatalf("Error setting %q to %q: %v", k, v, err) 36 } 37 } 38 set("foo", "bar") 39 if isEmpty(t, kv) { 40 t.Fatalf("iterator reports the kv is empty after adding foo=bar; iterator must be broken") 41 } 42 if v, err := kv.Get("foo"); err != nil || v != "bar" { 43 t.Errorf("get(foo) = %q, %v; want bar", v, err) 44 } 45 if v, err := kv.Get("NOT_EXIST"); err != sorted.ErrNotFound { 46 t.Errorf("get(NOT_EXIST) = %q, %v; want error sorted.ErrNotFound", v, err) 47 } 48 for i := 0; i < 2; i++ { 49 if err := kv.Delete("foo"); err != nil { 50 t.Errorf("Delete(foo) (on loop %d/2) returned error %v", i+1, err) 51 } 52 } 53 set("a", "av") 54 set("b", "bv") 55 set("c", "cv") 56 testEnumerate(t, kv, "", "", "av", "bv", "cv") 57 testEnumerate(t, kv, "a", "", "av", "bv", "cv") 58 testEnumerate(t, kv, "b", "", "bv", "cv") 59 testEnumerate(t, kv, "a", "c", "av", "bv") 60 testEnumerate(t, kv, "a", "b", "av") 61 testEnumerate(t, kv, "a", "a") 62 testEnumerate(t, kv, "d", "") 63 testEnumerate(t, kv, "d", "e") 64 65 // Verify that < comparison works identically for all DBs (because it is affected by collation rules) 66 // http://postgresql.1045698.n5.nabble.com/String-comparison-and-the-SQL-standard-td5740721.html 67 set("foo|abc", "foo|abcv") 68 testEnumerate(t, kv, "foo|", "", "foo|abcv") 69 testEnumerate(t, kv, "foo|", "foo}", "foo|abcv") 70 71 // Verify that the value isn't being used instead of the key in the range comparison. 72 set("y", "x:foo") 73 testEnumerate(t, kv, "x:", "x~") 74 75 // TODO: test batch commits 76 } 77 78 func testEnumerate(t *testing.T, kv sorted.KeyValue, start, end string, want ...string) { 79 var got []string 80 it := kv.Find(start, end) 81 for it.Next() { 82 key, val := it.Key(), it.Value() 83 keyb, valb := it.KeyBytes(), it.ValueBytes() 84 if key != string(keyb) { 85 t.Errorf("Key and KeyBytes disagree: %q vs %q", key, keyb) 86 } 87 if val != string(valb) { 88 t.Errorf("Value and ValueBytes disagree: %q vs %q", val, valb) 89 } 90 if key+"v" != val { 91 t.Errorf("iterator returned unexpected pair for test: %q, %q", key, val) 92 } 93 got = append(got, val) 94 } 95 err := it.Close() 96 if err != nil { 97 t.Errorf("for enumerate of (%q, %q), Close error: %v", start, end, err) 98 } 99 if !reflect.DeepEqual(got, want) { 100 t.Errorf("for enumerate of (%q, %q), got: %q; want %q", start, end, got, want) 101 } 102 } 103 104 func isEmpty(t *testing.T, kv sorted.KeyValue) bool { 105 it := kv.Find("", "") 106 hasRow := it.Next() 107 if err := it.Close(); err != nil { 108 t.Fatalf("Error closing iterator while testing for emptiness: %v", err) 109 } 110 return !hasRow 111 }