...

Source file src/github.com/peterbourgon/diskv/basic_test.go

Documentation: github.com/peterbourgon/diskv

     1  package diskv
     2  
     3  import (
     4  	"bytes"
     5  	"errors"
     6  	"testing"
     7  	"time"
     8  )
     9  
    10  func cmpBytes(a, b []byte) bool {
    11  	if len(a) != len(b) {
    12  		return false
    13  	}
    14  	for i := 0; i < len(a); i++ {
    15  		if a[i] != b[i] {
    16  			return false
    17  		}
    18  	}
    19  	return true
    20  }
    21  
    22  func (d *Diskv) isCached(key string) bool {
    23  	d.mu.RLock()
    24  	defer d.mu.RUnlock()
    25  	_, ok := d.cache[key]
    26  	return ok
    27  }
    28  
    29  func TestWriteReadErase(t *testing.T) {
    30  	d := New(Options{
    31  		BasePath:     "test-data",
    32  		CacheSizeMax: 1024,
    33  	})
    34  	defer d.EraseAll()
    35  	k, v := "a", []byte{'b'}
    36  	if err := d.Write(k, v); err != nil {
    37  		t.Fatalf("write: %s", err)
    38  	}
    39  	if readVal, err := d.Read(k); err != nil {
    40  		t.Fatalf("read: %s", err)
    41  	} else if bytes.Compare(v, readVal) != 0 {
    42  		t.Fatalf("read: expected %s, got %s", v, readVal)
    43  	}
    44  	if err := d.Erase(k); err != nil {
    45  		t.Fatalf("erase: %s", err)
    46  	}
    47  }
    48  
    49  func TestWRECache(t *testing.T) {
    50  	d := New(Options{
    51  		BasePath:     "test-data",
    52  		CacheSizeMax: 1024,
    53  	})
    54  	defer d.EraseAll()
    55  	k, v := "xxx", []byte{' ', ' ', ' '}
    56  	if d.isCached(k) {
    57  		t.Fatalf("key cached before Write and Read")
    58  	}
    59  	if err := d.Write(k, v); err != nil {
    60  		t.Fatalf("write: %s", err)
    61  	}
    62  	if d.isCached(k) {
    63  		t.Fatalf("key cached before Read")
    64  	}
    65  	if readVal, err := d.Read(k); err != nil {
    66  		t.Fatalf("read: %s", err)
    67  	} else if bytes.Compare(v, readVal) != 0 {
    68  		t.Fatalf("read: expected %s, got %s", v, readVal)
    69  	}
    70  	for i := 0; i < 10 && !d.isCached(k); i++ {
    71  		time.Sleep(10 * time.Millisecond)
    72  	}
    73  	if !d.isCached(k) {
    74  		t.Fatalf("key not cached after Read")
    75  	}
    76  	if err := d.Erase(k); err != nil {
    77  		t.Fatalf("erase: %s", err)
    78  	}
    79  	if d.isCached(k) {
    80  		t.Fatalf("key cached after Erase")
    81  	}
    82  }
    83  
    84  func TestStrings(t *testing.T) {
    85  	d := New(Options{
    86  		BasePath:     "test-data",
    87  		CacheSizeMax: 1024,
    88  	})
    89  	defer d.EraseAll()
    90  
    91  	keys := map[string]bool{"a": false, "b": false, "c": false, "d": false}
    92  	v := []byte{'1'}
    93  	for k := range keys {
    94  		if err := d.Write(k, v); err != nil {
    95  			t.Fatalf("write: %s: %s", k, err)
    96  		}
    97  	}
    98  
    99  	for k := range d.Keys(nil) {
   100  		if _, present := keys[k]; present {
   101  			t.Logf("got: %s", k)
   102  			keys[k] = true
   103  		} else {
   104  			t.Fatalf("strings() returns unknown key: %s", k)
   105  		}
   106  	}
   107  
   108  	for k, found := range keys {
   109  		if !found {
   110  			t.Errorf("never got %s", k)
   111  		}
   112  	}
   113  }
   114  
   115  func TestZeroByteCache(t *testing.T) {
   116  	d := New(Options{
   117  		BasePath:     "test-data",
   118  		CacheSizeMax: 0,
   119  	})
   120  	defer d.EraseAll()
   121  
   122  	k, v := "a", []byte{'1', '2', '3'}
   123  	if err := d.Write(k, v); err != nil {
   124  		t.Fatalf("Write: %s", err)
   125  	}
   126  
   127  	if d.isCached(k) {
   128  		t.Fatalf("key cached, expected not-cached")
   129  	}
   130  
   131  	if _, err := d.Read(k); err != nil {
   132  		t.Fatalf("Read: %s", err)
   133  	}
   134  
   135  	if d.isCached(k) {
   136  		t.Fatalf("key cached, expected not-cached")
   137  	}
   138  }
   139  
   140  func TestOneByteCache(t *testing.T) {
   141  	d := New(Options{
   142  		BasePath:     "test-data",
   143  		CacheSizeMax: 1,
   144  	})
   145  	defer d.EraseAll()
   146  
   147  	k1, k2, v1, v2 := "a", "b", []byte{'1'}, []byte{'1', '2'}
   148  	if err := d.Write(k1, v1); err != nil {
   149  		t.Fatal(err)
   150  	}
   151  
   152  	if v, err := d.Read(k1); err != nil {
   153  		t.Fatal(err)
   154  	} else if !cmpBytes(v, v1) {
   155  		t.Fatalf("Read: expected %s, got %s", string(v1), string(v))
   156  	}
   157  
   158  	for i := 0; i < 10 && !d.isCached(k1); i++ {
   159  		time.Sleep(10 * time.Millisecond)
   160  	}
   161  	if !d.isCached(k1) {
   162  		t.Fatalf("expected 1-byte value to be cached, but it wasn't")
   163  	}
   164  
   165  	if err := d.Write(k2, v2); err != nil {
   166  		t.Fatal(err)
   167  	}
   168  	if _, err := d.Read(k2); err != nil {
   169  		t.Fatalf("--> %s", err)
   170  	}
   171  
   172  	for i := 0; i < 10 && (!d.isCached(k1) || d.isCached(k2)); i++ {
   173  		time.Sleep(10 * time.Millisecond) // just wait for lazy-cache
   174  	}
   175  	if !d.isCached(k1) {
   176  		t.Fatalf("1-byte value was uncached for no reason")
   177  	}
   178  
   179  	if d.isCached(k2) {
   180  		t.Fatalf("2-byte value was cached, but cache max size is 1")
   181  	}
   182  }
   183  
   184  func TestStaleCache(t *testing.T) {
   185  	d := New(Options{
   186  		BasePath:     "test-data",
   187  		CacheSizeMax: 1,
   188  	})
   189  	defer d.EraseAll()
   190  
   191  	k, first, second := "a", "first", "second"
   192  	if err := d.Write(k, []byte(first)); err != nil {
   193  		t.Fatal(err)
   194  	}
   195  
   196  	v, err := d.Read(k)
   197  	if err != nil {
   198  		t.Fatal(err)
   199  	}
   200  	if string(v) != first {
   201  		t.Errorf("expected '%s', got '%s'", first, v)
   202  	}
   203  
   204  	if err := d.Write(k, []byte(second)); err != nil {
   205  		t.Fatal(err)
   206  	}
   207  
   208  	v, err = d.Read(k)
   209  	if err != nil {
   210  		t.Fatal(err)
   211  	}
   212  
   213  	if string(v) != second {
   214  		t.Errorf("expected '%s', got '%s'", second, v)
   215  	}
   216  }
   217  
   218  func TestHas(t *testing.T) {
   219  	d := New(Options{
   220  		BasePath:     "test-data",
   221  		CacheSizeMax: 1024,
   222  	})
   223  	defer d.EraseAll()
   224  
   225  	for k, v := range map[string]string{
   226  		"a":      "1",
   227  		"foo":    "2",
   228  		"012345": "3",
   229  	} {
   230  		d.Write(k, []byte(v))
   231  	}
   232  
   233  	d.Read("foo") // cache one of them
   234  	if !d.isCached("foo") {
   235  		t.Errorf("'foo' didn't get cached")
   236  	}
   237  
   238  	for _, tuple := range []struct {
   239  		key      string
   240  		expected bool
   241  	}{
   242  		{"a", true},
   243  		{"b", false},
   244  		{"foo", true},
   245  		{"bar", false},
   246  		{"01234", false},
   247  		{"012345", true},
   248  		{"0123456", false},
   249  	} {
   250  		if expected, got := tuple.expected, d.Has(tuple.key); expected != got {
   251  			t.Errorf("Has(%s): expected %v, got %v", tuple.key, expected, got)
   252  		}
   253  	}
   254  }
   255  
   256  type BrokenReader struct{}
   257  
   258  func (BrokenReader) Read(p []byte) (n int, err error) {
   259  	return 0, errors.New("failed to read")
   260  }
   261  
   262  func TestRemovesIncompleteFiles(t *testing.T) {
   263  	opts := Options{
   264  		BasePath:     "test-data",
   265  		CacheSizeMax: 1024,
   266  	}
   267  	d := New(opts)
   268  	defer d.EraseAll()
   269  
   270  	key, stream, sync := "key", BrokenReader{}, false
   271  
   272  	if err := d.WriteStream(key, stream, sync); err == nil {
   273  		t.Fatalf("Expected i/o copy error, none received.")
   274  	}
   275  
   276  	if _, err := d.Read(key); err == nil {
   277  		t.Fatal("Could read the key, but it shouldn't exist")
   278  	}
   279  }
   280  
   281  func TestTempDir(t *testing.T) {
   282  	opts := Options{
   283  		BasePath:     "test-data",
   284  		TempDir:      "test-data-temp",
   285  		CacheSizeMax: 1024,
   286  	}
   287  	d := New(opts)
   288  	defer d.EraseAll()
   289  
   290  	k, v := "a", []byte{'b'}
   291  	if err := d.Write(k, v); err != nil {
   292  		t.Fatalf("write: %s", err)
   293  	}
   294  	if readVal, err := d.Read(k); err != nil {
   295  		t.Fatalf("read: %s", err)
   296  	} else if bytes.Compare(v, readVal) != 0 {
   297  		t.Fatalf("read: expected %s, got %s", v, readVal)
   298  	}
   299  	if err := d.Erase(k); err != nil {
   300  		t.Fatalf("erase: %s", err)
   301  	}
   302  }
   303  
   304  type CrashingReader struct{}
   305  
   306  func (CrashingReader) Read(p []byte) (n int, err error) {
   307  	panic("System has crashed while reading the stream")
   308  }
   309  
   310  func TestAtomicWrite(t *testing.T) {
   311  	opts := Options{
   312  		BasePath: "test-data",
   313  		// Test would fail if TempDir is not set here.
   314  		TempDir:      "test-data-temp",
   315  		CacheSizeMax: 1024,
   316  	}
   317  	d := New(opts)
   318  	defer d.EraseAll()
   319  
   320  	key := "key"
   321  	func() {
   322  		defer func() {
   323  			recover() // Ignore panicking error
   324  		}()
   325  
   326  		stream := CrashingReader{}
   327  		d.WriteStream(key, stream, false)
   328  	}()
   329  
   330  	if d.Has(key) {
   331  		t.Fatal("Has key, but it shouldn't exist")
   332  	}
   333  	if _, ok := <-d.Keys(nil); ok {
   334  		t.Fatal("Store isn't empty")
   335  	}
   336  }
   337  

View as plain text