Spaces:
Sleeping
Sleeping
| // _ _ | |
| // __ _____ __ ___ ___ __ _| |_ ___ | |
| // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
| // \ V V / __/ (_| |\ V /| | (_| | || __/ | |
| // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
| // | |
| // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
| // | |
| // CONTACT: hello@weaviate.io | |
| // | |
| package sharding | |
| import ( | |
| "context" | |
| "errors" | |
| "fmt" | |
| "testing" | |
| ) | |
| var errAny = errors.New("anyErr") | |
| func TestQueryReplica(t *testing.T) { | |
| var ( | |
| ctx = context.Background() | |
| canceledCtx, cancledFunc = context.WithCancel(ctx) | |
| ) | |
| cancledFunc() | |
| doIf := func(targetNode string) func(node, host string) (interface{}, error) { | |
| return func(node, host string) (interface{}, error) { | |
| if node != targetNode { | |
| return nil, errAny | |
| } | |
| return node, nil | |
| } | |
| } | |
| tests := []struct { | |
| ctx context.Context | |
| resolver fakeNodeResolver | |
| schema fakeSchema | |
| targetNode string | |
| success bool | |
| name string | |
| }{ | |
| { | |
| ctx, newFakeResolver(0, 0), newFakeSchema(0, 0), "N0", false, "empty schema", | |
| }, | |
| { | |
| ctx, newFakeResolver(0, 1), newFakeSchema(1, 2), "N2", false, "unresolved name", | |
| }, | |
| { | |
| ctx, newFakeResolver(0, 1), newFakeSchema(0, 1), "N0", true, "one replica", | |
| }, | |
| { | |
| ctx, newFakeResolver(0, 9), newFakeSchema(0, 9), "N2", true, "random selection", | |
| }, | |
| { | |
| canceledCtx, newFakeResolver(0, 9), newFakeSchema(0, 9), "N2", false, "canceled", | |
| }, | |
| } | |
| for _, test := range tests { | |
| rindex := RemoteIndex{"C", &test.schema, nil, &test.resolver} | |
| got, lastNode, err := rindex.queryReplicas(test.ctx, "S", doIf(test.targetNode)) | |
| if !test.success { | |
| if got != nil { | |
| t.Errorf("%s: want: nil, got: %v", test.name, got) | |
| } else if err == nil { | |
| t.Errorf("%s: must return an error", test.name) | |
| } | |
| continue | |
| } | |
| if lastNode != test.targetNode { | |
| t.Errorf("%s: last responding node want:%s got:%s", test.name, test.targetNode, lastNode) | |
| } | |
| } | |
| } | |
| func newFakeResolver(fromNode, toNode int) fakeNodeResolver { | |
| m := make(map[string]string, toNode-fromNode) | |
| for i := fromNode; i < toNode; i++ { | |
| m[fmt.Sprintf("N%d", i)] = fmt.Sprintf("H%d", i) | |
| } | |
| return fakeNodeResolver{m} | |
| } | |
| func newFakeSchema(fromNode, toNode int) fakeSchema { | |
| nodes := make([]string, 0, toNode-fromNode) | |
| for i := fromNode; i < toNode; i++ { | |
| nodes = append(nodes, fmt.Sprintf("N%d", i)) | |
| } | |
| return fakeSchema{nodes} | |
| } | |
| type fakeNodeResolver struct { | |
| rTable map[string]string | |
| } | |
| func (f *fakeNodeResolver) NodeHostname(name string) (string, bool) { | |
| host, ok := f.rTable[name] | |
| return host, ok | |
| } | |
| type fakeSchema struct { | |
| nodes []string | |
| } | |
| func (f *fakeSchema) ShardOwner(class, shard string) (string, error) { | |
| return "", nil | |
| } | |
| func (f *fakeSchema) ShardReplicas(class, shard string) ([]string, error) { | |
| return f.nodes, nil | |
| } | |