github.com/weaviate/weaviate@v1.24.6/adapters/repos/db/nodes_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/models"
    25  	"github.com/weaviate/weaviate/entities/schema"
    26  	enthnsw "github.com/weaviate/weaviate/entities/vectorindex/hnsw"
    27  	"github.com/weaviate/weaviate/entities/verbosity"
    28  	"github.com/weaviate/weaviate/usecases/objects"
    29  )
    30  
    31  func TestNodesAPI_Journey(t *testing.T) {
    32  	dirName := t.TempDir()
    33  
    34  	logger := logrus.New()
    35  	schemaGetter := &fakeSchemaGetter{
    36  		schema:     schema.Schema{Objects: &models.Schema{Classes: nil}},
    37  		shardState: singleShardState(),
    38  	}
    39  	repo, err := New(logger, Config{
    40  		ServerVersion:             "server-version",
    41  		GitHash:                   "git-hash",
    42  		MemtablesFlushDirtyAfter:  60,
    43  		RootPath:                  dirName,
    44  		QueryMaximumResults:       10000,
    45  		MaxImportGoroutinesFactor: 1,
    46  		TrackVectorDimensions:     true,
    47  	}, &fakeRemoteClient{}, &fakeNodeResolver{}, &fakeRemoteNodeClient{}, &fakeReplicationClient{}, nil)
    48  	require.Nil(t, err)
    49  	repo.SetSchemaGetter(schemaGetter)
    50  	require.Nil(t, repo.WaitForStartup(testCtx()))
    51  
    52  	defer repo.Shutdown(context.Background())
    53  	migrator := NewMigrator(repo, logger)
    54  
    55  	// check nodes api response on empty DB
    56  	nodeStatues, err := repo.GetNodeStatus(context.Background(), "", verbosity.OutputVerbose)
    57  	require.Nil(t, err)
    58  	require.NotNil(t, nodeStatues)
    59  
    60  	require.Len(t, nodeStatues, 1)
    61  	nodeStatus := nodeStatues[0]
    62  	assert.NotNil(t, nodeStatus)
    63  	assert.Equal(t, "node1", nodeStatus.Name)
    64  	assert.Equal(t, "server-version", nodeStatus.Version)
    65  	assert.Equal(t, "git-hash", nodeStatus.GitHash)
    66  	assert.Len(t, nodeStatus.Shards, 0)
    67  	assert.Equal(t, int64(0), nodeStatus.Stats.ObjectCount)
    68  	assert.Equal(t, int64(0), nodeStatus.Stats.ShardCount)
    69  
    70  	// import 2 objects
    71  	class := &models.Class{
    72  		Class:               "ClassNodesAPI",
    73  		VectorIndexConfig:   enthnsw.NewDefaultUserConfig(),
    74  		InvertedIndexConfig: invertedConfig(),
    75  		Properties: []*models.Property{
    76  			{
    77  				Name:         "stringProp",
    78  				DataType:     schema.DataTypeText.PropString(),
    79  				Tokenization: models.PropertyTokenizationWhitespace,
    80  			},
    81  		},
    82  	}
    83  
    84  	require.Nil(t,
    85  		migrator.AddClass(context.Background(), class, schemaGetter.shardState))
    86  
    87  	schemaGetter.schema.Objects = &models.Schema{
    88  		Classes: []*models.Class{class},
    89  	}
    90  
    91  	batch := objects.BatchObjects{
    92  		objects.BatchObject{
    93  			OriginalIndex: 0,
    94  			Err:           nil,
    95  			Object: &models.Object{
    96  				Class: "ClassNodesAPI",
    97  				Properties: map[string]interface{}{
    98  					"stringProp": "first element",
    99  				},
   100  				ID: "8d5a3aa2-3c8d-4589-9ae1-3f638f506970",
   101  			},
   102  			UUID: "8d5a3aa2-3c8d-4589-9ae1-3f638f506970",
   103  		},
   104  		objects.BatchObject{
   105  			OriginalIndex: 1,
   106  			Err:           nil,
   107  			Object: &models.Object{
   108  				Class: "ClassNodesAPI",
   109  				Properties: map[string]interface{}{
   110  					"stringProp": "second element",
   111  				},
   112  				ID: "86a380e9-cb60-4b2a-bc48-51f52acd72d6",
   113  			},
   114  			UUID: "86a380e9-cb60-4b2a-bc48-51f52acd72d6",
   115  		},
   116  	}
   117  	batchRes, err := repo.BatchPutObjects(context.Background(), batch, nil)
   118  	require.Nil(t, err)
   119  
   120  	assert.Nil(t, batchRes[0].Err)
   121  	assert.Nil(t, batchRes[1].Err)
   122  
   123  	// check nodes api after importing 2 objects to DB
   124  	nodeStatues, err = repo.GetNodeStatus(context.Background(), "", verbosity.OutputVerbose)
   125  	require.Nil(t, err)
   126  	require.NotNil(t, nodeStatues)
   127  
   128  	require.Len(t, nodeStatues, 1)
   129  	nodeStatus = nodeStatues[0]
   130  	assert.NotNil(t, nodeStatus)
   131  	assert.Equal(t, "node1", nodeStatus.Name)
   132  	assert.Equal(t, "server-version", nodeStatus.Version)
   133  	assert.Equal(t, "git-hash", nodeStatus.GitHash)
   134  	assert.Len(t, nodeStatus.Shards, 1)
   135  	assert.Equal(t, "ClassNodesAPI", nodeStatus.Shards[0].Class)
   136  	assert.True(t, len(nodeStatus.Shards[0].Name) > 0)
   137  	// a previous version of this test made assertions on object counts,
   138  	// however with object count becoming async, we can no longer make exact
   139  	// assertions here. See https://github.com/weaviate/weaviate/issues/4193
   140  	// for details.
   141  	assert.Equal(t, "READY", nodeStatus.Shards[0].VectorIndexingStatus)
   142  	assert.Equal(t, int64(0), nodeStatus.Shards[0].VectorQueueLength)
   143  	assert.Equal(t, int64(1), nodeStatus.Stats.ShardCount)
   144  }