github.com/weaviate/weaviate@v1.24.6/usecases/schema/schema_comparison_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  	"testing"
    16  
    17  	"github.com/stretchr/testify/assert"
    18  	"github.com/weaviate/weaviate/entities/models"
    19  	"github.com/weaviate/weaviate/entities/schema"
    20  	"github.com/weaviate/weaviate/usecases/sharding"
    21  )
    22  
    23  func Test_SchemaComparison_Identical(t *testing.T) {
    24  	left := &State{
    25  		ShardingState: map[string]*sharding.State{
    26  			"Foo": {
    27  				IndexID: "Foo",
    28  			},
    29  		},
    30  
    31  		ObjectSchema: &models.Schema{
    32  			Classes: []*models.Class{
    33  				{
    34  					Class: "Foo",
    35  					Properties: []*models.Property{
    36  						{
    37  							DataType: []string{"int"},
    38  							Name:     "prop_1",
    39  						},
    40  					},
    41  				},
    42  			},
    43  		},
    44  	}
    45  
    46  	right := &State{
    47  		ShardingState: map[string]*sharding.State{
    48  			"Foo": {
    49  				IndexID: "Foo",
    50  			},
    51  		},
    52  
    53  		ObjectSchema: &models.Schema{
    54  			Classes: []*models.Class{
    55  				{
    56  					Class: "Foo",
    57  					Properties: []*models.Property{
    58  						{
    59  							DataType: []string{"int"},
    60  							Name:     "prop_1",
    61  						},
    62  					},
    63  				},
    64  			},
    65  		},
    66  	}
    67  
    68  	assert.Len(t, Diff("left schema", left, "right schema", right), 0)
    69  }
    70  
    71  func Test_SchemaComparison_MismatchInClasses(t *testing.T) {
    72  	left := &State{
    73  		ShardingState: map[string]*sharding.State{
    74  			"Foo": {
    75  				IndexID: "Foo",
    76  			},
    77  		},
    78  
    79  		ObjectSchema: &models.Schema{
    80  			Classes: []*models.Class{
    81  				{
    82  					Class: "Foo",
    83  					Properties: []*models.Property{
    84  						{
    85  							DataType: []string{"int"},
    86  							Name:     "prop_1",
    87  						},
    88  					},
    89  				},
    90  			},
    91  		},
    92  	}
    93  
    94  	right := &State{
    95  		ShardingState: map[string]*sharding.State{
    96  			"Foo": {
    97  				IndexID: "Foo",
    98  			},
    99  		},
   100  
   101  		ObjectSchema: &models.Schema{
   102  			Classes: []*models.Class{},
   103  		},
   104  	}
   105  
   106  	msgs := Diff("left schema", left, "right schema", right)
   107  	assert.Greater(t, len(msgs), 0)
   108  	assert.Contains(t, msgs, "class Foo exists in left schema, but not in right schema")
   109  }
   110  
   111  func Test_SchemaComparison_VariousMismatches(t *testing.T) {
   112  	left := &State{
   113  		ShardingState: map[string]*sharding.State{
   114  			"Foo": {
   115  				IndexID: "Foo",
   116  			},
   117  			"Foo2": {
   118  				Physical: map[string]sharding.Physical{
   119  					"abcd": {
   120  						OwnsVirtual: []string{"v1"},
   121  					},
   122  				},
   123  			},
   124  			"Foo4": {
   125  				Physical: map[string]sharding.Physical{
   126  					"abcd": {},
   127  				},
   128  			},
   129  		},
   130  
   131  		ObjectSchema: &models.Schema{
   132  			Classes: []*models.Class{
   133  				{
   134  					Class: "Foo",
   135  					Properties: []*models.Property{
   136  						{
   137  							DataType: []string{"int"},
   138  							Name:     "prop_1",
   139  						},
   140  						{
   141  							DataType: []string{"text"},
   142  							Name:     "prop_2",
   143  						},
   144  						{
   145  							DataType:     schema.DataTypeText.PropString(),
   146  							Tokenization: models.PropertyTokenizationWhitespace,
   147  							Name:         "prop_4",
   148  						},
   149  					},
   150  					Description: "foo",
   151  					InvertedIndexConfig: &models.InvertedIndexConfig{
   152  						IndexPropertyLength: true,
   153  					},
   154  					ModuleConfig: "bar",
   155  					ReplicationConfig: &models.ReplicationConfig{
   156  						Factor: 7,
   157  					},
   158  					ShardingConfig: map[string]interface{}{
   159  						"desiredCount": 7,
   160  					},
   161  					VectorIndexConfig: map[string]interface{}{
   162  						"ef": 1000,
   163  					},
   164  					VectorIndexType: "age-n-ass-double-u",
   165  				},
   166  				{Class: "Foo2"},
   167  				{Class: "Foo3"},
   168  				{Class: "Foo4"},
   169  			},
   170  		},
   171  	}
   172  
   173  	right := &State{
   174  		ShardingState: map[string]*sharding.State{
   175  			"Foo": {
   176  				IndexID: "Foo",
   177  			},
   178  			"Foo2": {
   179  				Physical: map[string]sharding.Physical{
   180  					"xyz": {
   181  						BelongsToNodes: []string{"n1"},
   182  					},
   183  				},
   184  			},
   185  			"Foo3": {
   186  				Physical: map[string]sharding.Physical{
   187  					"abcd": {},
   188  				},
   189  			},
   190  		},
   191  
   192  		ObjectSchema: &models.Schema{
   193  			Classes: []*models.Class{
   194  				{
   195  					Class: "Foo",
   196  					Properties: []*models.Property{
   197  						{
   198  							DataType: []string{"int"},
   199  							Name:     "prop_1",
   200  						},
   201  						{
   202  							DataType: []string{"bool"},
   203  							Name:     "prop_3",
   204  						},
   205  						{
   206  							DataType: []string{"text"},
   207  							Name:     "prop_4",
   208  						},
   209  					},
   210  					InvertedIndexConfig: &models.InvertedIndexConfig{
   211  						IndexTimestamps: true,
   212  					},
   213  					ReplicationConfig: &models.ReplicationConfig{
   214  						Factor: 8,
   215  					},
   216  					Vectorizer: "gpt-9",
   217  				},
   218  				{Class: "Foo2"},
   219  				{Class: "Foo3"},
   220  				{Class: "Foo4"},
   221  			},
   222  		},
   223  	}
   224  
   225  	actual := Diff("L", left, "R", right)
   226  
   227  	expected := []string{
   228  		"class Foo: property prop_2 exists in L, but not in R",
   229  		"class Foo: property prop_3 exists in R, but not in L",
   230  		"class Foo: property prop_4: mismatch: " +
   231  			"L has {\"dataType\":[\"text\"],\"name\":\"prop_4\",\"tokenization\":\"whitespace\"}, but " +
   232  			"R has {\"dataType\":[\"text\"],\"name\":\"prop_4\"}",
   233  		"class Foo: description mismatch: " +
   234  			"L has \"foo\", but R has \"\"",
   235  		"class Foo: inverted index config mismatch: " +
   236  			"L has {\"indexPropertyLength\":true}, " +
   237  			"but R has {\"indexTimestamps\":true}",
   238  		"class Foo: module config mismatch: " +
   239  			"L has \"bar\", but R has null",
   240  		"class Foo: replication config mismatch: " +
   241  			"L has {\"factor\":7}, but R has {\"factor\":8}",
   242  		"class Foo: sharding config mismatch: " +
   243  			"L has {\"desiredCount\":7}, but R has null",
   244  		"class Foo: vector index config mismatch: " +
   245  			"L has {\"ef\":1000}, but R has null",
   246  		"class Foo: vector index type mismatch: " +
   247  			"L has \"age-n-ass-double-u\", but R has \"\"",
   248  		"class Foo: vectorizer mismatch: " +
   249  			"L has \"\", but R has \"gpt-9\"",
   250  		"class Foo3: missing sharding state in L",
   251  		"class Foo4: missing sharding state in R",
   252  		"class Foo2: sharding state mismatch: " +
   253  			"L has {\"indexID\":\"\",\"config\":{\"virtualPerPhysical\":0,\"desiredCount\":0,\"actualCount\":0,\"desiredVirtualCount\":0,\"actualVirtualCount\":0,\"key\":\"\",\"strategy\":\"\",\"function\":\"\"},\"physical\":{\"abcd\":{\"name\":\"\",\"ownsVirtual\":[\"v1\"],\"ownsPercentage\":0}},\"virtual\":null,\"partitioningEnabled\":false}, " +
   254  			"but R has {\"indexID\":\"\",\"config\":{\"virtualPerPhysical\":0,\"desiredCount\":0,\"actualCount\":0,\"desiredVirtualCount\":0,\"actualVirtualCount\":0,\"key\":\"\",\"strategy\":\"\",\"function\":\"\"},\"physical\":{\"xyz\":{\"name\":\"\",\"ownsPercentage\":0,\"belongsToNodes\":[\"n1\"]}},\"virtual\":null,\"partitioningEnabled\":false}",
   255  	}
   256  
   257  	for _, exp := range expected {
   258  		assert.Contains(t, actual, exp)
   259  	}
   260  }