| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- package diskv_test
- import (
- "reflect"
- "runtime"
- "strings"
- "testing"
- "github.com/peterbourgon/diskv"
- )
- var (
- keysTestData = map[string]string{
- "ab01cd01": "When we started building CoreOS",
- "ab01cd02": "we looked at all the various components available to us",
- "ab01cd03": "re-using the best tools",
- "ef01gh04": "and building the ones that did not exist",
- "ef02gh05": "We believe strongly in the Unix philosophy",
- "xxxxxxxx": "tools should be independently useful",
- }
- prefixes = []string{
- "", // all
- "a",
- "ab",
- "ab0",
- "ab01",
- "ab01cd0",
- "ab01cd01",
- "ab01cd01x", // none
- "b", // none
- "b0", // none
- "0", // none
- "01", // none
- "e",
- "ef",
- "efx", // none
- "ef01gh0",
- "ef01gh04",
- "ef01gh05",
- "ef01gh06", // none
- }
- )
- func TestKeysFlat(t *testing.T) {
- transform := func(s string) []string {
- if s == "" {
- t.Fatalf(`transform should not be called with ""`)
- }
- return []string{}
- }
- d := diskv.New(diskv.Options{
- BasePath: "test-data",
- Transform: transform,
- })
- defer d.EraseAll()
- for k, v := range keysTestData {
- d.Write(k, []byte(v))
- }
- checkKeys(t, d.Keys(nil), keysTestData)
- }
- func TestKeysNested(t *testing.T) {
- d := diskv.New(diskv.Options{
- BasePath: "test-data",
- Transform: blockTransform(2),
- })
- defer d.EraseAll()
- for k, v := range keysTestData {
- d.Write(k, []byte(v))
- }
- checkKeys(t, d.Keys(nil), keysTestData)
- }
- func TestKeysPrefixFlat(t *testing.T) {
- d := diskv.New(diskv.Options{
- BasePath: "test-data",
- })
- defer d.EraseAll()
- for k, v := range keysTestData {
- d.Write(k, []byte(v))
- }
- for _, prefix := range prefixes {
- checkKeys(t, d.KeysPrefix(prefix, nil), filterPrefix(keysTestData, prefix))
- }
- }
- func TestKeysPrefixNested(t *testing.T) {
- d := diskv.New(diskv.Options{
- BasePath: "test-data",
- Transform: blockTransform(2),
- })
- defer d.EraseAll()
- for k, v := range keysTestData {
- d.Write(k, []byte(v))
- }
- for _, prefix := range prefixes {
- checkKeys(t, d.KeysPrefix(prefix, nil), filterPrefix(keysTestData, prefix))
- }
- }
- func TestKeysCancel(t *testing.T) {
- d := diskv.New(diskv.Options{
- BasePath: "test-data",
- })
- defer d.EraseAll()
- for k, v := range keysTestData {
- d.Write(k, []byte(v))
- }
- var (
- cancel = make(chan struct{})
- received = 0
- cancelAfter = len(keysTestData) / 2
- )
- for key := range d.Keys(cancel) {
- received++
- if received >= cancelAfter {
- close(cancel)
- runtime.Gosched() // allow walker to detect cancel
- }
- t.Logf("received %d: %q", received, key)
- }
- if want, have := cancelAfter, received; want != have {
- t.Errorf("want %d, have %d")
- }
- }
- func checkKeys(t *testing.T, c <-chan string, want map[string]string) {
- for k := range c {
- if _, ok := want[k]; !ok {
- t.Errorf("%q yielded but not expected", k)
- continue
- }
- delete(want, k)
- t.Logf("%q yielded OK", k)
- }
- if len(want) != 0 {
- t.Errorf("%d expected key(s) not yielded: %s", len(want), strings.Join(flattenKeys(want), ", "))
- }
- }
- func blockTransform(blockSize int) func(string) []string {
- return func(s string) []string {
- var (
- sliceSize = len(s) / blockSize
- pathSlice = make([]string, sliceSize)
- )
- for i := 0; i < sliceSize; i++ {
- from, to := i*blockSize, (i*blockSize)+blockSize
- pathSlice[i] = s[from:to]
- }
- return pathSlice
- }
- }
- func filterPrefix(in map[string]string, prefix string) map[string]string {
- out := map[string]string{}
- for k, v := range in {
- if strings.HasPrefix(k, prefix) {
- out[k] = v
- }
- }
- return out
- }
- func TestFilterPrefix(t *testing.T) {
- input := map[string]string{
- "all": "",
- "and": "",
- "at": "",
- "available": "",
- "best": "",
- "building": "",
- "components": "",
- "coreos": "",
- "did": "",
- "exist": "",
- "looked": "",
- "not": "",
- "ones": "",
- "re-using": "",
- "started": "",
- "that": "",
- "the": "",
- "to": "",
- "tools": "",
- "us": "",
- "various": "",
- "we": "",
- "when": "",
- }
- for prefix, want := range map[string]map[string]string{
- "a": map[string]string{"all": "", "and": "", "at": "", "available": ""},
- "al": map[string]string{"all": ""},
- "all": map[string]string{"all": ""},
- "alll": map[string]string{},
- "c": map[string]string{"components": "", "coreos": ""},
- "co": map[string]string{"components": "", "coreos": ""},
- "com": map[string]string{"components": ""},
- } {
- have := filterPrefix(input, prefix)
- if !reflect.DeepEqual(want, have) {
- t.Errorf("%q: want %v, have %v", prefix, flattenKeys(want), flattenKeys(have))
- }
- }
- }
- func flattenKeys(m map[string]string) []string {
- a := make([]string, 0, len(m))
- for k := range m {
- a = append(a, k)
- }
- return a
- }
|