github.com/weaviate/weaviate@v1.24.6/test/acceptance/multi_tenancy/update_tenant_references_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 test 13 14 import ( 15 "testing" 16 17 "github.com/go-openapi/strfmt" 18 "github.com/google/uuid" 19 "github.com/stretchr/testify/assert" 20 "github.com/stretchr/testify/require" 21 "github.com/weaviate/weaviate/entities/models" 22 "github.com/weaviate/weaviate/test/helper" 23 ) 24 25 func TestTenantObjectsReferenceUpdates(t *testing.T) { 26 className := "MultiTenantClass" 27 refProp := "refProp1" 28 29 class := models.Class{ 30 Class: className, 31 MultiTenancyConfig: &models.MultiTenancyConfig{Enabled: true}, 32 Properties: []*models.Property{ 33 {Name: refProp, DataType: []string{className}}, 34 }, 35 } 36 defer func() { 37 helper.DeleteClass(t, className) 38 }() 39 helper.CreateClass(t, &class) 40 41 tenantNames := []string{"Tenant1", "Tenant2", "Tenant3"} 42 tenants := make([]*models.Tenant, len(tenantNames)) 43 for i := range tenants { 44 tenants[i] = &models.Tenant{Name: tenantNames[i]} 45 } 46 helper.CreateTenants(t, className, tenants) 47 48 objs := make([]*models.Object, 0) 49 for i := 0; i < len(tenantNames)*4; i++ { 50 obj := &models.Object{ 51 ID: strfmt.UUID(uuid.New().String()), 52 Class: className, 53 Tenant: tenantNames[i%len(tenantNames)], 54 } 55 objs = append(objs, obj) 56 helper.CreateObject(t, obj) 57 } 58 59 for _, obj := range objs { 60 ref := &models.SingleRef{Beacon: helper.NewBeacon(className, obj.ID)} 61 helper.AddReferenceTenant(t, obj, ref, refProp, obj.Tenant) 62 helper.AddReferenceTenant(t, obj, ref, refProp, obj.Tenant) 63 } 64 65 for _, obj := range objs { 66 resp, err := helper.TenantObject(t, obj.Class, obj.ID, obj.Tenant) 67 require.Nil(t, err) 68 require.Equal(t, obj.ID, resp.ID) 69 require.Equal(t, obj.Class, resp.Class) 70 refs := resp.Properties.(map[string]interface{})[refProp].([]interface{}) 71 require.Len(t, refs, 2) 72 expectedBeacon := helper.NewBeacon(className, obj.ID).String() 73 assert.Equal(t, expectedBeacon, refs[0].(map[string]interface{})["beacon"]) 74 } 75 76 t.Run("Update reference - single", func(t *testing.T) { 77 for i, obj := range objs { 78 j := (i + len(tenantNames)) % len(objs) // always reference the next object with the same tenant 79 ref := models.MultipleRef{{Beacon: helper.NewBeacon(className, objs[j].ID)}} 80 helper.UpdateReferenceTenant(t, obj, ref, refProp, obj.Tenant) 81 } 82 83 for i, obj := range objs { 84 resp, err := helper.TenantObject(t, obj.Class, obj.ID, obj.Tenant) 85 require.Nil(t, err) 86 require.Equal(t, obj.ID, resp.ID) 87 require.Equal(t, obj.Class, resp.Class) 88 refs := resp.Properties.(map[string]interface{})[refProp].([]interface{}) 89 require.Len(t, refs, 1) 90 j := (i + len(tenantNames)) % len(objs) // always reference the next object with the same tenant 91 expectedBeacon := helper.NewBeacon(className, objs[j].ID).String() 92 assert.Equal(t, expectedBeacon, refs[0].(map[string]interface{})["beacon"]) 93 } 94 }) 95 96 t.Run("Update reference - multiple", func(t *testing.T) { 97 for i, obj := range objs { 98 ref := models.MultipleRef{} 99 j := (i + 2*len(tenantNames)) % len(objs) 100 ref = append(ref, &models.SingleRef{Beacon: helper.NewBeacon(className, objs[j].ID)}) 101 ref = append(ref, &models.SingleRef{Beacon: helper.NewBeacon(className, objs[j].ID)}) 102 ref = append(ref, &models.SingleRef{Beacon: helper.NewBeacon(className, objs[j].ID)}) 103 helper.UpdateReferenceTenant(t, obj, ref, refProp, obj.Tenant) 104 } 105 106 for i, obj := range objs { 107 resp, err := helper.TenantObject(t, obj.Class, obj.ID, obj.Tenant) 108 require.Nil(t, err) 109 require.Equal(t, obj.ID, resp.ID) 110 require.Equal(t, obj.Class, resp.Class) 111 refs := resp.Properties.(map[string]interface{})[refProp].([]interface{}) 112 require.Len(t, refs, 3) 113 j := (i + 2*len(tenantNames)) % len(objs) // always reference the next object with the same tenant 114 expectedBeacon := helper.NewBeacon(className, objs[j].ID).String() 115 assert.Equal(t, expectedBeacon, refs[0].(map[string]interface{})["beacon"]) 116 } 117 }) 118 119 t.Run("Update reference - empty", func(t *testing.T) { 120 for _, obj := range objs { 121 ref := models.MultipleRef{} 122 helper.UpdateReferenceTenant(t, obj, ref, refProp, obj.Tenant) 123 } 124 125 for _, obj := range objs { 126 resp, err := helper.TenantObject(t, obj.Class, obj.ID, obj.Tenant) 127 require.Nil(t, err) 128 require.Equal(t, obj.ID, resp.ID) 129 require.Equal(t, obj.Class, resp.Class) 130 refs := resp.Properties.(map[string]interface{})[refProp].([]interface{}) 131 require.Len(t, refs, 0) 132 } 133 }) 134 }