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  }