github.com/weaviate/weaviate@v1.24.6/usecases/objects/replication_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 objects
    13  
    14  import (
    15  	"testing"
    16  	"time"
    17  
    18  	"github.com/go-openapi/strfmt"
    19  	"github.com/stretchr/testify/assert"
    20  	"github.com/stretchr/testify/require"
    21  	"github.com/weaviate/weaviate/entities/models"
    22  	"github.com/weaviate/weaviate/entities/schema/crossref"
    23  	"github.com/weaviate/weaviate/entities/storobj"
    24  )
    25  
    26  func Test_VObject_MarshalBinary(t *testing.T) {
    27  	now := time.Now()
    28  	tests := []struct {
    29  		name    string
    30  		vector  []float32
    31  		vectors models.Vectors
    32  	}{
    33  		{
    34  			name:   "with vector",
    35  			vector: []float32{1, 2, 3, 4, 5},
    36  		},
    37  		{
    38  			name: "with vectors",
    39  			vectors: models.Vectors{
    40  				"vec1": []float32{0.1, 0.2, 0.3, 0.4},
    41  				"vec2": []float32{1, 2},
    42  			},
    43  		},
    44  	}
    45  	for _, tt := range tests {
    46  		t.Run(tt.name, func(t *testing.T) {
    47  			obj := models.Object{
    48  				ID:                 strfmt.UUID("c6f85bf5-c3b7-4c1d-bd51-e899f9605336"),
    49  				Class:              "SomeClass",
    50  				CreationTimeUnix:   now.UnixMilli(),
    51  				LastUpdateTimeUnix: now.Add(time.Hour).UnixMilli(), // time-traveling ;)
    52  				Properties: map[string]interface{}{
    53  					"propA":    "this is prop A",
    54  					"propB":    "this is prop B",
    55  					"someDate": now.Format(time.RFC3339Nano),
    56  					"aNumber":  1e+06,
    57  					"crossRef": map[string]interface{}{
    58  						"beacon": "weaviate://localhost/OtherClass/c82d011c-f05a-43de-8a8a-ee9c814d4cfb",
    59  					},
    60  				},
    61  				Vector: tt.vector,
    62  				Additional: map[string]interface{}{
    63  					"score": 0.055465422484,
    64  				},
    65  			}
    66  			if tt.vectors != nil {
    67  				obj.Vectors = tt.vectors
    68  			}
    69  
    70  			t.Run("when object is present", func(t *testing.T) {
    71  				expected := VObject{
    72  					LatestObject:    &obj,
    73  					StaleUpdateTime: now.UnixMilli(),
    74  					Version:         1,
    75  				}
    76  
    77  				b, err := expected.MarshalBinary()
    78  				require.Nil(t, err)
    79  
    80  				var received VObject
    81  				err = received.UnmarshalBinary(b)
    82  				require.Nil(t, err)
    83  
    84  				assert.EqualValues(t, expected, received)
    85  			})
    86  
    87  			t.Run("when object is present", func(t *testing.T) {
    88  				expected := VObject{
    89  					LatestObject:    &obj,
    90  					StaleUpdateTime: now.UnixMilli(),
    91  					Version:         1,
    92  				}
    93  
    94  				b, err := expected.MarshalBinary()
    95  				require.Nil(t, err)
    96  
    97  				var received VObject
    98  				err = received.UnmarshalBinary(b)
    99  				require.Nil(t, err)
   100  
   101  				assert.EqualValues(t, expected, received)
   102  			})
   103  
   104  			t.Run("when object is nil", func(t *testing.T) {
   105  				expected := VObject{
   106  					LatestObject:    nil,
   107  					StaleUpdateTime: now.UnixMilli(),
   108  					Version:         1,
   109  				}
   110  
   111  				b, err := expected.MarshalBinary()
   112  				require.Nil(t, err)
   113  
   114  				var received VObject
   115  				err = received.UnmarshalBinary(b)
   116  				require.Nil(t, err)
   117  
   118  				assert.EqualValues(t, expected, received)
   119  			})
   120  		})
   121  	}
   122  }
   123  
   124  func Test_Replica_MarshalBinary(t *testing.T) {
   125  	now := time.Now()
   126  	id := strfmt.UUID("c6f85bf5-c3b7-4c1d-bd51-e899f9605336")
   127  	tests := []struct {
   128  		name    string
   129  		vector  []float32
   130  		vectors map[string][]float32
   131  	}{
   132  		{
   133  			name:   "with vector",
   134  			vector: []float32{1, 2, 3, 4, 5},
   135  		},
   136  		{
   137  			name: "with vectors",
   138  			vectors: map[string][]float32{
   139  				"vec1": {0.1, 0.2, 0.3, 0.4},
   140  				"vec2": {1, 2},
   141  			},
   142  		},
   143  	}
   144  	for _, tt := range tests {
   145  		t.Run(tt.name, func(t *testing.T) {
   146  			obj := storobj.Object{
   147  				MarshallerVersion: 1,
   148  				Object: models.Object{
   149  					ID:                 id,
   150  					Class:              "SomeClass",
   151  					CreationTimeUnix:   now.UnixMilli(),
   152  					LastUpdateTimeUnix: now.Add(time.Hour).UnixMilli(), // time-traveling ;)
   153  					Properties: map[string]interface{}{
   154  						"propA":    "this is prop A",
   155  						"propB":    "this is prop B",
   156  						"someDate": now.Format(time.RFC3339Nano),
   157  						"aNumber":  1e+06,
   158  						"crossRef": models.MultipleRef{
   159  							crossref.NewLocalhost("OtherClass", id).
   160  								SingleRef(),
   161  						},
   162  					},
   163  					Additional: map[string]interface{}{
   164  						"score": 0.055465422484,
   165  					},
   166  				},
   167  			}
   168  			if tt.vector != nil {
   169  				obj.Vector = tt.vector
   170  				obj.VectorLen = len(tt.vector)
   171  			}
   172  			if tt.vectors != nil {
   173  				obj.Vector = []float32{}
   174  				obj.Vectors = tt.vectors
   175  			}
   176  
   177  			t.Run("when object is present", func(t *testing.T) {
   178  				expected := Replica{
   179  					Object: &obj,
   180  					ID:     obj.ID(),
   181  				}
   182  
   183  				b, err := expected.MarshalBinary()
   184  				require.Nil(t, err)
   185  
   186  				var received Replica
   187  				err = received.UnmarshalBinary(b)
   188  				require.Nil(t, err)
   189  
   190  				assert.EqualValues(t, expected.Object, received.Object)
   191  				assert.EqualValues(t, expected.ID, received.ID)
   192  				assert.EqualValues(t, expected.Deleted, received.Deleted)
   193  			})
   194  
   195  			t.Run("when object is nil", func(t *testing.T) {
   196  				expected := Replica{
   197  					Object: nil,
   198  					ID:     obj.ID(),
   199  				}
   200  
   201  				b, err := expected.MarshalBinary()
   202  				require.Nil(t, err)
   203  
   204  				var received Replica
   205  				err = received.UnmarshalBinary(b)
   206  				require.Nil(t, err)
   207  
   208  				assert.EqualValues(t, expected.Object, received.Object)
   209  				assert.EqualValues(t, expected.ID, received.ID)
   210  				assert.EqualValues(t, expected.Deleted, received.Deleted)
   211  			})
   212  		})
   213  	}
   214  }
   215  
   216  func Test_Replicas_MarshalBinary(t *testing.T) {
   217  	now := time.Now()
   218  	id1 := strfmt.UUID("c6f85bf5-c3b7-4c1d-bd51-e899f9605336")
   219  	id2 := strfmt.UUID("88750a99-a72d-46c2-a582-89f02654391d")
   220  	tests := []struct {
   221  		name               string
   222  		vec1, vec2         []float32
   223  		vectors1, vectors2 map[string][]float32
   224  	}{
   225  		{
   226  			name: "with vector",
   227  			vec1: []float32{1, 2, 3, 4, 5},
   228  			vec2: []float32{10, 20, 30, 40, 50},
   229  		},
   230  		{
   231  			name: "with vectors",
   232  			vectors1: map[string][]float32{
   233  				"vec1": {0.1, 0.2, 0.3, 0.4},
   234  				"vec2": {1, 2},
   235  			},
   236  			vectors2: map[string][]float32{
   237  				"vec1": {0.11, 0.22, 0.33, 0.44},
   238  				"vec2": {11, 22},
   239  			},
   240  		},
   241  	}
   242  	for _, tt := range tests {
   243  		t.Run(tt.name, func(t *testing.T) {
   244  			obj1 := storobj.Object{
   245  				MarshallerVersion: 1,
   246  				Object: models.Object{
   247  					ID:                 id1,
   248  					Class:              "SomeClass",
   249  					CreationTimeUnix:   now.UnixMilli(),
   250  					LastUpdateTimeUnix: now.Add(time.Hour).UnixMilli(), // time-traveling ;)
   251  					Properties: map[string]interface{}{
   252  						"propA":    "this is prop A",
   253  						"propB":    "this is prop B",
   254  						"someDate": now.Format(time.RFC3339Nano),
   255  						"aNumber":  1e+06,
   256  						"crossRef": models.MultipleRef{
   257  							crossref.NewLocalhost("OtherClass", id1).
   258  								SingleRef(),
   259  						},
   260  					},
   261  					Additional: map[string]interface{}{
   262  						"score": 0.055465422484,
   263  					},
   264  				},
   265  				Vector: []float32{},
   266  			}
   267  			if tt.vec1 != nil {
   268  				obj1.Vector = tt.vec1
   269  				obj1.VectorLen = len(tt.vec1)
   270  			}
   271  			if tt.vectors1 != nil {
   272  				obj1.Vector = []float32{}
   273  				obj1.Vectors = tt.vectors2
   274  			}
   275  
   276  			obj2 := storobj.Object{
   277  				MarshallerVersion: 1,
   278  				Object: models.Object{
   279  					ID:                 id2,
   280  					Class:              "SomeClass",
   281  					CreationTimeUnix:   now.UnixMilli(),
   282  					LastUpdateTimeUnix: now.Add(time.Hour).UnixMilli(), // time-traveling ;)
   283  					Properties: map[string]interface{}{
   284  						"propA":    "this is prop A",
   285  						"propB":    "this is prop B",
   286  						"someDate": now.Format(time.RFC3339Nano),
   287  						"aNumber":  1e+06,
   288  						"crossRef": models.MultipleRef{
   289  							crossref.NewLocalhost("OtherClass", id2).
   290  								SingleRef(),
   291  						},
   292  					},
   293  					Additional: map[string]interface{}{
   294  						"score": 0.055465422484,
   295  					},
   296  				},
   297  			}
   298  			if tt.vec2 != nil {
   299  				obj2.Vector = tt.vec2
   300  				obj2.VectorLen = len(tt.vec2)
   301  			}
   302  			if tt.vectors2 != nil {
   303  				obj2.Vector = []float32{}
   304  				obj2.Vectors = tt.vectors2
   305  			}
   306  
   307  			t.Run("when objects are present", func(t *testing.T) {
   308  				expected := Replicas{
   309  					{
   310  						Object: &obj1,
   311  						ID:     obj1.ID(),
   312  					},
   313  					{
   314  						Object: &obj2,
   315  						ID:     obj2.ID(),
   316  					},
   317  				}
   318  
   319  				b, err := expected.MarshalBinary()
   320  				require.Nil(t, err)
   321  
   322  				var received Replicas
   323  				err = received.UnmarshalBinary(b)
   324  				require.Nil(t, err)
   325  
   326  				assert.Len(t, received, 2)
   327  				assert.EqualValues(t, expected[0].Object, received[0].Object)
   328  				assert.EqualValues(t, expected[0].ID, received[0].ID)
   329  				assert.EqualValues(t, expected[0].Deleted, received[0].Deleted)
   330  				assert.EqualValues(t, expected[1].Object, received[1].Object)
   331  				assert.EqualValues(t, expected[1].ID, received[1].ID)
   332  				assert.EqualValues(t, expected[1].Deleted, received[1].Deleted)
   333  			})
   334  
   335  			t.Run("when there is a nil object", func(t *testing.T) {
   336  				expected := Replicas{
   337  					{
   338  						Object: &obj1,
   339  						ID:     obj1.ID(),
   340  					},
   341  					{
   342  						Object: nil,
   343  						ID:     obj2.ID(),
   344  					},
   345  				}
   346  
   347  				b, err := expected.MarshalBinary()
   348  				require.Nil(t, err)
   349  
   350  				var received Replicas
   351  				err = received.UnmarshalBinary(b)
   352  				require.Nil(t, err)
   353  
   354  				assert.Len(t, received, 2)
   355  				assert.EqualValues(t, expected[0].Object, received[0].Object)
   356  				assert.EqualValues(t, expected[0].ID, received[0].ID)
   357  				assert.EqualValues(t, expected[0].Deleted, received[0].Deleted)
   358  				assert.EqualValues(t, expected[1].Object, received[1].Object)
   359  				assert.EqualValues(t, expected[1].ID, received[1].ID)
   360  				assert.EqualValues(t, expected[1].Deleted, received[1].Deleted)
   361  			})
   362  		})
   363  	}
   364  }