github.com/weaviate/weaviate@v1.24.6/usecases/schema/cache_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  package schema
    13  
    14  import (
    15  	"errors"
    16  	"testing"
    17  
    18  	"github.com/stretchr/testify/assert"
    19  	"github.com/stretchr/testify/require"
    20  	"github.com/weaviate/weaviate/entities/models"
    21  	"github.com/weaviate/weaviate/entities/schema"
    22  	"github.com/weaviate/weaviate/entities/schema/test_utils"
    23  	"github.com/weaviate/weaviate/usecases/sharding"
    24  )
    25  
    26  func TestShardReplicas(t *testing.T) {
    27  	cache := schemaCache{
    28  		State: State{
    29  			ShardingState: map[string]*sharding.State{},
    30  		},
    31  	}
    32  
    33  	// class not found
    34  	_, err := cache.ShardReplicas("C", "S")
    35  	assert.ErrorContains(t, err, "class not found")
    36  
    37  	// shard not found
    38  	ss := &sharding.State{Physical: make(map[string]sharding.Physical)}
    39  	cache.State.ShardingState["C"] = ss
    40  	_, err = cache.ShardReplicas("C", "S")
    41  	assert.ErrorContains(t, err, "shard not found")
    42  
    43  	// two replicas found
    44  	nodes := []string{"A", "B"}
    45  	ss.Physical["S"] = sharding.Physical{BelongsToNodes: nodes}
    46  	res, err := cache.ShardReplicas("C", "S")
    47  	assert.Nil(t, err)
    48  	assert.Equal(t, nodes, res)
    49  }
    50  
    51  func TestUpdateClass(t *testing.T) {
    52  	class := "C"
    53  	cache := schemaCache{
    54  		State: State{
    55  			ShardingState: map[string]*sharding.State{},
    56  			ObjectSchema: &models.Schema{
    57  				Classes: []*models.Class{},
    58  			},
    59  		},
    60  	}
    61  
    62  	if err := cache.updateClass(&models.Class{}, nil); !errors.Is(err, errClassNotFound) {
    63  		t.Fatalf("update_class: want %v got %v", errClassNotFound, err)
    64  	}
    65  	if _, err := cache.addProperty("?", nil); !errors.Is(err, errClassNotFound) {
    66  		t.Fatalf("add_property: want %v got %v", errClassNotFound, err)
    67  	}
    68  	c := models.Class{
    69  		Class:      class,
    70  		Properties: []*models.Property{},
    71  	}
    72  	uc := models.Class{
    73  		Class: class,
    74  		Properties: []*models.Property{
    75  			{Description: "P1"},
    76  		},
    77  	}
    78  	// add class
    79  	ss := sharding.State{}
    80  	cache.addClass(&c, &ss)
    81  
    82  	if c, _ := cache.readOnlyClass(class); c == nil {
    83  		t.Fatalf("class not found")
    84  	} else if c == cache.unsafeFindClass(class) {
    85  		t.Fatalf("read_only_class doesn't return a shallow copy")
    86  	}
    87  
    88  	// update class
    89  	cache.updateClass(&uc, &sharding.State{IndexID: class})
    90  	p := models.Property{Description: "P2"}
    91  
    92  	x, err := cache.addProperty(class, &p)
    93  	if err != nil {
    94  		t.Fatalf("class not found")
    95  	}
    96  	if n := len(x.Properties); n != 2 {
    97  		t.Fatalf("number of properties want: %v got: 2", n)
    98  	}
    99  }
   100  
   101  func TestCache_MergeObjectProperty(t *testing.T) {
   102  	vFalse := false
   103  	vTrue := true
   104  
   105  	className := "objectClass"
   106  	propertyName := "objectProperty"
   107  
   108  	objectProperty := &models.Property{
   109  		Name:            propertyName,
   110  		DataType:        schema.DataTypeObject.PropString(),
   111  		IndexFilterable: &vTrue,
   112  		IndexSearchable: &vFalse,
   113  		Tokenization:    "",
   114  		NestedProperties: []*models.NestedProperty{
   115  			{
   116  				Name:            "nested_int",
   117  				DataType:        schema.DataTypeInt.PropString(),
   118  				IndexFilterable: &vTrue,
   119  				IndexSearchable: &vFalse,
   120  				Tokenization:    "",
   121  			},
   122  			{
   123  				Name:            "nested_text",
   124  				DataType:        schema.DataTypeText.PropString(),
   125  				IndexFilterable: &vTrue,
   126  				IndexSearchable: &vTrue,
   127  				Tokenization:    models.PropertyTokenizationWord,
   128  			},
   129  			{
   130  				Name:            "nested_objects",
   131  				DataType:        schema.DataTypeObjectArray.PropString(),
   132  				IndexFilterable: &vTrue,
   133  				IndexSearchable: &vFalse,
   134  				Tokenization:    "",
   135  				NestedProperties: []*models.NestedProperty{
   136  					{
   137  						Name:            "nested_bool_lvl2",
   138  						DataType:        schema.DataTypeBoolean.PropString(),
   139  						IndexFilterable: &vTrue,
   140  						IndexSearchable: &vFalse,
   141  						Tokenization:    "",
   142  					},
   143  					{
   144  						Name:            "nested_numbers_lvl2",
   145  						DataType:        schema.DataTypeNumberArray.PropString(),
   146  						IndexFilterable: &vTrue,
   147  						IndexSearchable: &vFalse,
   148  						Tokenization:    "",
   149  					},
   150  				},
   151  			},
   152  		},
   153  	}
   154  	updatedObjectProperty := &models.Property{
   155  		Name:            propertyName,
   156  		DataType:        schema.DataTypeObject.PropString(),
   157  		IndexFilterable: &vFalse, // different setting than existing class/prop
   158  		IndexSearchable: &vFalse,
   159  		Tokenization:    "",
   160  		NestedProperties: []*models.NestedProperty{
   161  			{
   162  				Name:            "nested_number",
   163  				DataType:        schema.DataTypeNumber.PropString(),
   164  				IndexFilterable: &vTrue,
   165  				IndexSearchable: &vFalse,
   166  				Tokenization:    "",
   167  			},
   168  			{
   169  				Name:            "nested_text",
   170  				DataType:        schema.DataTypeText.PropString(),
   171  				IndexFilterable: &vTrue,
   172  				IndexSearchable: &vTrue,
   173  				Tokenization:    models.PropertyTokenizationField, // different setting than existing class/prop
   174  			},
   175  			{
   176  				Name:            "nested_objects",
   177  				DataType:        schema.DataTypeObjectArray.PropString(),
   178  				IndexFilterable: &vTrue,
   179  				IndexSearchable: &vFalse,
   180  				Tokenization:    "",
   181  				NestedProperties: []*models.NestedProperty{
   182  					{
   183  						Name:            "nested_date_lvl2",
   184  						DataType:        schema.DataTypeDate.PropString(),
   185  						IndexFilterable: &vTrue,
   186  						IndexSearchable: &vFalse,
   187  						Tokenization:    "",
   188  					},
   189  					{
   190  						Name:            "nested_numbers_lvl2",
   191  						DataType:        schema.DataTypeNumberArray.PropString(),
   192  						IndexFilterable: &vFalse, // different setting than existing class/prop
   193  						IndexSearchable: &vFalse,
   194  						Tokenization:    "",
   195  					},
   196  				},
   197  			},
   198  		},
   199  	}
   200  	expectedObjectProperty := &models.Property{
   201  		Name:            propertyName,
   202  		DataType:        schema.DataTypeObject.PropString(),
   203  		IndexFilterable: &vTrue,
   204  		IndexSearchable: &vFalse,
   205  		Tokenization:    "",
   206  		NestedProperties: []*models.NestedProperty{
   207  			{
   208  				Name:            "nested_int",
   209  				DataType:        schema.DataTypeInt.PropString(),
   210  				IndexFilterable: &vTrue,
   211  				IndexSearchable: &vFalse,
   212  				Tokenization:    "",
   213  			},
   214  			{
   215  				Name:            "nested_number",
   216  				DataType:        schema.DataTypeNumber.PropString(),
   217  				IndexFilterable: &vTrue,
   218  				IndexSearchable: &vFalse,
   219  				Tokenization:    "",
   220  			},
   221  			{
   222  				Name:            "nested_text",
   223  				DataType:        schema.DataTypeText.PropString(),
   224  				IndexFilterable: &vTrue,
   225  				IndexSearchable: &vTrue,
   226  				Tokenization:    models.PropertyTokenizationWord, // from existing class/prop
   227  			},
   228  			{
   229  				Name:            "nested_objects",
   230  				DataType:        schema.DataTypeObjectArray.PropString(),
   231  				IndexFilterable: &vTrue,
   232  				IndexSearchable: &vFalse,
   233  				Tokenization:    "",
   234  				NestedProperties: []*models.NestedProperty{
   235  					{
   236  						Name:            "nested_bool_lvl2",
   237  						DataType:        schema.DataTypeBoolean.PropString(),
   238  						IndexFilterable: &vTrue,
   239  						IndexSearchable: &vFalse,
   240  						Tokenization:    "",
   241  					},
   242  					{
   243  						Name:            "nested_date_lvl2",
   244  						DataType:        schema.DataTypeDate.PropString(),
   245  						IndexFilterable: &vTrue,
   246  						IndexSearchable: &vFalse,
   247  						Tokenization:    "",
   248  					},
   249  					{
   250  						Name:            "nested_numbers_lvl2",
   251  						DataType:        schema.DataTypeNumberArray.PropString(),
   252  						IndexFilterable: &vTrue, // from existing class/prop
   253  						IndexSearchable: &vFalse,
   254  						Tokenization:    "",
   255  					},
   256  				},
   257  			},
   258  		},
   259  	}
   260  
   261  	cache := schemaCache{
   262  		State: State{
   263  			ShardingState: map[string]*sharding.State{},
   264  			ObjectSchema: &models.Schema{
   265  				Classes: []*models.Class{
   266  					{
   267  						Class:      className,
   268  						Properties: []*models.Property{objectProperty},
   269  					},
   270  				},
   271  			},
   272  		},
   273  	}
   274  
   275  	updatedClass, err := cache.mergeObjectProperty(className, updatedObjectProperty)
   276  	require.NoError(t, err)
   277  	require.NotNil(t, updatedClass)
   278  	require.Len(t, updatedClass.Properties, 1)
   279  
   280  	mergedProperty := updatedClass.Properties[0]
   281  	require.NotNil(t, mergedProperty)
   282  	assert.Equal(t, expectedObjectProperty.DataType, mergedProperty.DataType)
   283  	assert.Equal(t, expectedObjectProperty.IndexFilterable, mergedProperty.IndexFilterable)
   284  	assert.Equal(t, expectedObjectProperty.IndexSearchable, mergedProperty.IndexSearchable)
   285  	assert.Equal(t, expectedObjectProperty.Tokenization, mergedProperty.Tokenization)
   286  
   287  	test_utils.AssertNestedPropsMatch(t, expectedObjectProperty.NestedProperties, mergedProperty.NestedProperties)
   288  }