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  }