github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/crud_deletion_integration_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  //go:build integrationTest
    13  // +build integrationTest
    14  
    15  package db
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"github.com/sirupsen/logrus"
    22  	"github.com/stretchr/testify/assert"
    23  	"github.com/stretchr/testify/require"
    24  	"github.com/weaviate/weaviate/entities/additional"
    25  	"github.com/weaviate/weaviate/entities/dto"
    26  	"github.com/weaviate/weaviate/entities/filters"
    27  	"github.com/weaviate/weaviate/entities/models"
    28  	"github.com/weaviate/weaviate/entities/schema"
    29  	libschema "github.com/weaviate/weaviate/entities/schema"
    30  )
    31  
    32  func TestDeleteJourney(t *testing.T) {
    33  	dirName := t.TempDir()
    34  
    35  	logger := logrus.New()
    36  	schemaGetter := &fakeSchemaGetter{
    37  		schema:     schema.Schema{Objects: &models.Schema{Classes: nil}},
    38  		shardState: singleShardState(),
    39  	}
    40  	repo, err := New(logger, Config{
    41  		MemtablesFlushDirtyAfter:  60,
    42  		RootPath:                  dirName,
    43  		QueryMaximumResults:       10000,
    44  		MaxImportGoroutinesFactor: 1,
    45  	}, &fakeRemoteClient{}, &fakeNodeResolver{}, &fakeRemoteNodeClient{}, &fakeReplicationClient{}, nil)
    46  	require.Nil(t, err)
    47  	repo.SetSchemaGetter(schemaGetter)
    48  	require.Nil(t, repo.WaitForStartup(testCtx()))
    49  	defer repo.Shutdown(context.Background())
    50  	migrator := NewMigrator(repo, logger)
    51  
    52  	schema := libschema.Schema{
    53  		Objects: &models.Schema{
    54  			Classes: []*models.Class{updateTestClass()},
    55  		},
    56  	}
    57  
    58  	t.Run("add schema", func(t *testing.T) {
    59  		err := migrator.AddClass(context.Background(), updateTestClass(),
    60  			schemaGetter.CopyShardingState(updateTestClass().Class))
    61  		require.Nil(t, err)
    62  	})
    63  	schemaGetter.schema = schema
    64  
    65  	t.Run("import some objects", func(t *testing.T) {
    66  		for _, res := range updateTestData() {
    67  			err := repo.PutObject(context.Background(), res.Object(), res.Vector, nil, nil)
    68  			require.Nil(t, err)
    69  		}
    70  	})
    71  
    72  	searchVector := []float32{0.1, 0.1, 0.1}
    73  
    74  	t.Run("verify vector search results are initially as expected",
    75  		func(t *testing.T) {
    76  			res, err := repo.VectorSearch(context.Background(), dto.GetParams{
    77  				ClassName:    "UpdateTestClass",
    78  				SearchVector: searchVector,
    79  				Pagination: &filters.Pagination{
    80  					Limit: 100,
    81  				},
    82  			})
    83  
    84  			expectedOrder := []interface{}{
    85  				"element-0", "element-2", "element-3", "element-1",
    86  			}
    87  
    88  			require.Nil(t, err)
    89  			require.Len(t, res, 4)
    90  			assert.Equal(t, expectedOrder, extractPropValues(res, "name"))
    91  		})
    92  
    93  	searchInv := func(t *testing.T, op filters.Operator, value int) []interface{} {
    94  		res, err := repo.ObjectSearch(context.Background(), 0, 100,
    95  			&filters.LocalFilter{
    96  				Root: &filters.Clause{
    97  					Operator: op,
    98  					On: &filters.Path{
    99  						Class:    "UpdateTestClass",
   100  						Property: libschema.PropertyName("intProp"),
   101  					},
   102  					Value: &filters.Value{
   103  						Type:  libschema.DataTypeInt,
   104  						Value: value,
   105  					},
   106  				},
   107  			}, nil, additional.Properties{}, "")
   108  		require.Nil(t, err)
   109  		return extractPropValues(res, "name")
   110  	}
   111  
   112  	t.Run("verify invert index results are initially as expected",
   113  		func(t *testing.T) {
   114  			expectedOrder := []interface{}{
   115  				"element-0", "element-1", "element-2", "element-3",
   116  			}
   117  			assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorGreaterThanEqual, 0))
   118  
   119  			expectedOrder = []interface{}{"element-0"}
   120  			assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorEqual, 0))
   121  
   122  			expectedOrder = []interface{}{"element-1"}
   123  			assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorEqual, 10))
   124  
   125  			expectedOrder = []interface{}{"element-2"}
   126  			assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorEqual, 20))
   127  
   128  			expectedOrder = []interface{}{"element-3"}
   129  			assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorEqual, 30))
   130  		})
   131  
   132  	t.Run("delete element-0",
   133  		func(t *testing.T) {
   134  			id := updateTestData()[0].ID
   135  
   136  			err := repo.DeleteObject(context.Background(), "UpdateTestClass", id, nil, "")
   137  			require.Nil(t, err)
   138  		})
   139  
   140  	t.Run("verify new vector search results are as expected", func(t *testing.T) {
   141  		res, err := repo.VectorSearch(context.Background(), dto.GetParams{
   142  			ClassName:    "UpdateTestClass",
   143  			SearchVector: searchVector,
   144  			Pagination: &filters.Pagination{
   145  				Limit: 100,
   146  			},
   147  		})
   148  
   149  		expectedOrder := []interface{}{
   150  			"element-2", "element-3", "element-1",
   151  		}
   152  
   153  		require.Nil(t, err)
   154  		require.Len(t, res, 3)
   155  		assert.Equal(t, expectedOrder, extractPropValues(res, "name"))
   156  	})
   157  
   158  	t.Run("verify invert results still work properly", func(t *testing.T) {
   159  		expectedOrder := []interface{}{
   160  			"element-1", "element-2", "element-3",
   161  		}
   162  		assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorGreaterThanEqual, 0))
   163  
   164  		expectedOrder = []interface{}{"element-1"}
   165  		assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorEqual, 10))
   166  
   167  		expectedOrder = []interface{}{"element-2"}
   168  		assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorEqual, 20))
   169  
   170  		expectedOrder = []interface{}{"element-3"}
   171  		assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorEqual, 30))
   172  	})
   173  
   174  	t.Run("delete element-1",
   175  		func(t *testing.T) {
   176  			id := updateTestData()[1].ID
   177  
   178  			err := repo.DeleteObject(context.Background(), "UpdateTestClass", id, nil, "")
   179  			require.Nil(t, err)
   180  		})
   181  
   182  	t.Run("verify new vector search results are as expected", func(t *testing.T) {
   183  		res, err := repo.VectorSearch(context.Background(), dto.GetParams{
   184  			ClassName:    "UpdateTestClass",
   185  			SearchVector: searchVector,
   186  			Pagination: &filters.Pagination{
   187  				Limit: 100,
   188  			},
   189  		})
   190  
   191  		expectedOrder := []interface{}{
   192  			"element-2", "element-3",
   193  		}
   194  
   195  		require.Nil(t, err)
   196  		require.Len(t, res, 2)
   197  		assert.Equal(t, expectedOrder, extractPropValues(res, "name"))
   198  	})
   199  
   200  	t.Run("verify invert results have been updated correctly", func(t *testing.T) {
   201  		expectedOrder := []interface{}{
   202  			"element-2", "element-3",
   203  		}
   204  		assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorGreaterThanEqual, 0))
   205  
   206  		expectedOrder = []interface{}{"element-2"}
   207  		assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorEqual, 20))
   208  
   209  		expectedOrder = []interface{}{"element-3"}
   210  		assert.Equal(t, expectedOrder, searchInv(t, filters.OperatorEqual, 30))
   211  	})
   212  
   213  	t.Run("delete the index", func(t *testing.T) {
   214  		res, err := repo.VectorSearch(context.Background(), dto.GetParams{
   215  			ClassName:    "UpdateTestClass",
   216  			SearchVector: searchVector,
   217  			Pagination: &filters.Pagination{
   218  				Limit: 100,
   219  			},
   220  		})
   221  
   222  		expectedOrder := []interface{}{
   223  			"element-2", "element-3",
   224  		}
   225  
   226  		require.Nil(t, err)
   227  		require.Len(t, res, 2)
   228  		assert.Equal(t, expectedOrder, extractPropValues(res, "name"))
   229  
   230  		id := updateTestData()[2].ID
   231  
   232  		err = repo.DeleteObject(context.Background(), "UpdateTestClass", id, nil, "")
   233  		require.Nil(t, err)
   234  
   235  		index := repo.GetIndex("UpdateTestClass")
   236  		require.NotNil(t, index)
   237  
   238  		err = repo.DeleteIndex("UpdateTestClass")
   239  		assert.Nil(t, err)
   240  	})
   241  }