github.com/weaviate/weaviate@v1.24.6/usecases/classification/integrationtest/fakes_for_integration_test.go (about) 1 // _ _ 2 // __ _____ __ ___ ___ __ _| |_ ___ 3 // \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ 4 // \ V V / __/ (_| |\ V /| | (_| | || __/ 5 // \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| 6 // 7 // Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. 8 // 9 // CONTACT: hello@weaviate.io 10 // 11 12 //go:build integrationTest 13 // +build integrationTest 14 15 package classification_integration_test 16 17 import ( 18 "context" 19 "fmt" 20 "io" 21 "math/rand" 22 "sync" 23 24 "github.com/go-openapi/strfmt" 25 "github.com/google/uuid" 26 "github.com/weaviate/weaviate/entities/additional" 27 "github.com/weaviate/weaviate/entities/aggregation" 28 "github.com/weaviate/weaviate/entities/filters" 29 "github.com/weaviate/weaviate/entities/models" 30 "github.com/weaviate/weaviate/entities/schema" 31 "github.com/weaviate/weaviate/entities/search" 32 "github.com/weaviate/weaviate/entities/searchparams" 33 "github.com/weaviate/weaviate/entities/storobj" 34 enthnsw "github.com/weaviate/weaviate/entities/vectorindex/hnsw" 35 "github.com/weaviate/weaviate/usecases/objects" 36 "github.com/weaviate/weaviate/usecases/replica" 37 "github.com/weaviate/weaviate/usecases/sharding" 38 ) 39 40 type fakeSchemaGetter struct { 41 schema schema.Schema 42 shardState *sharding.State 43 } 44 45 func (f *fakeSchemaGetter) GetSchemaSkipAuth() schema.Schema { 46 return f.schema 47 } 48 49 func (f *fakeSchemaGetter) CopyShardingState(class string) *sharding.State { 50 return f.shardState 51 } 52 53 func (f *fakeSchemaGetter) ShardOwner(class, shard string) (string, error) { 54 ss := f.shardState 55 x, ok := ss.Physical[shard] 56 if !ok { 57 return "", fmt.Errorf("shard not found") 58 } 59 if len(x.BelongsToNodes) < 1 || x.BelongsToNodes[0] == "" { 60 return "", fmt.Errorf("owner node not found") 61 } 62 return ss.Physical[shard].BelongsToNodes[0], nil 63 } 64 65 func (f *fakeSchemaGetter) ShardReplicas(class, shard string) ([]string, error) { 66 ss := f.shardState 67 x, ok := ss.Physical[shard] 68 if !ok { 69 return nil, fmt.Errorf("shard not found") 70 } 71 return x.BelongsToNodes, nil 72 } 73 74 func (f *fakeSchemaGetter) TenantShard(class, tenant string) (string, string) { 75 return tenant, models.TenantActivityStatusHOT 76 } 77 78 func (f *fakeSchemaGetter) ShardFromUUID(class string, uuid []byte) string { 79 ss := f.shardState 80 return ss.Shard("", string(uuid)) 81 } 82 83 func (f *fakeSchemaGetter) Nodes() []string { 84 return []string{"node1"} 85 } 86 87 func (m *fakeSchemaGetter) NodeName() string { 88 return "node1" 89 } 90 91 func (m *fakeSchemaGetter) ClusterHealthScore() int { 92 return 0 93 } 94 95 func (m *fakeSchemaGetter) ResolveParentNodes(_ string, shard string, 96 ) (map[string]string, error) { 97 return nil, nil 98 } 99 100 func singleShardState() *sharding.State { 101 config, err := sharding.ParseConfig(nil, 1) 102 if err != nil { 103 panic(err) 104 } 105 106 s, err := sharding.InitState("test-index", config, 107 fakeNodes{[]string{"node1"}}, 1, false) 108 if err != nil { 109 panic(err) 110 } 111 112 return s 113 } 114 115 type fakeClassificationRepo struct { 116 sync.Mutex 117 db map[strfmt.UUID]models.Classification 118 } 119 120 func newFakeClassificationRepo() *fakeClassificationRepo { 121 return &fakeClassificationRepo{ 122 db: map[strfmt.UUID]models.Classification{}, 123 } 124 } 125 126 func (f *fakeClassificationRepo) Put(ctx context.Context, class models.Classification) error { 127 f.Lock() 128 defer f.Unlock() 129 130 f.db[class.ID] = class 131 return nil 132 } 133 134 func (f *fakeClassificationRepo) Get(ctx context.Context, id strfmt.UUID) (*models.Classification, error) { 135 f.Lock() 136 defer f.Unlock() 137 138 class, ok := f.db[id] 139 if !ok { 140 return nil, nil 141 } 142 143 return &class, nil 144 } 145 146 func testSchema() schema.Schema { 147 return schema.Schema{ 148 Objects: &models.Schema{ 149 Classes: []*models.Class{ 150 { 151 Class: "ExactCategory", 152 VectorIndexConfig: enthnsw.NewDefaultUserConfig(), 153 InvertedIndexConfig: invertedConfig(), 154 }, 155 { 156 Class: "MainCategory", 157 VectorIndexConfig: enthnsw.NewDefaultUserConfig(), 158 InvertedIndexConfig: invertedConfig(), 159 }, 160 { 161 Class: "Article", 162 VectorIndexConfig: enthnsw.NewDefaultUserConfig(), 163 InvertedIndexConfig: invertedConfig(), 164 Properties: []*models.Property{ 165 { 166 Name: "description", 167 DataType: []string{string(schema.DataTypeText)}, 168 }, 169 { 170 Name: "name", 171 DataType: schema.DataTypeText.PropString(), 172 Tokenization: models.PropertyTokenizationWhitespace, 173 }, 174 { 175 Name: "exactCategory", 176 DataType: []string{"ExactCategory"}, 177 }, 178 { 179 Name: "mainCategory", 180 DataType: []string{"MainCategory"}, 181 }, 182 { 183 Name: "categories", 184 DataType: []string{"ExactCategory"}, 185 }, 186 { 187 Name: "anyCategory", 188 DataType: []string{"MainCategory", "ExactCategory"}, 189 }, 190 }, 191 }, 192 }, 193 }, 194 } 195 } 196 197 // only used for knn-type 198 func testDataAlreadyClassified() search.Results { 199 return search.Results{ 200 search.Result{ 201 ID: "8aeecd06-55a0-462c-9853-81b31a284d80", 202 ClassName: "Article", 203 Vector: []float32{1, 0, 0}, 204 Schema: map[string]interface{}{ 205 "description": "This article talks about politics", 206 "exactCategory": models.MultipleRef{beaconRef(idCategoryPolitics)}, 207 "mainCategory": models.MultipleRef{beaconRef(idMainCategoryPoliticsAndSociety)}, 208 }, 209 }, 210 search.Result{ 211 ID: "9f4c1847-2567-4de7-8861-34cf47a071ae", 212 ClassName: "Article", 213 Vector: []float32{0, 1, 0}, 214 Schema: map[string]interface{}{ 215 "description": "This articles talks about society", 216 "exactCategory": models.MultipleRef{beaconRef(idCategorySociety)}, 217 "mainCategory": models.MultipleRef{beaconRef(idMainCategoryPoliticsAndSociety)}, 218 }, 219 }, 220 search.Result{ 221 ID: "926416ec-8fb1-4e40-ab8c-37b226b3d68e", 222 ClassName: "Article", 223 Vector: []float32{0, 0, 1}, 224 Schema: map[string]interface{}{ 225 "description": "This article talks about food", 226 "exactCategory": models.MultipleRef{beaconRef(idCategoryFoodAndDrink)}, 227 "mainCategory": models.MultipleRef{beaconRef(idMainCategoryFoodAndDrink)}, 228 }, 229 }, 230 } 231 } 232 233 // only used for zeroshot-type 234 func testDataZeroShotUnclassified() search.Results { 235 return search.Results{ 236 search.Result{ 237 ID: "8aeecd06-55a0-462c-9853-81b31a284d80", 238 ClassName: "FoodType", 239 Vector: []float32{1, 0, 0}, 240 Schema: map[string]interface{}{ 241 "text": "Ice cream", 242 }, 243 }, 244 search.Result{ 245 ID: "9f4c1847-2567-4de7-8861-34cf47a071ae", 246 ClassName: "FoodType", 247 Vector: []float32{0, 1, 0}, 248 Schema: map[string]interface{}{ 249 "text": "Meat", 250 }, 251 }, 252 search.Result{ 253 ID: "926416ec-8fb1-4e40-ab8c-37b226b3d68e", 254 ClassName: "Recipes", 255 Vector: []float32{0, 0, 1}, 256 Schema: map[string]interface{}{ 257 "text": "Cut the steak in half and put it into pan", 258 }, 259 }, 260 search.Result{ 261 ID: "926416ec-8fb1-4e40-ab8c-37b226b3d688", 262 ClassName: "Recipes", 263 Vector: []float32{0, 1, 1}, 264 Schema: map[string]interface{}{ 265 "description": "There are flavors of vanilla, chocolate and strawberry", 266 }, 267 }, 268 } 269 } 270 271 func mustUUID() strfmt.UUID { 272 id, err := uuid.NewRandom() 273 if err != nil { 274 panic(err) 275 } 276 277 return strfmt.UUID(id.String()) 278 } 279 280 func largeTestDataSize(size int) search.Results { 281 out := make(search.Results, size) 282 283 for i := range out { 284 out[i] = search.Result{ 285 ID: mustUUID(), 286 ClassName: "Article", 287 Vector: []float32{0.02, 0, rand.Float32()}, 288 Schema: map[string]interface{}{ 289 "description": "does not matter much", 290 }, 291 } 292 } 293 return out 294 } 295 296 type fakeAuthorizer struct{} 297 298 func (f *fakeAuthorizer) Authorize(principal *models.Principal, verb, resource string) error { 299 return nil 300 } 301 302 func beaconRef(target string) *models.SingleRef { 303 beacon := fmt.Sprintf("weaviate://localhost/%s", target) 304 return &models.SingleRef{Beacon: strfmt.URI(beacon)} 305 } 306 307 const ( 308 idMainCategoryPoliticsAndSociety = "39c6abe3-4bbe-4c4e-9e60-ca5e99ec6b4e" 309 idMainCategoryFoodAndDrink = "5a3d909a-4f0d-4168-8f5c-cd3074d1e79a" 310 idCategoryPolitics = "1b204f16-7da6-44fd-bbd2-8cc4a7414bc3" 311 idCategorySociety = "ec500f39-1dc9-4580-9bd1-55a8ea8e37a2" 312 idCategoryFoodAndDrink = "027b708a-31ca-43ea-9001-88bec864c79c" 313 ) 314 315 func invertedConfig() *models.InvertedIndexConfig { 316 return &models.InvertedIndexConfig{ 317 CleanupIntervalSeconds: 60, 318 } 319 } 320 321 func testSchemaForZeroShot() schema.Schema { 322 return schema.Schema{ 323 Objects: &models.Schema{ 324 Classes: []*models.Class{ 325 { 326 Class: "FoodType", 327 VectorIndexConfig: enthnsw.NewDefaultUserConfig(), 328 InvertedIndexConfig: invertedConfig(), 329 Properties: []*models.Property{ 330 { 331 Name: "text", 332 DataType: []string{string(schema.DataTypeText)}, 333 }, 334 }, 335 }, 336 { 337 Class: "Recipes", 338 VectorIndexConfig: enthnsw.NewDefaultUserConfig(), 339 InvertedIndexConfig: invertedConfig(), 340 Properties: []*models.Property{ 341 { 342 Name: "text", 343 DataType: []string{string(schema.DataTypeText)}, 344 }, 345 { 346 Name: "ofFoodType", 347 DataType: []string{"FoodType"}, 348 }, 349 }, 350 }, 351 }, 352 }, 353 } 354 } 355 356 type fakeNodes struct { 357 nodes []string 358 } 359 360 func (f fakeNodes) Candidates() []string { 361 return f.nodes 362 } 363 364 func (f fakeNodes) LocalName() string { 365 return f.nodes[0] 366 } 367 368 type fakeRemoteClient struct{} 369 370 func (f *fakeRemoteClient) PutObject(ctx context.Context, hostName, indexName, 371 shardName string, obj *storobj.Object, 372 ) error { 373 return nil 374 } 375 376 func (f *fakeRemoteClient) PutFile(ctx context.Context, hostName, indexName, 377 shardName, fileName string, payload io.ReadSeekCloser, 378 ) error { 379 return nil 380 } 381 382 func (f *fakeRemoteClient) GetObject(ctx context.Context, hostName, indexName, 383 shardName string, id strfmt.UUID, props search.SelectProperties, 384 additional additional.Properties, 385 ) (*storobj.Object, error) { 386 return nil, nil 387 } 388 389 func (f *fakeRemoteClient) FindObject(ctx context.Context, hostName, indexName, 390 shardName string, id strfmt.UUID, props search.SelectProperties, 391 additional additional.Properties, 392 ) (*storobj.Object, error) { 393 return nil, nil 394 } 395 396 func (f *fakeRemoteClient) OverwriteObjects(ctx context.Context, 397 host, index, shard string, objects []*objects.VObject, 398 ) ([]replica.RepairResponse, error) { 399 return nil, nil 400 } 401 402 func (f *fakeRemoteClient) Exists(ctx context.Context, hostName, indexName, 403 shardName string, id strfmt.UUID, 404 ) (bool, error) { 405 return false, nil 406 } 407 408 func (f *fakeRemoteClient) DeleteObject(ctx context.Context, hostName, indexName, 409 shardName string, id strfmt.UUID, 410 ) error { 411 return nil 412 } 413 414 func (f *fakeRemoteClient) MergeObject(ctx context.Context, hostName, indexName, 415 shardName string, mergeDoc objects.MergeDocument, 416 ) error { 417 return nil 418 } 419 420 func (f *fakeRemoteClient) SearchShard(ctx context.Context, hostName, indexName, 421 shardName string, vector []float32, targetVector string, limit int, filters *filters.LocalFilter, 422 keywordRanking *searchparams.KeywordRanking, sort []filters.Sort, 423 cursor *filters.Cursor, groupBy *searchparams.GroupBy, additional additional.Properties, 424 ) ([]*storobj.Object, []float32, error) { 425 return nil, nil, nil 426 } 427 428 func (f *fakeRemoteClient) BatchPutObjects(ctx context.Context, hostName, indexName, shardName string, objs []*storobj.Object, repl *additional.ReplicationProperties) []error { 429 return nil 430 } 431 432 func (f *fakeRemoteClient) MultiGetObjects(ctx context.Context, hostName, indexName, 433 shardName string, ids []strfmt.UUID, 434 ) ([]*storobj.Object, error) { 435 return nil, nil 436 } 437 438 func (f *fakeRemoteClient) BatchAddReferences(ctx context.Context, hostName, 439 indexName, shardName string, refs objects.BatchReferences, 440 ) []error { 441 return nil 442 } 443 444 func (f *fakeRemoteClient) Aggregate(ctx context.Context, hostName, indexName, 445 shardName string, params aggregation.Params, 446 ) (*aggregation.Result, error) { 447 return nil, nil 448 } 449 450 func (f *fakeRemoteClient) FindUUIDs(ctx context.Context, hostName, indexName, shardName string, 451 filters *filters.LocalFilter, 452 ) ([]strfmt.UUID, error) { 453 return nil, nil 454 } 455 456 func (f *fakeRemoteClient) DeleteObjectBatch(ctx context.Context, hostName, indexName, shardName string, 457 uuids []strfmt.UUID, dryRun bool, 458 ) objects.BatchSimpleObjects { 459 return nil 460 } 461 462 func (f *fakeRemoteClient) GetShardQueueSize(ctx context.Context, 463 hostName, indexName, shardName string, 464 ) (int64, error) { 465 return 0, nil 466 } 467 468 func (f *fakeRemoteClient) GetShardStatus(ctx context.Context, 469 hostName, indexName, shardName string, 470 ) (string, error) { 471 return "", nil 472 } 473 474 func (f *fakeRemoteClient) UpdateShardStatus(ctx context.Context, hostName, indexName, shardName, 475 targetStatus string, 476 ) error { 477 return nil 478 } 479 480 func (f *fakeRemoteClient) DigestObjects(ctx context.Context, 481 hostName, indexName, shardName string, ids []strfmt.UUID, 482 ) (result []replica.RepairResponse, err error) { 483 return nil, nil 484 } 485 486 type fakeNodeResolver struct{} 487 488 func (f *fakeNodeResolver) NodeHostname(string) (string, bool) { 489 return "", false 490 } 491 492 type fakeRemoteNodeClient struct{} 493 494 func (f *fakeRemoteNodeClient) GetNodeStatus(ctx context.Context, hostName, className, output string) (*models.NodeStatus, error) { 495 return &models.NodeStatus{}, nil 496 } 497 498 type fakeReplicationClient struct{} 499 500 func (f *fakeReplicationClient) PutObject(ctx context.Context, host, index, shard, requestID string, 501 obj *storobj.Object, 502 ) (replica.SimpleResponse, error) { 503 return replica.SimpleResponse{}, nil 504 } 505 506 func (f *fakeReplicationClient) DeleteObject(ctx context.Context, host, index, shard, requestID string, 507 id strfmt.UUID, 508 ) (replica.SimpleResponse, error) { 509 return replica.SimpleResponse{}, nil 510 } 511 512 func (f *fakeReplicationClient) PutObjects(ctx context.Context, host, index, shard, requestID string, 513 objs []*storobj.Object, 514 ) (replica.SimpleResponse, error) { 515 return replica.SimpleResponse{}, nil 516 } 517 518 func (f *fakeReplicationClient) MergeObject(ctx context.Context, host, index, shard, requestID string, 519 mergeDoc *objects.MergeDocument, 520 ) (replica.SimpleResponse, error) { 521 return replica.SimpleResponse{}, nil 522 } 523 524 func (f *fakeReplicationClient) DeleteObjects(ctx context.Context, host, index, shard, requestID string, 525 uuids []strfmt.UUID, dryRun bool, 526 ) (replica.SimpleResponse, error) { 527 return replica.SimpleResponse{}, nil 528 } 529 530 func (f *fakeReplicationClient) AddReferences(ctx context.Context, host, index, shard, requestID string, 531 refs []objects.BatchReference, 532 ) (replica.SimpleResponse, error) { 533 return replica.SimpleResponse{}, nil 534 } 535 536 func (f *fakeReplicationClient) Commit(ctx context.Context, host, index, shard, requestID string, resp interface{}) error { 537 return nil 538 } 539 540 func (f *fakeReplicationClient) Abort(ctx context.Context, host, index, shard, requestID string) (replica.SimpleResponse, error) { 541 return replica.SimpleResponse{}, nil 542 } 543 544 func (c *fakeReplicationClient) Exists(ctx context.Context, host, index, 545 shard string, id strfmt.UUID, 546 ) (bool, error) { 547 return false, nil 548 } 549 550 func (f *fakeReplicationClient) FetchObject(_ context.Context, host, index, 551 shard string, id strfmt.UUID, props search.SelectProperties, 552 additional additional.Properties, 553 ) (objects.Replica, error) { 554 return objects.Replica{}, nil 555 } 556 557 func (c *fakeReplicationClient) FetchObjects(ctx context.Context, host, 558 index, shard string, ids []strfmt.UUID, 559 ) ([]objects.Replica, error) { 560 return nil, nil 561 } 562 563 func (c *fakeReplicationClient) DigestObjects(ctx context.Context, 564 host, index, shard string, ids []strfmt.UUID, 565 ) (result []replica.RepairResponse, err error) { 566 return nil, nil 567 } 568 569 func (c *fakeReplicationClient) OverwriteObjects(ctx context.Context, 570 host, index, shard string, vobjects []*objects.VObject, 571 ) ([]replica.RepairResponse, error) { 572 return nil, nil 573 }