github.com/weaviate/weaviate@v1.24.6/test/acceptance/actions/setup_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 "encoding/json" 16 "fmt" 17 "net/http" 18 "testing" 19 20 "github.com/stretchr/testify/require" 21 "github.com/weaviate/weaviate/client/nodes" 22 clschema "github.com/weaviate/weaviate/client/schema" 23 "github.com/weaviate/weaviate/entities/models" 24 "github.com/weaviate/weaviate/entities/schema" 25 "github.com/weaviate/weaviate/entities/storagestate" 26 "github.com/weaviate/weaviate/entities/verbosity" 27 "github.com/weaviate/weaviate/test/helper" 28 graphqlhelper "github.com/weaviate/weaviate/test/helper/graphql" 29 ) 30 31 func Test_Objects(t *testing.T) { 32 t.Run("setup", func(t *testing.T) { 33 helper.AssertCreateObjectClass(t, &models.Class{ 34 Class: "ObjectTestThing", 35 ModuleConfig: map[string]interface{}{ 36 "text2vec-contextionary": map[string]interface{}{ 37 "vectorizeClassName": true, 38 }, 39 }, 40 Properties: []*models.Property{ 41 { 42 Name: "testString", 43 DataType: schema.DataTypeText.PropString(), 44 Tokenization: models.PropertyTokenizationWhitespace, 45 }, 46 }, 47 }) 48 helper.AssertCreateObjectClass(t, &models.Class{ 49 Class: "TestObject", 50 ModuleConfig: map[string]interface{}{ 51 "text2vec-contextionary": map[string]interface{}{ 52 "vectorizeClassName": true, 53 }, 54 }, 55 Properties: []*models.Property{ 56 { 57 Name: "testString", 58 DataType: schema.DataTypeText.PropString(), 59 Tokenization: models.PropertyTokenizationWhitespace, 60 }, 61 { 62 Name: "testWholeNumber", 63 DataType: []string{"int"}, 64 }, 65 { 66 Name: "testNumber", 67 DataType: []string{"number"}, 68 }, 69 { 70 Name: "testDateTime", 71 DataType: []string{"date"}, 72 }, 73 { 74 Name: "testTrueFalse", 75 DataType: []string{"boolean"}, 76 }, 77 { 78 Name: "testReference", 79 DataType: []string{"ObjectTestThing"}, 80 }, 81 }, 82 }) 83 helper.AssertCreateObjectClass(t, &models.Class{ 84 Class: "TestObjectTwo", 85 ModuleConfig: map[string]interface{}{ 86 "text2vec-contextionary": map[string]interface{}{ 87 "vectorizeClassName": true, 88 }, 89 }, 90 Properties: []*models.Property{ 91 { 92 Name: "testReference", 93 DataType: []string{"TestObject"}, 94 }, 95 { 96 Name: "testReferences", 97 DataType: []string{"TestObject"}, 98 }, 99 { 100 Name: "testString", 101 DataType: schema.DataTypeText.PropString(), 102 Tokenization: models.PropertyTokenizationWhitespace, 103 }, 104 }, 105 }) 106 }) 107 108 // tests 109 t.Run("adding objects", addingObjects) 110 t.Run("removing objects", removingObjects) 111 t.Run("object references", objectReferences) 112 t.Run("updating objects deprecated", updateObjectsDeprecated) 113 114 // tear down 115 helper.AssertDeleteObjectClass(t, "ObjectTestThing") 116 helper.AssertDeleteObjectClass(t, "TestObject") 117 helper.AssertDeleteObjectClass(t, "TestObjectTwo") 118 } 119 120 func Test_Delete_ReadOnly_Classes(t *testing.T) { 121 className := "DeleteReadonlyClassTest" 122 123 t.Run("setup", func(t *testing.T) { 124 helper.AssertCreateObjectClass(t, &models.Class{ 125 Class: className, 126 ModuleConfig: map[string]interface{}{ 127 "text2vec-contextionary": map[string]interface{}{ 128 "vectorizeClassName": true, 129 }, 130 }, 131 Properties: []*models.Property{ 132 { 133 Name: "stringProp", 134 DataType: schema.DataTypeText.PropString(), 135 Tokenization: models.PropertyTokenizationWhitespace, 136 }, 137 }, 138 }) 139 140 batchSize := 1000 141 batch := make([]*models.Object, batchSize) 142 for i := 0; i < batchSize; i++ { 143 batch[i] = &models.Object{ 144 Class: className, 145 Properties: map[string]interface{}{ 146 "stringProp": fmt.Sprintf("obj#%d", i+1), 147 }, 148 } 149 } 150 helper.CreateObjectsBatch(t, batch) 151 }) 152 153 t.Run("assert data exists", func(t *testing.T) { 154 res := graphqlhelper.AssertGraphQL(t, helper.RootAuth, 155 fmt.Sprintf("{Aggregate {%s {meta {count}}}}", className)) 156 count := res.Get("Aggregate", className).AsSlice()[0].(map[string]interface{})["meta"].(map[string]interface{})["count"] 157 require.EqualValues(t, json.Number("1000"), count) 158 }) 159 160 t.Run("set shard to readonly", func(t *testing.T) { 161 verbose := verbosity.OutputVerbose 162 nodesResp, err := helper.Client(t).Nodes.NodesGet(nodes.NewNodesGetParams().WithOutput(&verbose), nil) 163 require.Nil(t, err) 164 require.NotNil(t, nodesResp.Payload) 165 require.Len(t, nodesResp.Payload.Nodes, 1) 166 require.Len(t, nodesResp.Payload.Nodes[0].Shards, 1) 167 require.Equal(t, className, nodesResp.Payload.Nodes[0].Shards[0].Class) 168 targetShard := nodesResp.Payload.Nodes[0].Shards[0].Name 169 170 params := clschema.NewSchemaObjectsShardsUpdateParams(). 171 WithBody(&models.ShardStatus{Status: storagestate.StatusReadOnly.String()}). 172 WithClassName(className). 173 WithShardName(targetShard) 174 shardsResp, err := helper.Client(t).Schema.SchemaObjectsShardsUpdate(params, nil) 175 require.Nil(t, err) 176 require.NotNil(t, shardsResp.Payload) 177 require.Equal(t, storagestate.StatusReadOnly.String(), shardsResp.Payload.Status) 178 }) 179 180 t.Run("delete class with readonly shard", func(t *testing.T) { 181 params := clschema.NewSchemaObjectsDeleteParams().WithClassName(className) 182 resp, err := helper.Client(t).Schema.SchemaObjectsDelete(params, nil) 183 require.Nil(t, err) 184 require.True(t, resp.IsCode(http.StatusOK)) 185 }) 186 187 t.Run("assert class is deleted", func(t *testing.T) { 188 params := clschema.NewSchemaObjectsGetParams().WithClassName(className) 189 _, err := helper.Client(t).Schema.SchemaObjectsGet(params, nil) 190 require.Equal(t, err, &clschema.SchemaObjectsGetNotFound{}) 191 }) 192 }