kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/serving/xrefs/assemble/assemble_test.go (about) 1 /* 2 * Copyright 2015 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 assemble 18 19 import ( 20 "context" 21 "testing" 22 23 "kythe.io/kythe/go/test/testutil" 24 25 "google.golang.org/protobuf/proto" 26 27 ipb "kythe.io/kythe/proto/internal_go_proto" 28 srvpb "kythe.io/kythe/proto/serving_go_proto" 29 spb "kythe.io/kythe/proto/storage_go_proto" 30 ) 31 32 func fact(name, value string) *spb.Entry { 33 return &spb.Entry{ 34 FactName: name, 35 FactValue: []byte(value), 36 } 37 } 38 39 func edge(kind, targetSig string) *spb.Entry { 40 return &spb.Entry{ 41 EdgeKind: kind, 42 Target: &spb.VName{ 43 Signature: targetSig, 44 }, 45 FactName: "/", 46 } 47 } 48 49 func TestAppendEntry(t *testing.T) { 50 tests := []struct { 51 entries []*spb.Entry 52 expected *ipb.Source 53 }{{ 54 entries: []*spb.Entry{fact("fact", "value")}, 55 expected: &ipb.Source{ 56 Facts: map[string][]byte{"fact": []byte("value")}, 57 }, 58 }, { 59 entries: []*spb.Entry{edge("kind", "target")}, 60 expected: &ipb.Source{ 61 EdgeGroups: map[string]*ipb.Source_EdgeGroup{ 62 "kind": { 63 Edges: []*ipb.Source_Edge{{Ticket: "kythe:#target"}}, 64 }, 65 }, 66 }, 67 }, { 68 entries: []*spb.Entry{ 69 fact("kind", "first"), 70 fact("kind", "second"), 71 edge("edgeKind", "firstTarget"), 72 edge("edgeKind", "secondTarget"), 73 fact("blah", "blah"), 74 }, 75 expected: &ipb.Source{ 76 Facts: map[string][]byte{ 77 "kind": []byte("second"), 78 "blah": []byte("blah"), 79 }, 80 EdgeGroups: map[string]*ipb.Source_EdgeGroup{ 81 "edgeKind": { 82 Edges: []*ipb.Source_Edge{{ 83 Ticket: "kythe:#firstTarget", 84 }, { 85 Ticket: "kythe:#secondTarget", 86 }}, 87 }, 88 }, 89 }, 90 }} 91 92 for i, test := range tests { 93 src := &ipb.Source{ 94 Facts: make(map[string][]byte), 95 EdgeGroups: make(map[string]*ipb.Source_EdgeGroup), 96 } 97 98 for _, e := range test.entries { 99 AppendEntry(src, e) 100 } 101 102 if err := testutil.DeepEqual(test.expected, src); err != nil { 103 t.Errorf("tests[%d] error: %v", i, err) 104 } 105 } 106 } 107 108 var ctx = context.Background() 109 110 type testESB struct { 111 *EdgeSetBuilder 112 113 PagedEdgeSets []*srvpb.PagedEdgeSet 114 EdgePages []*srvpb.EdgePage 115 } 116 117 func newTestESB(esb *EdgeSetBuilder) *testESB { 118 if esb == nil { 119 esb = new(EdgeSetBuilder) 120 } 121 122 t := &testESB{ 123 EdgeSetBuilder: esb, 124 } 125 t.Output = func(_ context.Context, pes *srvpb.PagedEdgeSet) error { 126 t.PagedEdgeSets = append(t.PagedEdgeSets, pes) 127 return nil 128 } 129 t.OutputPage = func(_ context.Context, pes *srvpb.EdgePage) error { 130 t.EdgePages = append(t.EdgePages, pes) 131 return nil 132 } 133 return t 134 } 135 136 func makeNodes() map[string]*srvpb.Node { 137 m := make(map[string]*srvpb.Node) 138 // TODO(schroederc): fill 139 return m 140 } 141 142 // TODO(schroederc): add some facts for each node 143 var testNodes = makeNodes() 144 145 func getEdgeTargets(tickets ...string) []*srvpb.EdgeGroup_Edge { 146 es := make([]*srvpb.EdgeGroup_Edge, len(tickets)) 147 for i, t := range tickets { 148 es[i] = &srvpb.EdgeGroup_Edge{ 149 Target: getNode(t), 150 } 151 } 152 return es 153 } 154 155 func getNode(t string) *srvpb.Node { 156 n, ok := testNodes[t] 157 if !ok { 158 n = &srvpb.Node{Ticket: t} 159 } 160 return n 161 } 162 163 func TestEdgeSetBuilder(t *testing.T) { 164 tests := []struct { 165 src *srvpb.Node 166 grp *srvpb.EdgeGroup 167 edgeSet *srvpb.PagedEdgeSet 168 edgePages []*srvpb.EdgePage 169 }{{ 170 src: getNode("someSource"), 171 }, { 172 grp: &srvpb.EdgeGroup{ 173 Kind: "someEdgeKind", 174 Edge: getEdgeTargets("kythe:#aTarget"), 175 }, 176 }, { 177 // flush 178 edgeSet: &srvpb.PagedEdgeSet{ 179 Source: getNode("someSource"), 180 Group: []*srvpb.EdgeGroup{{ 181 Kind: "someEdgeKind", 182 Edge: getEdgeTargets("kythe:#aTarget"), 183 }}, 184 TotalEdges: 1, 185 }, 186 }, { 187 src: getNode("someOtherSource"), 188 }, { 189 grp: &srvpb.EdgeGroup{ 190 Kind: "someEdgeKind", 191 Edge: getEdgeTargets( 192 "kythe:#aTarget", 193 "kythe:#anotherTarget", 194 ), 195 }, 196 }, { 197 grp: &srvpb.EdgeGroup{ 198 Kind: "someEdgeKind", 199 Edge: getEdgeTargets( 200 "kythe:#onceMoreWithFeeling", 201 ), 202 }, 203 }, { 204 src: getNode("aThirdSource"), 205 206 // forced flush due to new source 207 edgeSet: &srvpb.PagedEdgeSet{ 208 Source: getNode("someOtherSource"), 209 Group: []*srvpb.EdgeGroup{{ 210 Kind: "someEdgeKind", 211 Edge: getEdgeTargets( 212 "kythe:#aTarget", 213 "kythe:#anotherTarget", 214 "kythe:#onceMoreWithFeeling", 215 ), 216 }}, 217 218 TotalEdges: 3, // fits exactly MaxEdgePageSize 219 }, 220 }, { 221 grp: &srvpb.EdgeGroup{ 222 Kind: "edgeKind123", 223 Edge: getEdgeTargets("kythe:#aTarget"), 224 }, 225 }, { 226 grp: &srvpb.EdgeGroup{ 227 Kind: "edgeKind123", 228 Edge: getEdgeTargets( 229 "kythe:#bTarget", 230 "kythe:#anotherTarget", 231 "kythe:#threeTarget", 232 "kythe:#fourTarget", 233 ), 234 }, 235 236 edgePages: []*srvpb.EdgePage{{ 237 SourceTicket: "aThirdSource", 238 PageKey: "aThirdSource.0000000000", 239 EdgesGroup: &srvpb.EdgeGroup{ 240 Kind: "edgeKind123", 241 Edge: getEdgeTargets( 242 "kythe:#aTarget", 243 "kythe:#bTarget", 244 "kythe:#anotherTarget", 245 ), 246 }, 247 }}, 248 }, { 249 grp: &srvpb.EdgeGroup{ 250 Kind: "edgeKind123", 251 Edge: getEdgeTargets( 252 "kythe:#five", "kythe:#six", "kythe:#seven", "kythe:#eight", "kythe:#nine", 253 ), 254 }, 255 256 edgePages: []*srvpb.EdgePage{{ 257 SourceTicket: "aThirdSource", 258 PageKey: "aThirdSource.0000000001", 259 EdgesGroup: &srvpb.EdgeGroup{ 260 Kind: "edgeKind123", 261 Edge: getEdgeTargets( 262 "kythe:#threeTarget", "kythe:#fourTarget", "kythe:#five", 263 ), 264 }, 265 }, { 266 SourceTicket: "aThirdSource", 267 PageKey: "aThirdSource.0000000002", 268 EdgesGroup: &srvpb.EdgeGroup{ 269 Kind: "edgeKind123", 270 Edge: getEdgeTargets( 271 "kythe:#six", "kythe:#seven", "kythe:#eight", 272 ), 273 }, 274 }}, 275 }, { 276 grp: &srvpb.EdgeGroup{ 277 Kind: "edgeKind123", 278 Edge: getEdgeTargets( 279 "kythe:#ten", "kythe:#eleven", 280 ), 281 }, 282 }, { 283 grp: &srvpb.EdgeGroup{ 284 Kind: "edgeKindFinal", 285 Edge: getEdgeTargets( 286 "kythe:#ten", 287 ), 288 }, 289 290 edgePages: []*srvpb.EdgePage{{ 291 SourceTicket: "aThirdSource", 292 PageKey: "aThirdSource.0000000003", 293 EdgesGroup: &srvpb.EdgeGroup{ 294 Kind: "edgeKind123", 295 Edge: getEdgeTargets( 296 "kythe:#nine", "kythe:#ten", "kythe:#eleven", 297 ), 298 }, 299 }}, 300 }, { 301 grp: &srvpb.EdgeGroup{ 302 Kind: "edgeKindFinal", 303 Edge: getEdgeTargets( 304 "kythe:#two", "kythe:#three", 305 ), 306 }, 307 }, { 308 // flush 309 310 edgeSet: &srvpb.PagedEdgeSet{ 311 TotalEdges: 15, 312 313 Source: getNode("aThirdSource"), 314 Group: []*srvpb.EdgeGroup{{ 315 Kind: "edgeKindFinal", 316 Edge: getEdgeTargets( 317 "kythe:#ten", "kythe:#two", "kythe:#three", 318 ), 319 }}, 320 321 PageIndex: []*srvpb.PageIndex{{ 322 PageKey: "aThirdSource.0000000000", 323 EdgeKind: "edgeKind123", 324 EdgeCount: 3, 325 }, { 326 PageKey: "aThirdSource.0000000001", 327 EdgeKind: "edgeKind123", 328 EdgeCount: 3, 329 }, { 330 PageKey: "aThirdSource.0000000002", 331 EdgeKind: "edgeKind123", 332 EdgeCount: 3, 333 }, { 334 PageKey: "aThirdSource.0000000003", 335 EdgeKind: "edgeKind123", 336 EdgeCount: 3, 337 }}, 338 }, 339 }} 340 341 tESB := newTestESB(&EdgeSetBuilder{ 342 MaxEdgePageSize: 3, 343 }) 344 var edgeSets, edgePages int 345 for _, test := range tests { 346 if test.src != nil { 347 testutil.Fatalf(t, "Failure to StartEdgeSet: %v", 348 tESB.StartEdgeSet(ctx, test.src)) 349 } else if test.grp != nil { 350 testutil.Fatalf(t, "Failure to AddGroup: %v", 351 tESB.AddGroup(ctx, test.grp)) 352 } else { 353 testutil.Fatalf(t, "Failure to Flush: %v", 354 tESB.Flush(ctx)) 355 } 356 357 if test.edgeSet != nil { 358 // Expected a new PagedEdgeSet 359 if edgeSets+1 != len(tESB.PagedEdgeSets) { 360 t.Fatalf("Missing expected PagedEdgeSet: %v", test.edgeSet) 361 } else if found := tESB.PagedEdgeSets[len(tESB.PagedEdgeSets)-1]; !proto.Equal(test.edgeSet, found) { 362 t.Errorf("Expected PagedEdgeSet: %v; found: %v", test.edgeSet, found) 363 } 364 edgeSets++ 365 } else if edgeSets != len(tESB.PagedEdgeSets) { 366 t.Fatalf("Unexpected PagedEdgeSet: %v", tESB.PagedEdgeSets[len(tESB.PagedEdgeSets)-1]) 367 } 368 369 // Expected new EdgePage(s) 370 for i := 0; i < len(test.edgePages); i++ { 371 if edgePages >= len(tESB.EdgePages) { 372 t.Fatalf("Missing expected EdgePages: %v", test.edgePages[i]) 373 } else if err := testutil.DeepEqual(test.edgePages[i], tESB.EdgePages[edgePages]); err != nil { 374 t.Error(err) 375 } 376 edgePages++ 377 } 378 if edgePages != len(tESB.EdgePages) { 379 t.Fatalf("Unexpected EdgePage(s): %v", tESB.EdgePages[edgePages:]) 380 } 381 } 382 }