github.com/weaviate/weaviate@v1.24.6/entities/storobj/storage_object_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 storobj
    13  
    14  import (
    15  	"fmt"
    16  	"testing"
    17  	"time"
    18  
    19  	"github.com/go-openapi/strfmt"
    20  	"github.com/stretchr/testify/assert"
    21  	"github.com/stretchr/testify/require"
    22  	"github.com/weaviate/weaviate/entities/additional"
    23  	"github.com/weaviate/weaviate/entities/models"
    24  	"github.com/weaviate/weaviate/entities/schema"
    25  )
    26  
    27  func TestStorageObjectMarshalling(t *testing.T) {
    28  	before := FromObject(
    29  		&models.Object{
    30  			Class:              "MyFavoriteClass",
    31  			CreationTimeUnix:   123456,
    32  			LastUpdateTimeUnix: 56789,
    33  			ID:                 strfmt.UUID("73f2eb5f-5abf-447a-81ca-74b1dd168247"),
    34  			Additional: models.AdditionalProperties{
    35  				"classification": &additional.Classification{
    36  					BasedOn: []string{"some", "fields"},
    37  				},
    38  				"interpretation": map[string]interface{}{
    39  					"Source": []interface{}{
    40  						map[string]interface{}{
    41  							"concept":    "foo",
    42  							"occurrence": float64(7),
    43  							"weight":     float64(3),
    44  						},
    45  					},
    46  				},
    47  			},
    48  			Properties: map[string]interface{}{
    49  				"name": "MyName",
    50  				"foo":  float64(17),
    51  			},
    52  		},
    53  		[]float32{1, 2, 0.7},
    54  		models.Vectors{
    55  			"vector1": {1, 2, 3},
    56  			"vector2": {4, 5, 6},
    57  		},
    58  	)
    59  	before.DocID = 7
    60  
    61  	asBinary, err := before.MarshalBinary()
    62  	require.Nil(t, err)
    63  
    64  	after, err := FromBinary(asBinary)
    65  	require.Nil(t, err)
    66  
    67  	t.Run("compare", func(t *testing.T) {
    68  		assert.Equal(t, before, after)
    69  	})
    70  
    71  	t.Run("extract only doc id and compare", func(t *testing.T) {
    72  		id, err := DocIDFromBinary(asBinary)
    73  		require.Nil(t, err)
    74  		assert.Equal(t, uint64(7), id)
    75  	})
    76  
    77  	t.Run("extract single text prop", func(t *testing.T) {
    78  		prop, ok, err := ParseAndExtractTextProp(asBinary, "name")
    79  		require.Nil(t, err)
    80  		require.True(t, ok)
    81  		require.NotEmpty(t, prop)
    82  		assert.Equal(t, "MyName", prop[0])
    83  	})
    84  
    85  	t.Run("extract non-existing text prop", func(t *testing.T) {
    86  		prop, ok, err := ParseAndExtractTextProp(asBinary, "IDoNotExist")
    87  		require.Nil(t, err)
    88  		require.True(t, ok)
    89  		require.Empty(t, prop)
    90  	})
    91  }
    92  
    93  func TestFilteringNilProperty(t *testing.T) {
    94  	object := FromObject(
    95  		&models.Object{
    96  			Class: "MyFavoriteClass",
    97  			ID:    "73f2eb5f-5abf-447a-81ca-74b1dd168247",
    98  			Properties: map[string]interface{}{
    99  				"IWillBeRemoved": nil,
   100  				"IWillStay":      float64(17),
   101  			},
   102  		},
   103  		[]float32{1, 2, 0.7},
   104  		nil,
   105  	)
   106  	props := object.Properties()
   107  	propsTyped, ok := props.(map[string]interface{})
   108  	require.True(t, ok)
   109  	assert.Equal(t, propsTyped["IWillStay"], float64(17))
   110  
   111  	elem, ok := propsTyped["IWillBeRemoved"]
   112  	require.False(t, ok)
   113  	require.Nil(t, elem)
   114  }
   115  
   116  func TestStorageObjectUnmarshallingSpecificProps(t *testing.T) {
   117  	before := FromObject(
   118  		&models.Object{
   119  			Class:              "MyFavoriteClass",
   120  			CreationTimeUnix:   123456,
   121  			LastUpdateTimeUnix: 56789,
   122  			ID:                 strfmt.UUID("73f2eb5f-5abf-447a-81ca-74b1dd168247"),
   123  			Additional: models.AdditionalProperties{
   124  				"classification": &additional.Classification{
   125  					BasedOn: []string{"some", "fields"},
   126  				},
   127  				"interpretation": map[string]interface{}{
   128  					"Source": []interface{}{
   129  						map[string]interface{}{
   130  							"concept":    "foo",
   131  							"occurrence": float64(7),
   132  							"weight":     float64(3),
   133  						},
   134  					},
   135  				},
   136  			},
   137  			Properties: map[string]interface{}{
   138  				"name": "MyName",
   139  				"foo":  float64(17),
   140  			},
   141  		},
   142  		[]float32{1, 2, 0.7},
   143  		models.Vectors{
   144  			"vector1": {1, 2, 3},
   145  			"vector2": {4, 5, 6},
   146  			"vector3": {7, 8, 9},
   147  		},
   148  	)
   149  	before.DocID = 7
   150  
   151  	asBinary, err := before.MarshalBinary()
   152  	require.Nil(t, err)
   153  
   154  	t.Run("without any optional", func(t *testing.T) {
   155  		after, err := FromBinaryOptional(asBinary, additional.Properties{})
   156  		require.Nil(t, err)
   157  
   158  		t.Run("compare", func(t *testing.T) {
   159  			// modify before to match expectations of after
   160  			before.Object.Additional = nil
   161  			before.Vector = nil
   162  			before.VectorLen = 3
   163  			before.Vectors = nil
   164  			assert.Equal(t, before, after)
   165  
   166  			assert.Equal(t, before.DocID, after.DocID)
   167  
   168  			// The vector length should always be returned (for usage metrics
   169  			// purposes) even if the vector itself is skipped
   170  			assert.Equal(t, after.VectorLen, 3)
   171  		})
   172  	})
   173  }
   174  
   175  func TestNewStorageObject(t *testing.T) {
   176  	t.Run("objects", func(t *testing.T) {
   177  		so := New(12)
   178  
   179  		t.Run("check index id", func(t *testing.T) {
   180  			assert.Equal(t, uint64(12), so.DocID)
   181  		})
   182  
   183  		t.Run("is invalid without required params", func(t *testing.T) {
   184  			assert.False(t, so.Valid())
   185  		})
   186  
   187  		t.Run("reassign index id", func(t *testing.T) {
   188  			so.DocID = 13
   189  			assert.Equal(t, uint64(13), so.DocID)
   190  		})
   191  
   192  		t.Run("assign class", func(t *testing.T) {
   193  			so.SetClass("MyClass")
   194  			assert.Equal(t, schema.ClassName("MyClass"), so.Class())
   195  		})
   196  
   197  		t.Run("assign uuid", func(t *testing.T) {
   198  			id := strfmt.UUID("bf706904-8618-463f-899c-4a2aafd48d56")
   199  			so.SetID(id)
   200  			assert.Equal(t, id, so.ID())
   201  		})
   202  
   203  		t.Run("assign uuid", func(t *testing.T) {
   204  			schema := map[string]interface{}{
   205  				"foo": "bar",
   206  			}
   207  			so.SetProperties(schema)
   208  			assert.Equal(t, schema, so.Properties())
   209  		})
   210  
   211  		t.Run("must now be valid", func(t *testing.T) {
   212  			assert.True(t, so.Valid())
   213  		})
   214  
   215  		t.Run("make sure it's identical with an object created from an existing object",
   216  			func(t *testing.T) {
   217  				alt := FromObject(&models.Object{
   218  					Class: "MyClass",
   219  					ID:    "bf706904-8618-463f-899c-4a2aafd48d56",
   220  					Properties: map[string]interface{}{
   221  						"foo": "bar",
   222  					},
   223  				}, nil, nil)
   224  				alt.DocID = 13
   225  
   226  				assert.Equal(t, so, alt)
   227  			})
   228  	})
   229  
   230  	t.Run("objects", func(t *testing.T) {
   231  		so := New(12)
   232  
   233  		t.Run("check index id", func(t *testing.T) {
   234  			assert.Equal(t, uint64(12), so.DocID)
   235  		})
   236  
   237  		t.Run("is invalid without required params", func(t *testing.T) {
   238  			assert.False(t, so.Valid())
   239  		})
   240  
   241  		t.Run("reassign index id", func(t *testing.T) {
   242  			so.DocID = 13
   243  			assert.Equal(t, uint64(13), so.DocID)
   244  		})
   245  
   246  		t.Run("assign class", func(t *testing.T) {
   247  			so.SetClass("MyClass")
   248  			assert.Equal(t, schema.ClassName("MyClass"), so.Class())
   249  		})
   250  
   251  		t.Run("assign uuid", func(t *testing.T) {
   252  			id := strfmt.UUID("bf706904-8618-463f-899c-4a2aafd48d56")
   253  			so.SetID(id)
   254  			assert.Equal(t, id, so.ID())
   255  		})
   256  
   257  		t.Run("assign uuid", func(t *testing.T) {
   258  			schema := map[string]interface{}{
   259  				"foo": "bar",
   260  			}
   261  			so.SetProperties(schema)
   262  			assert.Equal(t, schema, so.Properties())
   263  		})
   264  
   265  		t.Run("must now be valid", func(t *testing.T) {
   266  			assert.True(t, so.Valid())
   267  		})
   268  
   269  		t.Run("make sure it's identical with an object created from an existing action",
   270  			func(t *testing.T) {
   271  				alt := FromObject(&models.Object{
   272  					Class: "MyClass",
   273  					ID:    "bf706904-8618-463f-899c-4a2aafd48d56",
   274  					Properties: map[string]interface{}{
   275  						"foo": "bar",
   276  					},
   277  				}, nil, nil)
   278  				alt.DocID = 13
   279  
   280  				assert.Equal(t, so, alt)
   281  			})
   282  	})
   283  }
   284  
   285  func TestStorageArrayObjectMarshalling(t *testing.T) {
   286  	before := FromObject(
   287  		&models.Object{
   288  			Class:              "MyFavoriteClass",
   289  			CreationTimeUnix:   123456,
   290  			LastUpdateTimeUnix: 56789,
   291  			ID:                 strfmt.UUID("73f2eb5f-5abf-447a-81ca-74b1dd168247"),
   292  			Additional: models.AdditionalProperties{
   293  				"classification": &additional.Classification{
   294  					BasedOn: []string{"some", "fields"},
   295  				},
   296  				"interpretation": map[string]interface{}{
   297  					"Source": []interface{}{
   298  						map[string]interface{}{
   299  							"concept":    "foo",
   300  							"occurrence": float64(7),
   301  							"weight":     float64(3),
   302  						},
   303  					},
   304  				},
   305  			},
   306  			Properties: map[string]interface{}{
   307  				"textArray":   []string{"c", "d"},
   308  				"numberArray": []float64{1.1, 2.1},
   309  				"foo":         float64(17),
   310  			},
   311  		},
   312  		[]float32{1, 2, 0.7},
   313  		models.Vectors{
   314  			"vector1": {1, 2, 3},
   315  			"vector2": {4, 5, 6},
   316  			"vector3": {7, 8, 9},
   317  		},
   318  	)
   319  	before.DocID = 7
   320  
   321  	asBinary, err := before.MarshalBinary()
   322  	require.Nil(t, err)
   323  
   324  	after, err := FromBinary(asBinary)
   325  	require.Nil(t, err)
   326  
   327  	t.Run("compare", func(t *testing.T) {
   328  		assert.Equal(t, before, after)
   329  	})
   330  
   331  	t.Run("extract only doc id and compare", func(t *testing.T) {
   332  		id, err := DocIDFromBinary(asBinary)
   333  		require.Nil(t, err)
   334  		assert.Equal(t, uint64(7), id)
   335  	})
   336  
   337  	t.Run("extract text array prop", func(t *testing.T) {
   338  		prop, ok, err := ParseAndExtractTextProp(asBinary, "textArray")
   339  		require.Nil(t, err)
   340  		require.True(t, ok)
   341  		assert.Equal(t, []string{"c", "d"}, prop)
   342  	})
   343  
   344  	t.Run("extract number array prop", func(t *testing.T) {
   345  		prop, ok, err := ParseAndExtractNumberArrayProp(asBinary, "numberArray")
   346  		require.Nil(t, err)
   347  		require.True(t, ok)
   348  		assert.Equal(t, []float64{1.1, 2.1}, prop)
   349  	})
   350  }
   351  
   352  func TestExtractionOfSingleProperties(t *testing.T) {
   353  	expected := map[string]interface{}{
   354  		"numberArray":  []interface{}{1.1, 2.1},
   355  		"intArray":     []interface{}{1., 2., 5000.},
   356  		"textArrayUTF": []interface{}{"語", "b"},
   357  		"textArray":    []interface{}{"hello", ",", "I", "am", "a", "veeery", "long", "Array", "with some text."},
   358  		"foo":          float64(17),
   359  		"text":         "single string",
   360  		"bool":         true,
   361  		"time":         "2011-11-23T01:52:23.000004234Z",
   362  		"boolArray":    []interface{}{true, false, true},
   363  		"beacon":       []interface{}{map[string]interface{}{"beacon": "weaviate://localhost/SomeClass/3453/73f4eb5f-5abf-447a-81ca-74b1dd168247"}},
   364  		"ref":          []interface{}{map[string]interface{}{"beacon": "weaviate://localhost/SomeClass/3453/73f4eb5f-5abf-447a-81ca-74b1dd168247"}},
   365  	}
   366  	properties := map[string]interface{}{
   367  		"numberArray":  []float64{1.1, 2.1},
   368  		"intArray":     []int32{1, 2, 5000},
   369  		"textArrayUTF": []string{"語", "b"},
   370  		"textArray":    []string{"hello", ",", "I", "am", "a", "veeery", "long", "Array", "with some text."},
   371  		"foo":          float64(17),
   372  		"text":         "single string",
   373  		"bool":         true,
   374  		"time":         time.Date(2011, 11, 23, 1, 52, 23, 4234, time.UTC),
   375  		"boolArray":    []bool{true, false, true},
   376  		"beacon":       []map[string]interface{}{{"beacon": "weaviate://localhost/SomeClass/3453/73f4eb5f-5abf-447a-81ca-74b1dd168247"}},
   377  		"ref":          []models.SingleRef{{Beacon: "weaviate://localhost/SomeClass/3453/73f4eb5f-5abf-447a-81ca-74b1dd168247", Class: "OtherClass", Href: "/v1/f81bfe5e-16ba-4615-a516-46c2ae2e5a80"}},
   378  	}
   379  	before := FromObject(
   380  		&models.Object{
   381  			Class:              "MyFavoriteClass",
   382  			CreationTimeUnix:   123456,
   383  			LastUpdateTimeUnix: 56789,
   384  			ID:                 strfmt.UUID("73f2eb5f-5abf-447a-81ca-74b1dd168247"),
   385  			Properties:         properties,
   386  		},
   387  		[]float32{1, 2, 0.7},
   388  		nil,
   389  	)
   390  
   391  	before.DocID = 7
   392  	byteObject, err := before.MarshalBinary()
   393  	require.Nil(t, err)
   394  
   395  	var propertyNames []string
   396  	var propStrings [][]string
   397  	for key := range properties {
   398  		propertyNames = append(propertyNames, key)
   399  		propStrings = append(propStrings, []string{key})
   400  	}
   401  
   402  	extractedProperties := map[string]interface{}{}
   403  
   404  	// test with reused property map
   405  	for i := 0; i < 2; i++ {
   406  		require.Nil(t, UnmarshalPropertiesFromObject(byteObject, &extractedProperties, propertyNames, propStrings))
   407  		for key := range expected {
   408  			require.Equal(t, expected[key], extractedProperties[key])
   409  		}
   410  
   411  	}
   412  }
   413  
   414  func TestStorageObjectMarshallingWithGroup(t *testing.T) {
   415  	before := FromObject(
   416  		&models.Object{
   417  			Class:              "MyFavoriteClass",
   418  			CreationTimeUnix:   123456,
   419  			LastUpdateTimeUnix: 56789,
   420  			ID:                 strfmt.UUID("73f2eb5f-5abf-447a-81ca-74b1dd168247"),
   421  			Additional: models.AdditionalProperties{
   422  				"classification": &additional.Classification{
   423  					BasedOn: []string{"some", "fields"},
   424  				},
   425  				"interpretation": map[string]interface{}{
   426  					"Source": []interface{}{
   427  						map[string]interface{}{
   428  							"concept":    "foo",
   429  							"occurrence": float64(7),
   430  							"weight":     float64(3),
   431  						},
   432  					},
   433  				},
   434  				"group": &additional.Group{
   435  					ID: 100,
   436  					GroupedBy: &additional.GroupedBy{
   437  						Value: "group-by-some-property",
   438  						Path:  []string{"property-path"},
   439  					},
   440  					MaxDistance: 0.1,
   441  					MinDistance: 0.2,
   442  					Count:       200,
   443  					Hits: []map[string]interface{}{
   444  						{
   445  							"property1": "value1",
   446  							"_additional": &additional.GroupHitAdditional{
   447  								ID:       "2c76ca18-2073-4c48-aa52-7f444d2f5b80",
   448  								Distance: 0.24,
   449  							},
   450  						},
   451  						{
   452  							"property1": "value2",
   453  						},
   454  					},
   455  				},
   456  			},
   457  			Properties: map[string]interface{}{
   458  				"name": "MyName",
   459  				"foo":  float64(17),
   460  			},
   461  		},
   462  		[]float32{1, 2, 0.7},
   463  		models.Vectors{
   464  			"vector1": {1, 2, 3},
   465  			"vector2": {4, 5, 6},
   466  			"vector3": {7, 8, 9},
   467  		},
   468  	)
   469  	before.DocID = 7
   470  
   471  	asBinary, err := before.MarshalBinary()
   472  	require.Nil(t, err)
   473  
   474  	after, err := FromBinary(asBinary)
   475  	require.Nil(t, err)
   476  
   477  	t.Run("compare", func(t *testing.T) {
   478  		assert.Equal(t, before, after)
   479  	})
   480  
   481  	t.Run("extract only doc id and compare", func(t *testing.T) {
   482  		id, err := DocIDFromBinary(asBinary)
   483  		require.Nil(t, err)
   484  		assert.Equal(t, uint64(7), id)
   485  	})
   486  
   487  	t.Run("extract single text prop", func(t *testing.T) {
   488  		prop, ok, err := ParseAndExtractTextProp(asBinary, "name")
   489  		require.Nil(t, err)
   490  		require.True(t, ok)
   491  		require.NotEmpty(t, prop)
   492  		assert.Equal(t, "MyName", prop[0])
   493  	})
   494  
   495  	t.Run("extract non-existing text prop", func(t *testing.T) {
   496  		prop, ok, err := ParseAndExtractTextProp(asBinary, "IDoNotExist")
   497  		require.Nil(t, err)
   498  		require.True(t, ok)
   499  		require.Empty(t, prop)
   500  	})
   501  
   502  	t.Run("extract group additional property", func(t *testing.T) {
   503  		require.NotNil(t, after.AdditionalProperties())
   504  		require.NotNil(t, after.AdditionalProperties()["group"])
   505  		group, ok := after.AdditionalProperties()["group"].(*additional.Group)
   506  		require.True(t, ok)
   507  		assert.Equal(t, 100, group.ID)
   508  		assert.NotNil(t, group.GroupedBy)
   509  		assert.Equal(t, "group-by-some-property", group.GroupedBy.Value)
   510  		assert.Equal(t, []string{"property-path"}, group.GroupedBy.Path)
   511  		assert.Equal(t, 200, group.Count)
   512  		assert.Equal(t, float32(0.1), group.MaxDistance)
   513  		assert.Equal(t, float32(0.2), group.MinDistance)
   514  		require.Len(t, group.Hits, 2)
   515  		require.NotNil(t, group.Hits[0]["_additional"])
   516  		groupHitAdditional, ok := group.Hits[0]["_additional"].(*additional.GroupHitAdditional)
   517  		require.True(t, ok)
   518  		assert.Equal(t, strfmt.UUID("2c76ca18-2073-4c48-aa52-7f444d2f5b80"), groupHitAdditional.ID)
   519  		assert.Equal(t, float32(0.24), groupHitAdditional.Distance)
   520  		assert.Equal(t, "value1", group.Hits[0]["property1"])
   521  		require.Nil(t, group.Hits[1]["_additional"])
   522  		assert.Equal(t, "value2", group.Hits[1]["property1"])
   523  	})
   524  }
   525  
   526  func TestStorageMaxVectorDimensionsObjectMarshalling(t *testing.T) {
   527  	generateVector := func(dims uint16) []float32 {
   528  		vector := make([]float32, dims)
   529  		for i := range vector {
   530  			vector[i] = 0.1
   531  		}
   532  		return vector
   533  	}
   534  	// 65535 is max uint16 number
   535  	edgeVectorLengths := []uint16{0, 1, 768, 50000, 65535}
   536  	for _, vectorLength := range edgeVectorLengths {
   537  		t.Run(fmt.Sprintf("%v vector dimensions", vectorLength), func(t *testing.T) {
   538  			t.Run("marshal binary", func(t *testing.T) {
   539  				vector := generateVector(vectorLength)
   540  				before := FromObject(
   541  					&models.Object{
   542  						Class:            "MyFavoriteClass",
   543  						CreationTimeUnix: 123456,
   544  						ID:               strfmt.UUID("73f2eb5f-5abf-447a-81ca-74b1dd168247"),
   545  						Properties: map[string]interface{}{
   546  							"name": "myName",
   547  						},
   548  					},
   549  					vector,
   550  					nil,
   551  				)
   552  				before.DocID = 7
   553  
   554  				asBinary, err := before.MarshalBinary()
   555  				require.Nil(t, err)
   556  
   557  				after, err := FromBinary(asBinary)
   558  				require.Nil(t, err)
   559  
   560  				t.Run("compare", func(t *testing.T) {
   561  					assert.Equal(t, before, after)
   562  				})
   563  
   564  				t.Run("try to extract a property", func(t *testing.T) {
   565  					prop, ok, err := ParseAndExtractTextProp(asBinary, "name")
   566  					require.Nil(t, err)
   567  					require.True(t, ok)
   568  					assert.Equal(t, []string{"myName"}, prop)
   569  				})
   570  			})
   571  
   572  			t.Run("marshal optional binary", func(t *testing.T) {
   573  				vector := generateVector(vectorLength)
   574  				before := FromObject(
   575  					&models.Object{
   576  						Class:            "MyFavoriteClass",
   577  						CreationTimeUnix: 123456,
   578  						ID:               strfmt.UUID("73f2eb5f-5abf-447a-81ca-74b1dd168247"),
   579  						Properties: map[string]interface{}{
   580  							"name": "myName",
   581  						},
   582  					},
   583  					vector,
   584  					nil,
   585  				)
   586  				before.DocID = 7
   587  
   588  				asBinary, err := before.MarshalBinary()
   589  				require.Nil(t, err)
   590  
   591  				t.Run("get without additional properties", func(t *testing.T) {
   592  					after, err := FromBinaryOptional(asBinary, additional.Properties{})
   593  					require.Nil(t, err)
   594  					// modify before to match expectations of after
   595  					before.Object.Additional = nil
   596  					before.Vector = nil
   597  					before.VectorLen = int(vectorLength)
   598  					assert.Equal(t, before, after)
   599  
   600  					assert.Equal(t, before.DocID, after.DocID)
   601  
   602  					// The vector length should always be returned (for usage metrics
   603  					// purposes) even if the vector itself is skipped
   604  					assert.Equal(t, after.VectorLen, int(vectorLength))
   605  				})
   606  
   607  				t.Run("get with additional property vector", func(t *testing.T) {
   608  					after, err := FromBinaryOptional(asBinary, additional.Properties{Vector: true})
   609  					require.Nil(t, err)
   610  					// modify before to match expectations of after
   611  					before.Object.Additional = nil
   612  					before.Vector = vector
   613  					before.VectorLen = int(vectorLength)
   614  					assert.Equal(t, before, after)
   615  
   616  					assert.Equal(t, before.DocID, after.DocID)
   617  
   618  					// The vector length should always be returned (for usage metrics
   619  					// purposes) even if the vector itself is skipped
   620  					assert.Equal(t, after.VectorLen, int(vectorLength))
   621  					assert.Equal(t, vector, after.Vector)
   622  				})
   623  			})
   624  		})
   625  	}
   626  }