kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/storage/stream/stream_test.go (about) 1 /* 2 * Copyright 2016 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 stream 18 19 import ( 20 "bytes" 21 "encoding/json" 22 "fmt" 23 "testing" 24 25 "kythe.io/kythe/go/platform/delimited" 26 "kythe.io/kythe/go/util/compare" 27 28 "google.golang.org/protobuf/encoding/protojson" 29 "google.golang.org/protobuf/proto" 30 31 cpb "kythe.io/kythe/proto/common_go_proto" 32 spb "kythe.io/kythe/proto/storage_go_proto" 33 ) 34 35 func TestReader(t *testing.T) { 36 r := testBuffer(testEntries) 37 38 var i int 39 if err := NewReader(r)(func(e *spb.Entry) error { 40 if diff := compare.ProtoDiff(testEntries[i], e); diff != "" { 41 t.Errorf("testEntries[%d]: %s", i, diff) 42 } 43 i++ 44 return nil 45 }); err != nil { 46 t.Fatal(err) 47 } 48 49 if i != len(testEntries) { 50 t.Fatalf("Missing %d entries", len(testEntries)-i) 51 } 52 } 53 54 func TestJSONReader(t *testing.T) { 55 r := testJSONBuffer(testEntries) 56 57 var i int 58 if err := NewJSONReader(r)(func(e *spb.Entry) error { 59 if diff := compare.ProtoDiff(testEntries[i], e); diff != "" { 60 t.Errorf("testEntries[%d]: %s", i, diff) 61 } 62 i++ 63 return nil 64 }); err != nil { 65 t.Fatal(err) 66 } 67 68 if i != len(testEntries) { 69 t.Fatalf("Missing %d entries", len(testEntries)-i) 70 } 71 } 72 73 func TestStructuredEntry(t *testing.T) { 74 ms := &cpb.MarkedSource{PreText: "hi"} 75 pbms, err := proto.Marshal(ms) 76 if err != nil { 77 t.Fatalf("Error marshaling MarkedSource: %v", err) 78 } 79 entry := &spb.Entry{ 80 Source: &spb.VName{Signature: "sig"}, 81 FactName: "/kythe/code", 82 FactValue: pbms, 83 } 84 entryJSON, err := json.Marshal((*StructuredEntry)(entry)) 85 if err != nil { 86 t.Fatalf("Error marshaling entry: %v", err) 87 } 88 89 var rawOut richJSONEntry 90 if err := json.Unmarshal(entryJSON, &rawOut); err != nil { 91 t.Fatalf("Error unmarshaling entry (without fact_value): %v", err) 92 } 93 94 var msOut cpb.MarkedSource 95 if err := protojson.Unmarshal(rawOut.FactValue, &msOut); err != nil { 96 t.Fatalf("Error unmarshaling fact_value: %v", err) 97 } 98 99 if !proto.Equal(ms, &msOut) { 100 t.Errorf("Failed to properly encode marked source:\n%s", rawOut.FactValue) 101 } 102 103 var entryOut StructuredEntry 104 if err := json.Unmarshal(entryJSON, &entryOut); err != nil { 105 t.Fatalf("Error unmarshaling StructuredEntry: %v", err) 106 } 107 108 if diff := compare.ProtoDiff(entry, (*spb.Entry)(&entryOut)); diff != "" { 109 t.Errorf("Roundtrip Marshal/Unmarshal failed: \n%v\n%v\n%s", entry, &entryOut, diff) 110 } 111 } 112 113 func BenchmarkReader(b *testing.B) { 114 buf := testBuffer(genEntries(b.N)) 115 b.ResetTimer() 116 if err := NewReader(buf)(func(e *spb.Entry) error { 117 return nil 118 }); err != nil { 119 b.Fatal(err) 120 } 121 } 122 123 func BenchmarkJSONReader(b *testing.B) { 124 buf := testJSONBuffer(genEntries(b.N)) 125 b.ResetTimer() 126 if err := NewJSONReader(buf)(func(e *spb.Entry) error { 127 return nil 128 }); err != nil { 129 b.Fatal(err) 130 } 131 } 132 133 func BenchmarkReaderChannel(b *testing.B) { 134 buf := testBuffer(genEntries(b.N)) 135 b.ResetTimer() 136 for range ReadEntries(buf) { 137 } 138 } 139 140 func BenchmarkJSONReaderChannel(b *testing.B) { 141 buf := testJSONBuffer(genEntries(b.N)) 142 b.ResetTimer() 143 for range ReadJSONEntries(buf) { 144 } 145 } 146 147 func testBuffer(entries []*spb.Entry) *bytes.Buffer { 148 buf := bytes.NewBuffer(nil) 149 wr := delimited.NewWriter(buf) 150 for _, e := range entries { 151 if err := wr.PutProto(e); err != nil { 152 panic(err) 153 } 154 } 155 return buf 156 } 157 158 func testJSONBuffer(entries []*spb.Entry) *bytes.Buffer { 159 buf := bytes.NewBuffer(nil) 160 for _, e := range entries { 161 rec, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(e) 162 if err != nil { 163 panic(err) 164 } 165 buf.Write(rec) 166 } 167 return buf 168 } 169 170 var testEntries = []*spb.Entry{ 171 fact("node0", "kind", "test"), 172 edge("node0", "edge", "node1"), 173 fact("node1", "kind", "anotherTest"), 174 fact("blah", "blah", "eh"), 175 } 176 177 func genEntries(n int) []*spb.Entry { 178 entries := make([]*spb.Entry, n) 179 for i := 0; i < n; i++ { 180 if i%2 == 0 { 181 entries[i] = fact(fmt.Sprintf("node%d", i), "kind", "test") 182 } else { 183 entries[i] = edge(fmt.Sprintf("node%d", i-1), "edgeKind", fmt.Sprintf("node%d", i+1)) 184 } 185 } 186 return entries 187 } 188 189 func fact(signature, factName, factValue string) *spb.Entry { 190 return &spb.Entry{ 191 Source: &spb.VName{Signature: signature}, 192 FactName: factName, 193 FactValue: []byte(factValue), 194 } 195 } 196 197 func edge(signature, edgeKind, targetSig string) *spb.Entry { 198 return &spb.Entry{ 199 Source: &spb.VName{Signature: signature}, 200 EdgeKind: edgeKind, 201 Target: &spb.VName{Signature: targetSig}, 202 FactName: "/", 203 } 204 }