kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/storage/keyvalue/keyvalue_test.go (about)

     1  /*
     2   * Copyright 2014 The Kythe Authors. All rights reserved.
     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 keyvalue
    18  
    19  import (
    20  	"bytes"
    21  	"strings"
    22  	"testing"
    23  
    24  	"google.golang.org/protobuf/proto"
    25  
    26  	spb "kythe.io/kythe/proto/storage_go_proto"
    27  )
    28  
    29  func TestKeyRange(t *testing.T) {
    30  	r := KeyRange([]byte("key"))
    31  	if c := bytes.Compare(r.Start, r.End); c != -1 {
    32  		t.Errorf("%s >= %s", r.Start, r.End)
    33  	}
    34  }
    35  
    36  func TestVNameEncoding(t *testing.T) {
    37  	tests := []*spb.VName{
    38  		nil,
    39  		vname("sig", "corpus", "root", "path", "language"),
    40  		vname("", "", "", "", ""),
    41  		vname("", "kythe", "", "", "java"),
    42  	}
    43  
    44  	for _, v := range tests {
    45  		rec, err := encodeVName(v)
    46  		if err != nil {
    47  			t.Errorf("encodeVName: unexpected error: %v", err)
    48  		}
    49  
    50  		res, err := decodeVName(string(rec))
    51  		if err != nil {
    52  			t.Errorf("decodeVName: unexpected error: %v", err)
    53  		}
    54  
    55  		if !proto.Equal(res, v) {
    56  			t.Errorf("Decoded VName doesn't match original\n  orig: %+v\ndecoded: %+v", v, res)
    57  		}
    58  	}
    59  }
    60  
    61  func TestErrors(t *testing.T) {
    62  	tests := []struct {
    63  		entry *spb.Entry
    64  		error string
    65  	}{
    66  		{
    67  			entry(nil, "", nil, "fact", ""),
    68  			"missing source VName",
    69  		},
    70  		{
    71  			entry(vname("sig", "corpus", "root", "path", "language"), "edgeKind", nil, "fact", ""),
    72  			"edgeKind and target Ticket must be both non-empty or empty",
    73  		},
    74  		{
    75  			entry(vname("sig", "corpus", "root", "path", "language"),
    76  				entryKeySepStr, vname("sig2", "", "", "", ""),
    77  				"fact", "value"),
    78  			"edgeKind contains key separator",
    79  		},
    80  		{
    81  			entry(vname("sig", "corpus", "root", "path", "language"), "", nil, entryKeySepStr, ""),
    82  			"factName contains key separator",
    83  		},
    84  		{
    85  			entry(vname("sig", entryKeySepStr, "root", "path", "language"), "", nil, "fact", ""),
    86  			"source VName contains key separator",
    87  		},
    88  		{
    89  			entry(vname("sig", "corpus", "root", "path", "language"),
    90  				"edgeKind", vname("sig2", entryKeySepStr, "", "", ""),
    91  				"fact", "value"),
    92  			"target VName contains key separator",
    93  		},
    94  	}
    95  
    96  	for _, test := range tests {
    97  		key, err := EncodeKey(test.entry.Source, test.entry.FactName, test.entry.EdgeKind, test.entry.Target)
    98  		if err == nil {
    99  			t.Fatalf("Missing expected error containing %q for test {%+v}; got %q", test.error, test.entry, string(key))
   100  		} else if !strings.Contains(err.Error(), test.error) {
   101  			t.Errorf("Expected error containing %q; received %v from {%+v}", test.error, err, test.entry)
   102  		}
   103  	}
   104  }
   105  
   106  func TestKeyEncoding(t *testing.T) {
   107  	tests := []*spb.Entry{
   108  		entry(vname("sig", "corpus", "root", "path", "language"), "", nil, "fact", "value"),
   109  		entry(vname("sig", "corpus", "root", "path", "language"),
   110  			"someEdge", vname("anotherVName", "", "", "", ""),
   111  			"/", ""),
   112  		entry(vname(entryKeyPrefix, "~!@#$%^&*()_+`-={}|:;\"'?/>.<,", "", "", ""), "", nil, "/", ""),
   113  	}
   114  
   115  	for _, test := range tests {
   116  		key, err := EncodeKey(test.Source, test.FactName, test.EdgeKind, test.Target)
   117  		fatalOnErr(t, "Error encoding key: %v", err)
   118  
   119  		if !bytes.HasPrefix(key, entryKeyPrefixBytes) {
   120  			t.Fatalf("Key missing entry prefix: %q", string(key))
   121  		}
   122  
   123  		prefix, err := KeyPrefix(test.Source, test.EdgeKind)
   124  		fatalOnErr(t, "Error creating key prefix: %v", err)
   125  
   126  		if !bytes.HasPrefix(key, prefix) {
   127  			t.Fatalf("Key missing KeyPrefix: %q %q", string(key), string(prefix))
   128  		}
   129  
   130  		entry, err := Entry(key, test.FactValue)
   131  		fatalOnErr(t, "Error creating Entry from key: %v", err)
   132  
   133  		if !proto.Equal(entry, test) {
   134  			t.Errorf("Expected Entry: {%+v}; Got: {%+v}", test, entry)
   135  		}
   136  	}
   137  }
   138  
   139  func fatalOnErr(t *testing.T, msg string, err error) {
   140  	if err != nil {
   141  		t.Fatalf(msg, err)
   142  	}
   143  }
   144  
   145  func vname(signature, corpus, root, path, language string) *spb.VName {
   146  	return &spb.VName{
   147  		Signature: signature,
   148  		Corpus:    corpus,
   149  		Root:      root,
   150  		Path:      path,
   151  		Language:  language,
   152  	}
   153  }
   154  
   155  func entry(src *spb.VName, edgeKind string, target *spb.VName, factName string, factValue string) *spb.Entry {
   156  	return &spb.Entry{
   157  		Source:    src,
   158  		EdgeKind:  edgeKind,
   159  		Target:    target,
   160  		FactName:  factName,
   161  		FactValue: []byte(factValue),
   162  	}
   163  }