fork of https://github.com/sourcegraph/zoekt
0

Configure Feed

Select the types of activity you want to include in your feed.

1package main 2 3import ( 4 "context" 5 "errors" 6 "fmt" 7 "net/url" 8 "os" 9 "os/exec" 10 "path/filepath" 11 "sort" 12 "strings" 13 "testing" 14 "time" 15 16 "github.com/sourcegraph/log/logtest" 17 proto "github.com/sourcegraph/zoekt/cmd/zoekt-sourcegraph-indexserver/protos/sourcegraph/zoekt/configuration/v1" 18 "github.com/sourcegraph/zoekt/ctags" 19 "google.golang.org/grpc" 20 "google.golang.org/protobuf/testing/protocmp" 21 "google.golang.org/protobuf/types/known/timestamppb" 22 23 "github.com/google/go-cmp/cmp" 24 "github.com/google/go-cmp/cmp/cmpopts" 25 26 "github.com/sourcegraph/zoekt" 27) 28 29func TestIterateIndexOptions_Fingerprint(t *testing.T) { 30 fingerprintV0 := &proto.Fingerprint{ 31 Identifier: 100, 32 GeneratedAt: timestamppb.New(time.Unix(100, 0)), 33 } 34 35 fingerprintV1 := &proto.Fingerprint{ 36 Identifier: 101, 37 GeneratedAt: timestamppb.New(time.Unix(101, 0)), 38 } 39 40 fingerprintV2 := &proto.Fingerprint{ 41 Identifier: 102, 42 GeneratedAt: timestamppb.New(time.Unix(102, 0)), 43 } 44 45 mkSearchConfigurationResponse := func(fingerprint *proto.Fingerprint, repoIDs ...int32) *proto.SearchConfigurationResponse { 46 repositories := make([]*proto.ZoektIndexOptions, 0, len(repoIDs)) 47 for _, repoID := range repoIDs { 48 repositories = append(repositories, &proto.ZoektIndexOptions{ 49 RepoId: repoID, 50 }) 51 } 52 53 return &proto.SearchConfigurationResponse{ 54 UpdatedOptions: repositories, 55 Fingerprint: fingerprint, 56 } 57 } 58 59 grpcClient := &mockGRPCClient{ 60 mockList: func(_ context.Context, in *proto.ListRequest, opts ...grpc.CallOption) (*proto.ListResponse, error) { 61 return &proto.ListResponse{ 62 RepoIds: []int32{1, 2, 3}, 63 }, nil 64 }, 65 } 66 67 clientOpts := []SourcegraphClientOption{ 68 WithBatchSize(1), 69 } 70 71 testURL := url.URL{Scheme: "http", Host: "does.not.matter", Path: "/"} 72 sg := newSourcegraphClient(&testURL, "", grpcClient, clientOpts...) 73 74 type step struct { 75 name string 76 77 wantFingerprint *proto.Fingerprint 78 returnFingerprint *proto.Fingerprint 79 returnErr error 80 skipCheckingRepoIDs bool 81 } 82 83 for _, step := range []step{ 84 { 85 name: "first call", 86 wantFingerprint: nil, 87 returnFingerprint: fingerprintV0, 88 }, 89 { 90 name: "second call (should provide fingerprint from last time)", 91 wantFingerprint: fingerprintV0, 92 returnFingerprint: fingerprintV1, 93 }, 94 { 95 name: "error", 96 wantFingerprint: fingerprintV1, 97 returnFingerprint: fingerprintV2, 98 99 returnErr: fmt.Errorf("boom"), 100 skipCheckingRepoIDs: true, // don't bother checking repoIDs if we expect an error 101 }, 102 { 103 name: "call after error (should ignore fingerprint from last time, and provide the older one)", 104 wantFingerprint: fingerprintV1, 105 returnFingerprint: fingerprintV2, 106 }, 107 } { 108 t.Run(step.name, func(t *testing.T) { 109 called := false 110 grpcClient.mockSearchConfiguration = func(_ context.Context, in *proto.SearchConfigurationRequest, opts ...grpc.CallOption) (*proto.SearchConfigurationResponse, error) { 111 called = true 112 113 diff := cmp.Diff(step.wantFingerprint, in.GetFingerprint(), protocmp.Transform()) 114 if diff != "" { 115 t.Fatalf("unexpected fingerprint (-want +got):\n%s", diff) 116 } 117 118 return mkSearchConfigurationResponse(step.returnFingerprint, in.RepoIds...), step.returnErr 119 } 120 121 result, err := sg.List(context.Background(), nil) 122 if err != nil { 123 t.Fatalf("unexpected error from List: %v", err) 124 } 125 126 var iteratedIDs []uint32 127 result.IterateIndexOptions(func(options IndexOptions) { 128 iteratedIDs = append(iteratedIDs, options.RepoID) 129 }) 130 131 if !called { 132 t.Fatal("expected SearchConfiguration to be called") 133 } 134 135 if step.skipCheckingRepoIDs { 136 return 137 } 138 139 sort.Slice(iteratedIDs, func(i, j int) bool { 140 return iteratedIDs[i] < iteratedIDs[j] 141 }) 142 143 expectedIDs := []uint32{1, 2, 3} 144 sort.Slice(expectedIDs, func(i, j int) bool { 145 return expectedIDs[i] < expectedIDs[j] 146 }) 147 148 if diff := cmp.Diff(expectedIDs, iteratedIDs); diff != "" { 149 t.Fatalf("unexpected repo ids (-want +got):\n%s", diff) 150 } 151 }) 152 } 153} 154 155func TestGetIndexOptions(t *testing.T) { 156 157 type testCase struct { 158 name string 159 response *proto.SearchConfigurationResponse 160 want *IndexOptions 161 wantErr string 162 } 163 164 for _, tc := range []testCase{ 165 { 166 name: "symbols, large files", 167 response: &proto.SearchConfigurationResponse{ 168 UpdatedOptions: []*proto.ZoektIndexOptions{ 169 { 170 Symbols: true, 171 LargeFiles: []string{"foo", "bar"}, 172 }, 173 }, 174 }, 175 want: &IndexOptions{ 176 Symbols: true, 177 LargeFiles: []string{"foo", "bar"}, 178 }, 179 }, 180 { 181 name: "no symbols , large files", 182 response: &proto.SearchConfigurationResponse{ 183 UpdatedOptions: []*proto.ZoektIndexOptions{ 184 { 185 Symbols: true, 186 LargeFiles: []string{"foo", "bar"}, 187 }, 188 }, 189 }, 190 want: &IndexOptions{ 191 Symbols: true, 192 LargeFiles: []string{"foo", "bar"}, 193 }, 194 }, 195 196 { 197 name: "empty", 198 response: nil, 199 want: nil, 200 }, 201 202 { 203 name: "symbols", 204 response: &proto.SearchConfigurationResponse{ 205 UpdatedOptions: []*proto.ZoektIndexOptions{ 206 { 207 Symbols: true, 208 }, 209 }, 210 }, 211 want: &IndexOptions{ 212 Symbols: true, 213 }, 214 }, 215 { 216 name: "repoID", 217 response: &proto.SearchConfigurationResponse{ 218 UpdatedOptions: []*proto.ZoektIndexOptions{ 219 { 220 RepoId: 123, 221 }, 222 }, 223 }, 224 want: &IndexOptions{ 225 RepoID: 123, 226 }, 227 }, 228 { 229 name: "error", 230 response: &proto.SearchConfigurationResponse{ 231 UpdatedOptions: []*proto.ZoektIndexOptions{ 232 { 233 Error: "boom", 234 }, 235 }, 236 }, 237 want: nil, 238 wantErr: "boom", 239 }, 240 } { 241 called := false 242 mockClient := &mockGRPCClient{ 243 mockSearchConfiguration: func(_ context.Context, _ *proto.SearchConfigurationRequest, _ ...grpc.CallOption) (*proto.SearchConfigurationResponse, error) { 244 called = true 245 return tc.response, nil 246 }, 247 } 248 249 testURL := &url.URL{ 250 Scheme: "http", 251 Host: "does.not.matter", 252 Path: "/", 253 } 254 255 sg := newSourcegraphClient( 256 testURL, 257 "", 258 mockClient, 259 ) 260 261 var got IndexOptions 262 var err error 263 sg.ForceIterateIndexOptions(func(o IndexOptions) { 264 got = o 265 }, func(_ uint32, e error) { 266 err = e 267 }, 123) 268 269 if !called { 270 t.Fatal("expected mock to be called") 271 } 272 273 if err != nil { 274 if tc.wantErr == "" || !strings.Contains(err.Error(), tc.wantErr) { 275 t.Fatalf("unexpected error: %v", err) 276 } 277 } 278 279 if tc.want == nil { 280 continue 281 } 282 283 tc.want.CloneURL = sg.getCloneURL(got.Name) 284 285 if diff := cmp.Diff(tc.want, &got, cmpopts.EquateEmpty()); diff != "" { 286 t.Errorf("mismatch (-want +got):\n%s", diff) 287 } 288 } 289 290 // Mimic our fingerprint API, which doesn't return anything if the 291 // repo hasn't changed. 292 t.Run("unchanged", func(t *testing.T) { 293 294 called := false 295 mockClient := &mockGRPCClient{ 296 mockSearchConfiguration: func(_ context.Context, _ *proto.SearchConfigurationRequest, _ ...grpc.CallOption) (*proto.SearchConfigurationResponse, error) { 297 called = true 298 return nil, nil 299 }, 300 } 301 302 testURL := &url.URL{ 303 Scheme: "http", 304 Host: "does.not.matter", 305 Path: "/", 306 } 307 308 sg := newSourcegraphClient( 309 testURL, 310 "", 311 mockClient, 312 ) 313 gotAtLeastOneOption := false 314 var err error 315 sg.ForceIterateIndexOptions(func(_ IndexOptions) { 316 gotAtLeastOneOption = true 317 }, func(_ uint32, e error) { 318 err = e 319 }, 123) 320 321 if !called { 322 t.Fatal("expected mock to be called") 323 } 324 325 if err != nil { 326 t.Fatalf("unexpected error: %v", err) 327 } 328 329 if gotAtLeastOneOption { 330 t.Fatalf("expected no options, got %v", gotAtLeastOneOption) 331 } 332 }) 333 334 var response *proto.SearchConfigurationResponse 335 mockClient := &mockGRPCClient{ 336 mockSearchConfiguration: func(_ context.Context, req *proto.SearchConfigurationRequest, _ ...grpc.CallOption) (*proto.SearchConfigurationResponse, error) { 337 if len(req.GetRepoIds()) == 0 || req.GetRepoIds()[0] != 123 { 338 return nil, errors.New("invalid repo id") 339 } 340 return response, nil 341 }, 342 } 343 344 sg := newSourcegraphClient(&url.URL{Path: "/"}, "", mockClient, WithBatchSize(0)) 345 346 cases := []struct { 347 Response *proto.SearchConfigurationResponse 348 *IndexOptions 349 }{ 350 { 351 Response: &proto.SearchConfigurationResponse{ 352 UpdatedOptions: []*proto.ZoektIndexOptions{ 353 { 354 Symbols: true, 355 LargeFiles: []string{"foo", "bar"}, 356 }, 357 }, 358 }, 359 IndexOptions: &IndexOptions{ 360 Symbols: true, 361 LargeFiles: []string{"foo", "bar"}, 362 Branches: []zoekt.RepositoryBranch{}, 363 LanguageMap: map[string]ctags.CTagsParserType{}, 364 }, 365 }, 366 367 { 368 Response: &proto.SearchConfigurationResponse{ 369 UpdatedOptions: []*proto.ZoektIndexOptions{ 370 { 371 Symbols: false, 372 LargeFiles: []string{"foo", "bar"}, 373 }, 374 }, 375 }, 376 IndexOptions: &IndexOptions{ 377 LargeFiles: []string{"foo", "bar"}, 378 Branches: []zoekt.RepositoryBranch{}, 379 LanguageMap: map[string]ctags.CTagsParserType{}, 380 }, 381 }, 382 383 { 384 Response: &proto.SearchConfigurationResponse{}, 385 }, 386 387 { 388 Response: &proto.SearchConfigurationResponse{ 389 UpdatedOptions: []*proto.ZoektIndexOptions{ 390 { 391 Symbols: true, 392 }, 393 }, 394 }, 395 IndexOptions: &IndexOptions{ 396 Symbols: true, 397 Branches: []zoekt.RepositoryBranch{}, 398 LanguageMap: map[string]ctags.CTagsParserType{}, 399 }, 400 }, 401 402 { 403 Response: &proto.SearchConfigurationResponse{ 404 UpdatedOptions: []*proto.ZoektIndexOptions{ 405 { 406 RepoId: 123, 407 }, 408 }, 409 }, 410 IndexOptions: &IndexOptions{ 411 RepoID: 123, 412 Branches: []zoekt.RepositoryBranch{}, 413 LanguageMap: map[string]ctags.CTagsParserType{}, 414 }, 415 }, 416 417 { 418 Response: &proto.SearchConfigurationResponse{ 419 UpdatedOptions: []*proto.ZoektIndexOptions{ 420 { 421 Error: "boom", 422 }, 423 }, 424 }, 425 }, 426 } 427 428 for _, tc := range cases { 429 response = tc.Response 430 431 var got IndexOptions 432 var err error 433 sg.ForceIterateIndexOptions(func(o IndexOptions) { 434 got = o 435 }, func(_ uint32, e error) { 436 err = e 437 }, 123) 438 439 if err != nil && tc.IndexOptions != nil { 440 t.Fatalf("unexpected error: %v", err) 441 } 442 if tc.IndexOptions == nil { 443 continue 444 } 445 446 tc.IndexOptions.CloneURL = sg.getCloneURL(got.Name) 447 448 if d := cmp.Diff(*tc.IndexOptions, got); d != "" { 449 t.Errorf("mismatch (-want +got):\n%s", d) 450 } 451 } 452 453 // Special case our fingerprint API which doesn't return anything if the 454 // repo hasn't changed. 455 t.Run("unchanged", func(t *testing.T) { 456 response = &proto.SearchConfigurationResponse{} 457 458 got := false 459 var err error 460 sg.ForceIterateIndexOptions(func(_ IndexOptions) { 461 got = true 462 }, func(_ uint32, e error) { 463 err = e 464 }, 123) 465 if err != nil { 466 t.Fatalf("unexpected error: %v", err) 467 } 468 469 if got { 470 t.Fatalf("expected no options, got %v", got) 471 } 472 }) 473} 474 475func TestIndex(t *testing.T) { 476 cases := []struct { 477 name string 478 args indexArgs 479 mockRepositoryMetadata *zoekt.Repository 480 want []string 481 }{{ 482 name: "minimal", 483 args: indexArgs{ 484 IndexOptions: IndexOptions{ 485 Name: "test/repo", 486 CloneURL: "http://api.test/.internal/git/test/repo", 487 Branches: []zoekt.RepositoryBranch{{Name: "HEAD", Version: "deadbeef"}}, 488 }, 489 }, 490 want: []string{ 491 "git -c init.defaultBranch=nonExistentBranchBB0FOFCH32 init --bare $TMPDIR/test%2Frepo.git", 492 "git -C $TMPDIR/test%2Frepo.git -c protocol.version=2 -c http.extraHeader=X-Sourcegraph-Actor-UID: internal fetch --depth=1 http://api.test/.internal/git/test/repo deadbeef", 493 "git -C $TMPDIR/test%2Frepo.git update-ref HEAD deadbeef", 494 "git -C $TMPDIR/test%2Frepo.git config zoekt.archived 0", 495 "git -C $TMPDIR/test%2Frepo.git config zoekt.fork 0", 496 "git -C $TMPDIR/test%2Frepo.git config zoekt.name test/repo", 497 "git -C $TMPDIR/test%2Frepo.git config zoekt.priority 0", 498 "git -C $TMPDIR/test%2Frepo.git config zoekt.public 0", 499 "git -C $TMPDIR/test%2Frepo.git config zoekt.repoid 0", 500 "zoekt-git-index -submodules=false -branches HEAD -disable_ctags $TMPDIR/test%2Frepo.git", 501 }, 502 }, { 503 name: "minimal-id", 504 args: indexArgs{ 505 IndexOptions: IndexOptions{ 506 Name: "test/repo", 507 CloneURL: "http://api.test/.internal/git/test/repo", 508 Branches: []zoekt.RepositoryBranch{{Name: "HEAD", Version: "deadbeef"}}, 509 RepoID: 123, 510 }, 511 }, 512 want: []string{ 513 "git -c init.defaultBranch=nonExistentBranchBB0FOFCH32 init --bare $TMPDIR/test%2Frepo.git", 514 "git -C $TMPDIR/test%2Frepo.git -c protocol.version=2 -c http.extraHeader=X-Sourcegraph-Actor-UID: internal fetch --depth=1 http://api.test/.internal/git/test/repo deadbeef", 515 "git -C $TMPDIR/test%2Frepo.git update-ref HEAD deadbeef", 516 "git -C $TMPDIR/test%2Frepo.git config zoekt.archived 0", 517 "git -C $TMPDIR/test%2Frepo.git config zoekt.fork 0", 518 "git -C $TMPDIR/test%2Frepo.git config zoekt.name test/repo", 519 "git -C $TMPDIR/test%2Frepo.git config zoekt.priority 0", 520 "git -C $TMPDIR/test%2Frepo.git config zoekt.public 0", 521 "git -C $TMPDIR/test%2Frepo.git config zoekt.repoid 123", 522 "zoekt-git-index -submodules=false -branches HEAD -disable_ctags $TMPDIR/test%2Frepo.git", 523 }, 524 }, { 525 name: "all", 526 args: indexArgs{ 527 Incremental: true, 528 IndexDir: "/data/index", 529 Parallelism: 4, 530 FileLimit: 123, 531 IndexOptions: IndexOptions{ 532 Name: "test/repo", 533 CloneURL: "http://api.test/.internal/git/test/repo", 534 LargeFiles: []string{"foo", "bar"}, 535 Symbols: true, 536 Branches: []zoekt.RepositoryBranch{ 537 {Name: "HEAD", Version: "deadbeef"}, 538 {Name: "dev", Version: "feebdaed"}, // ignored for archive 539 }, 540 }, 541 }, 542 want: []string{ 543 "git -c init.defaultBranch=nonExistentBranchBB0FOFCH32 init --bare $TMPDIR/test%2Frepo.git", 544 "git -C $TMPDIR/test%2Frepo.git -c protocol.version=2 -c http.extraHeader=X-Sourcegraph-Actor-UID: internal fetch --depth=1 http://api.test/.internal/git/test/repo deadbeef feebdaed", 545 "git -C $TMPDIR/test%2Frepo.git update-ref HEAD deadbeef", 546 "git -C $TMPDIR/test%2Frepo.git update-ref refs/heads/dev feebdaed", 547 "git -C $TMPDIR/test%2Frepo.git config zoekt.archived 0", 548 "git -C $TMPDIR/test%2Frepo.git config zoekt.fork 0", 549 "git -C $TMPDIR/test%2Frepo.git config zoekt.name test/repo", 550 "git -C $TMPDIR/test%2Frepo.git config zoekt.priority 0", 551 "git -C $TMPDIR/test%2Frepo.git config zoekt.public 0", 552 "git -C $TMPDIR/test%2Frepo.git config zoekt.repoid 0", 553 "zoekt-git-index -submodules=false -incremental -branches HEAD,dev " + 554 "-file_limit 123 -parallelism 4 -index /data/index -require_ctags -large_file foo -large_file bar " + 555 "$TMPDIR/test%2Frepo.git", 556 }, 557 }, { 558 name: "delta", 559 args: indexArgs{ 560 Incremental: true, 561 IndexDir: "/data/index", 562 Parallelism: 4, 563 FileLimit: 123, 564 UseDelta: true, 565 IndexOptions: IndexOptions{ 566 RepoID: 0, 567 Name: "test/repo", 568 CloneURL: "http://api.test/.internal/git/test/repo", 569 LargeFiles: []string{"foo", "bar"}, 570 Symbols: true, 571 Branches: []zoekt.RepositoryBranch{ 572 {Name: "HEAD", Version: "deadbeef"}, 573 {Name: "dev", Version: "feebdaed"}, 574 {Name: "release", Version: "12345678"}, 575 }, 576 }, 577 DeltaShardNumberFallbackThreshold: 22, 578 }, 579 mockRepositoryMetadata: &zoekt.Repository{ 580 ID: 0, 581 Name: "test/repo", 582 Branches: []zoekt.RepositoryBranch{ 583 {Name: "HEAD", Version: "oldhead"}, 584 {Name: "dev", Version: "olddev"}, 585 {Name: "release", Version: "oldrelease"}, 586 }, 587 }, 588 want: []string{ 589 "git -c init.defaultBranch=nonExistentBranchBB0FOFCH32 init --bare $TMPDIR/test%2Frepo.git", 590 "git -C $TMPDIR/test%2Frepo.git -c protocol.version=2 -c http.extraHeader=X-Sourcegraph-Actor-UID: internal fetch --depth=1 http://api.test/.internal/git/test/repo deadbeef feebdaed 12345678 oldhead olddev oldrelease", 591 "git -C $TMPDIR/test%2Frepo.git update-ref HEAD deadbeef", 592 "git -C $TMPDIR/test%2Frepo.git update-ref refs/heads/dev feebdaed", 593 "git -C $TMPDIR/test%2Frepo.git update-ref refs/heads/release 12345678", 594 "git -C $TMPDIR/test%2Frepo.git config zoekt.archived 0", 595 "git -C $TMPDIR/test%2Frepo.git config zoekt.fork 0", 596 "git -C $TMPDIR/test%2Frepo.git config zoekt.name test/repo", 597 "git -C $TMPDIR/test%2Frepo.git config zoekt.priority 0", 598 "git -C $TMPDIR/test%2Frepo.git config zoekt.public 0", 599 "git -C $TMPDIR/test%2Frepo.git config zoekt.repoid 0", 600 "zoekt-git-index -submodules=false -incremental -branches HEAD,dev,release " + 601 "-delta -delta_threshold 22 -file_limit 123 -parallelism 4 -index /data/index -require_ctags -large_file foo -large_file bar " + 602 "$TMPDIR/test%2Frepo.git", 603 }, 604 }} 605 606 for _, tc := range cases { 607 t.Run(tc.name, func(t *testing.T) { 608 var got []string 609 runCmd := func(c *exec.Cmd) error { 610 cmd := strings.Join(c.Args, " ") 611 cmd = strings.ReplaceAll(cmd, filepath.Clean(os.TempDir()), "$TMPDIR") 612 got = append(got, cmd) 613 return nil 614 } 615 616 findRepositoryMetadata := func(args *indexArgs) (repository *zoekt.Repository, metadata *zoekt.IndexMetadata, ok bool, err error) { 617 if tc.mockRepositoryMetadata == nil { 618 return args.BuildOptions().FindRepositoryMetadata() 619 } 620 621 return tc.mockRepositoryMetadata, &zoekt.IndexMetadata{}, true, nil 622 } 623 624 c := gitIndexConfig{ 625 runCmd: runCmd, 626 findRepositoryMetadata: findRepositoryMetadata, 627 } 628 629 if err := gitIndex(c, &tc.args, sourcegraphNop{}, logtest.Scoped(t)); err != nil { 630 t.Fatal(err) 631 } 632 if !cmp.Equal(got, tc.want) { 633 t.Errorf("git mismatch (-want +got):\n%s", cmp.Diff(tc.want, got, splitargs)) 634 } 635 }) 636 } 637} 638 639var splitargs = cmpopts.AcyclicTransformer("splitargs", func(cmd string) []string { 640 return strings.Split(cmd, " ") 641}) 642 643type mockGRPCClient struct { 644 mockSearchConfiguration func(context.Context, *proto.SearchConfigurationRequest, ...grpc.CallOption) (*proto.SearchConfigurationResponse, error) 645 mockList func(context.Context, *proto.ListRequest, ...grpc.CallOption) (*proto.ListResponse, error) 646 mockDocumentRanks func(context.Context, *proto.DocumentRanksRequest, ...grpc.CallOption) (*proto.DocumentRanksResponse, error) 647 mockUpdateIndexStatus func(context.Context, *proto.UpdateIndexStatusRequest, ...grpc.CallOption) (*proto.UpdateIndexStatusResponse, error) 648} 649 650func (m *mockGRPCClient) SearchConfiguration(ctx context.Context, in *proto.SearchConfigurationRequest, opts ...grpc.CallOption) (*proto.SearchConfigurationResponse, error) { 651 if m.mockSearchConfiguration != nil { 652 return m.mockSearchConfiguration(ctx, in, opts...) 653 } 654 655 return nil, fmt.Errorf("mock RPC SearchConfiguration not implemented") 656} 657 658func (m *mockGRPCClient) List(ctx context.Context, in *proto.ListRequest, opts ...grpc.CallOption) (*proto.ListResponse, error) { 659 if m.mockList != nil { 660 return m.mockList(ctx, in, opts...) 661 } 662 663 return nil, fmt.Errorf("mock RPC List not implemented") 664} 665 666func (m *mockGRPCClient) DocumentRanks(ctx context.Context, in *proto.DocumentRanksRequest, opts ...grpc.CallOption) (*proto.DocumentRanksResponse, error) { 667 if m.mockDocumentRanks != nil { 668 return m.mockDocumentRanks(ctx, in, opts...) 669 } 670 671 return nil, fmt.Errorf("mock RPC DocumentRanks not implemented") 672} 673 674func (m *mockGRPCClient) UpdateIndexStatus(ctx context.Context, in *proto.UpdateIndexStatusRequest, opts ...grpc.CallOption) (*proto.UpdateIndexStatusResponse, error) { 675 if m.mockUpdateIndexStatus != nil { 676 return m.mockUpdateIndexStatus(ctx, in, opts...) 677 } 678 679 return nil, fmt.Errorf("mock RPC UpdateIndexStatus not implemented") 680} 681 682var _ proto.ZoektConfigurationServiceClient = &mockGRPCClient{}