ronantakizawa/codereview-bench huggingface dataset:
Repository: codenotary/immudb
File: embedded/sql/stmt.go (Go)

Code before:
	table, err := tx.catalog.GetTableByName(tableName.RawValue().(string))
	if err != nil {
		return nil, err
	}

	values := make([][]ValueExp, len(table.indexes))

	for i, index := range table.indexes {
		values[i] = []ValueExp{
			&Varchar{val: table.name},
			&Varchar{val: index.Name()},
			&Bool{val: index.unique},
			&Bool{val: index.IsPrimary()},
		}
	}

	return newValuesRowReader(tx, params, cols, stmt.Alias(), values)
}

func NewDeleteTableStmt(table string) *DeleteTableStmt {
	return &DeleteTableStmt{table: table}
}

// DeleteTableStmt represents a statement to delete a table.
type DeleteTableStmt struct {
	table string
}

func (stmt *DeleteTableStmt) inferParameters(ctx context.Context, tx *SQLTx, params map[string]SQLValueType) error {
	return nil
}

/*
	Exec executes the delete table statement.
	It the table exists, if not it does nothing.
	If the table exists, it deletes all the indexes and the table itself.
	Note that this is a soft delete of the index and table key,
	the data is not deleted, but the metadata is updated.
*/
func (stmt *DeleteTableStmt) execAt(ctx context.Context, tx *SQLTx, params map[string]interface{}) (*SQLTx, error) {
	if !tx.catalog.ExistTable(stmt.table) {
		return tx, nil
	}

	table, err := tx.catalog.GetTableByName(stmt.table)
	if err != nil {
		return nil, err
	}

	// metadata for deleted keys
	md := store.NewKVMetadata()

Review comment (suggestion):
`ifExists bool`

By default it may be better to return an error if the table does not exist

Code after:
	table, err := tx.catalog.GetTableByName(tableName.RawValue().(string))
	if err != nil {
		return nil, err
	}

	values := make([][]ValueExp, len(table.indexes))

	for i, index := range table.indexes {
		values[i] = []ValueExp{
			&Varchar{val: table.name},
			&Varchar{val: index.Name()},
			&Bool{val: index.unique},
			&Bool{val: index.IsPrimary()},
		}
	}

	return newValuesRowReader(tx, params, cols, stmt.Alias(), values)
}

func NewDropTableStmt(table string) *DropTableStmt {
	return &DropTableStmt{table: table}
}

// DropTableStmt represents a statement to delete a table.
type DropTableStmt struct {
	table string
}

func (stmt *DropTableStmt) inferParameters(ctx context.Context, tx *SQLTx, params map[string]SQLValueType) error {
	return nil
}

/*
	Exec executes the delete table statement.
	It the table exists, if not it does nothing.
	If the table exists, it deletes all the indexes and the table itself.
	Note that this is a soft delete of the index and table key,
	the data is not deleted, but the metadata is updated.
*/
func (stmt *DropTableStmt) execAt(ctx context.Context, tx *SQLTx, params map[string]interface{}) (*SQLTx, error) {
	if !tx.catalog.ExistTable(stmt.table) {
		return nil, ErrTableDoesNotExist
	}

	table, err := tx.catalog.GetTableByName(stmt.table)
	if err != nil {
		return nil, err
	}

	// delete indexes
	indexes := table.GetIndexes()
Repository: codenotary/immudb
File: embedded/sql/stmt.go (Go)

Code before:
/*
	Exec executes the delete table statement.
	It the table exists, if not it does nothing.
	If the table exists, it deletes all the indexes and the table itself.
	Note that this is a soft delete of the index and table key,
	the data is not deleted, but the metadata is updated.
*/
func (stmt *DeleteTableStmt) execAt(ctx context.Context, tx *SQLTx, params map[string]interface{}) (*SQLTx, error) {
	if !tx.catalog.ExistTable(stmt.table) {
		return tx, nil
	}

	table, err := tx.catalog.GetTableByName(stmt.table)
	if err != nil {
		return nil, err
	}

	// metadata for deleted keys
	md := store.NewKVMetadata()
	md.AsDeleted(true)

	// delete indexes
	indexes := table.GetIndexes()
	for _, index := range indexes {
		mappedKey := mapKey(tx.sqlPrefix(), catalogIndexPrefix, EncodeID(1), EncodeID(table.id), EncodeID(index.id))
		err = tx.set(mappedKey, md, nil)
		if err != nil {
			return nil, err
		}
	}

	// delete table
	mappedKey := mapKey(tx.sqlPrefix(), catalogTablePrefix, EncodeID(1), EncodeID(table.id))
	err = tx.set(mappedKey, md, nil)
	if err != nil {
		return nil, err
	}

	tx.mutatedCatalog = true

	return tx, nil
}


Review comment (refactor):
adding the `delete` method into the sqlTx might simplify the code here:

```
func (sqlTx *SQLTx) delete(key []byte) error {
	return sqlTx.tx.Delete(key)
}
```


Code after:
/*
	Exec executes the delete table statement.
	It the table exists, if not it does nothing.
	If the table exists, it deletes all the indexes and the table itself.
	Note that this is a soft delete of the index and table key,
	the data is not deleted, but the metadata is updated.
*/
func (stmt *DropTableStmt) execAt(ctx context.Context, tx *SQLTx, params map[string]interface{}) (*SQLTx, error) {
	if !tx.catalog.ExistTable(stmt.table) {
		return nil, ErrTableDoesNotExist
	}

	table, err := tx.catalog.GetTableByName(stmt.table)
	if err != nil {
		return nil, err
	}

	// delete indexes
	indexes := table.GetIndexes()
	for _, index := range indexes {
		mappedKey := mapKey(tx.sqlPrefix(), catalogIndexPrefix, EncodeID(1), EncodeID(table.id), EncodeID(index.id))
		err = tx.delete(mappedKey)
		if err != nil {
			return nil, err
		}
	}

	// delete table
	mappedKey := mapKey(tx.sqlPrefix(), catalogTablePrefix, EncodeID(1), EncodeID(table.id))
	err = tx.delete(mappedKey)
	if err != nil {
		return nil, err
	}

	tx.mutatedCatalog = true

	return tx, nil
}
Repository: codenotary/immudb
File: pkg/server/server.go (Go)

Code before:
	if (!user.IsSysAdmin) &&
		(!user.HasPermission(req.Database, auth.PermissionAdmin)) {
		return nil, fmt.Errorf("the database '%s' does not exist or you do not have admin permission on this database", req.Database)
	}

	if req.RetentionPeriod < 0 || (req.RetentionPeriod > 0 && req.RetentionPeriod < store.MinimumRetentionPeriod.Milliseconds()) {
		return nil, fmt.Errorf(
			"%w: invalid retention period for database '%s'. RetentionPeriod should at least '%v' hours",
			ErrIllegalArguments, req.Database, store.MinimumRetentionPeriod)
	}

	s.dbListMutex.Lock()
	defer s.dbListMutex.Unlock()

	db, err := s.dbList.GetByName(req.Database)
	if err != nil {
		return nil, err
	}

	rp := time.Duration(req.RetentionPeriod) * time.Millisecond
	truncator := truncator.NewTruncator(db, rp, 0, s.Logger)
	err = truncator.Truncate(ctx, rp)
	if err != nil {
		return nil, err
	}

	return &schema.TruncateDatabaseResponse{
		Database: req.Database,
	}, nil
}


Review comment (suggestion):
it's better to compare errors using `errors.Is()` e.g. `errors.Is(err, ErrTruncatorDoesNotExist)`, as it tolerates error wrapping 

Code after:
	if (!user.IsSysAdmin) &&
		(!user.HasPermission(req.Database, auth.PermissionAdmin)) {
		return nil, fmt.Errorf("the database '%s' does not exist or you do not have admin permission on this database", req.Database)
	}

	if req.RetentionPeriod < 0 || (req.RetentionPeriod > 0 && req.RetentionPeriod < store.MinimumRetentionPeriod.Milliseconds()) {
		return nil, fmt.Errorf(
			"%w: invalid retention period for database '%s'. RetentionPeriod should at least '%v' hours",
			ErrIllegalArguments, req.Database, store.MinimumRetentionPeriod)
	}

	s.dbListMutex.Lock()
	defer s.dbListMutex.Unlock()

	db, err := s.dbList.GetByName(req.Database)
	if err != nil {
		return nil, err
	}

	rp := time.Duration(req.RetentionPeriod) * time.Millisecond

	// check if truncator already exists for the database
	var t *truncator.Truncator

	t, err = s.getTruncatorFor(db.GetName())
	if err == ErrTruncatorDoesNotExist {
		t = truncator.NewTruncator(db, rp, 0, s.Logger)
	}

	err = t.Truncate(ctx, rp)
	if err != nil {
		return nil, err
	}

	return &schema.TruncateDatabaseResponse{
		Database: req.Database,
	}, nil
}
Repository: codenotary/immudb
File: test/document_storage_tests/documents_tests/actions/insert_documents.go (Go)

Code before:

func InsertOneDocumentWithMultipleFields(expect *httpexpect.Expect, sessionID string, collection *httpexpect.Object, document map[string]interface{}) *httpexpect.Object {
	collectionName := collection.Value("collection").Object().Value("name").String().Raw()

	payload := map[string]interface{}{
		"documents": []interface{}{
			document,
		},
	}

	keys := reflect.ValueOf(document).MapKeys()
	field := keys[1].String()
	value := document[keys[1].String()]

	return insertDocuments(expect, sessionID, collectionName, payload, field, value)
}

func insertDocuments(expect *httpexpect.Expect, sessionID string, collectionName string, payload map[string]interface{}, field string, value interface{}) *httpexpect.Object {
	expect.POST(fmt.Sprintf("/collection/%s/documents", collectionName)).
		WithHeader("grpc-metadata-sessionid", sessionID).
		WithJSON(payload).
		Expect().
		Status(http.StatusOK).JSON().Object().NotEmpty().
		Keys().ContainsOnly("transactionId", "documentIds")

	searchPayload := map[string]interface{}{
		"query": map[string]interface{}{
			"expressions": []interface{}{
				map[string]interface{}{
					"fieldComparisons": []interface{}{
						map[string]interface{}{
							"field":    field,
							"operator": "EQ",
							"value":    value,
						},
					},
				},
			},
		},
		"page":     1,
		"pageSize": 1,
	}

	return SearchDocuments(expect, sessionID, collectionName, searchPayload)
}


Review comment (suggestion):
much cleaner is just to have searchPayload as type struct and then marshal it to map[string]interface{} with json.Marshal. 

Code after:

func InsertOneDocumentWithMultipleFields(expect *httpexpect.Expect, sessionID string, collection *httpexpect.Object) models.Employee {
	collectionName := collection.Value("collection").Object().Value("name").String().Raw()

	document := models.Employee{
		BirthDate: "1964-06-02",
		FirstName: "Bezalel",
		LastName:  "Simmel",
		Gender:    "F",
		HireDate:  "1985-11-21",
	}

	payload := map[string]interface{}{
		"documents": []interface{}{
			document,
		},
	}

	insertDocuments(expect, sessionID, collectionName, payload, "first_name", document.FirstName)

	return document
}

func insertDocuments(expect *httpexpect.Expect, sessionID string, collectionName string, payload map[string]interface{}, field string, value interface{}) {
	expect.POST(fmt.Sprintf("/collection/%s/documents", collectionName)).
		WithHeader("grpc-metadata-sessionid", sessionID).
		WithJSON(payload).
		Expect().
		Status(http.StatusOK).JSON().Object().NotEmpty().
		Keys().ContainsOnly("transactionId", "documentIds")
}
Repository: codenotary/immudb
File: test/document_storage_tests/documents_tests/insert_documents_test.go (Go)

Code before:

type InsertDocumentsTestSuite struct {
	suite.Suite
	expect     *httpexpect.Expect
	sessionID  string
	collection *httpexpect.Object
}

func (s *InsertDocumentsTestSuite) SetupTest() {
	s.expect, s.sessionID = actions.OpenSession(s.T())
	s.collection = actions.CreateCollectionWithNameAndMultipleFields(s.expect, s.sessionID, uuid.New().String())
}

func (s *InsertDocumentsTestSuite) TestInsertOneDocumentWithMultipleFields() {
	document := map[string]interface{}{
		"birth_date": "1964-06-02",
		"first_name": "Bezalel",
		"last_name":  "Simmel",
		"gender":     "F",
		"hire_date":  "1985-11-21",
	}

	documentFound := actions.InsertOneDocumentWithMultipleFields(s.expect, s.sessionID, s.collection, document)

	documentFound.Keys().ContainsOnly("_id", "birth_date", "first_name", "last_name", "gender", "hire_date")
	documentFound.Value("birth_date").IsEqual(document["birth_date"])
	documentFound.Value("first_name").IsEqual(document["first_name"])
	documentFound.Value("last_name").IsEqual(document["last_name"])
	documentFound.Value("gender").IsEqual(document["gender"])
	documentFound.Value("hire_date").IsEqual(document["hire_date"])
}

func TestInsertDocumentsSuite(t *testing.T) {
	suite.Run(t, new(InsertDocumentsTestSuite))
}


Review comment (suggestion):
you should expect also concrete types, now there are just strings

Code after:
	"github.com/stretchr/testify/suite"
)

type InsertDocumentsTestSuite struct {
	suite.Suite
	expect     *httpexpect.Expect
	sessionID  string
	collection *httpexpect.Object
}

func (s *InsertDocumentsTestSuite) SetupTest() {
	s.expect, s.sessionID = actions.OpenSession(s.T())
	s.collection = actions.CreateCollectionWithNameAndMultipleFields(s.expect, s.sessionID, uuid.New().String())
}

func (s *InsertDocumentsTestSuite) TestInsertOneDocumentWithMultipleFields() {
	documentModel := actions.InsertOneDocumentWithMultipleFields(s.expect, s.sessionID, s.collection)

	fieldComparison := models.FieldComparison{}
	fieldComparison.Field = "first_name"
	fieldComparison.Operator = "EQ"
	fieldComparison.Value = documentModel.FirstName
	documentFound := actions.SearchDocuments(s.expect, s.sessionID, s.collection, fieldComparison)

	documentFound.Keys().ContainsOnly("_id", "birth_date", "first_name", "last_name", "gender", "hire_date")

	var employee models.Employee

	documentFound.Decode(&employee)

	assert.Equal(s.T(), employee.BirthDate, "1964-06-02")
	assert.Equal(s.T(), employee.FirstName, "Bezalel")
	assert.Equal(s.T(), employee.LastName, "Simmel")
	assert.Equal(s.T(), employee.Gender, "F")
	assert.Equal(s.T(), employee.HireDate, "1985-11-21")
}

func TestInsertDocumentsSuite(t *testing.T) {
	suite.Run(t, new(InsertDocumentsTestSuite))
}
Repository: codenotary/immudb
File: pkg/server/remote_storage.go (Go)

Code before:
		// No remote storage
		return nil
	}

	ctx := context.Background()

	hasRemoteIdentifier, err := storage.Exists(ctx, IDENTIFIER_FNAME)
	if err != nil {
		return err
	}

	localIdentifierFile := filepath.Join(s.Options.Dir, IDENTIFIER_FNAME)

	if hasRemoteIdentifier {

		remoteIdStream, err := storage.Get(ctx, IDENTIFIER_FNAME, 0, -1)
		if err != nil {
			return err
		}
		remoteId, err := ioutil.ReadAll(remoteIdStream)
		remoteIdStream.Close()
		if err != nil {
			return err
		}

		if !fileExists(localIdentifierFile) || s.Options.RemoteStorageOptions.S3ExternalIdentifier {
			err := ioutil.WriteFile(localIdentifierFile, remoteId, os.ModePerm)
			if err != nil {
				return err
			}
		} else {
			localId, err := ioutil.ReadFile(localIdentifierFile)
			if err != nil {
				return err
			}

			if !bytes.Equal(remoteId, localId) {
				return ErrRemoteStorageDoesNotMatch
			}
		}
	}

	// Ensure all sub-folders are created, init code relies on this
	_, subFolders, err := storage.ListEntries(context.Background(), "")
	if err != nil {
		return err
	}
	for _, subFolder := range subFolders {
		err := os.MkdirAll(
			filepath.Join(s.Options.Dir, subFolder),
			store.DefaultFileMode,

Review comment (suggestion):
it may be problematic to overwrite an existent local identifier

it may be better to raise an error if the local identifier (if any) differs from the remote one

I'd suggest to extend the method `getOrSetUUID` in server.go file before initializing the remote storage with a parameter `createIfNotExists`, and set its value in the call with the value of  `!s.Options.RemoteStorageOptions.S3ExternalIdentifier` ...

Code after:
	return nil, nil
}

func (s *ImmuServer) initializeRemoteStorage(storage remotestorage.Storage) error {
	if storage == nil {
		if s.Options.RemoteStorageOptions.S3ExternalIdentifier {
			return ErrNoStorageForIdentifier
		}
		// No remote storage
		return nil
	}

	ctx := context.Background()

	hasRemoteIdentifier, err := storage.Exists(ctx, IDENTIFIER_FNAME)
	if err != nil {
		return err
	}

	if !hasRemoteIdentifier && s.Options.RemoteStorageOptions.S3ExternalIdentifier {
		return ErrNoRemoteIdentifier
	}

	localIdentifierFile := filepath.Join(s.Options.Dir, IDENTIFIER_FNAME)

	if hasRemoteIdentifier {
		remoteIDStream, err := storage.Get(ctx, IDENTIFIER_FNAME, 0, -1)
		if err != nil {
			return err
		}
		remoteID, err := ioutil.ReadAll(remoteIDStream)
		remoteIDStream.Close()
		if err != nil {
			return err
		}

		if !fileExists(localIdentifierFile) {
			err := ioutil.WriteFile(localIdentifierFile, remoteID, os.ModePerm)
			if err != nil {
				return err
			}
			s.UUID, err = xid.FromBytes(remoteID)
		} else {
			localID, err := ioutil.ReadFile(localIdentifierFile)
			if err != nil {
				return err
			}

			if !bytes.Equal(remoteID, localID) {
				return ErrRemoteStorageDoesNotMatch
			}
Repository: codenotary/immudb
File: pkg/server/remote_storage.go (Go)

Code before:

	if !hasRemoteIdentifier && s.Options.RemoteStorageOptions.S3ExternalIdentifier {
		return ErrNoRemoteIdentifier
	}

	localIdentifierFile := filepath.Join(s.Options.Dir, IDENTIFIER_FNAME)

	if hasRemoteIdentifier {
		remoteIDStream, err := storage.Get(ctx, IDENTIFIER_FNAME, 0, -1)
		if err != nil {
			return err
		}
		remoteID, err := ioutil.ReadAll(remoteIDStream)
		remoteIDStream.Close()
		if err != nil {
			return err
		}

		if !fileExists(localIdentifierFile) {
			err := ioutil.WriteFile(localIdentifierFile, remoteID, os.ModePerm)
			if err != nil {
				return err
			}
			s.UUID, err = xid.FromBytes(remoteID)
		} else {
			if s.Options.RemoteStorageOptions.S3ExternalIdentifier {
				return ErrUnexpectedLocalIdentifier
			}

			localID, err := ioutil.ReadFile(localIdentifierFile)
			if err != nil {
				return err
			}

			if !bytes.Equal(remoteID, localID) {
				return ErrRemoteStorageDoesNotMatch
			}
		}
	}

	// Ensure all sub-folders are created, init code relies on this
	_, subFolders, err := storage.ListEntries(context.Background(), "")
	if err != nil {
		return err
	}
	for _, subFolder := range subFolders {
		err := os.MkdirAll(
			filepath.Join(s.Options.Dir, subFolder),
			store.DefaultFileMode,
		)
		if err != nil {

Review comment (suggestion):
it should be fine if the local file exists as long as the uuid match, so this validation could be removed

Code after:
	if !hasRemoteIdentifier && s.Options.RemoteStorageOptions.S3ExternalIdentifier {
		return ErrNoRemoteIdentifier
	}

	localIdentifierFile := filepath.Join(s.Options.Dir, IDENTIFIER_FNAME)

	if hasRemoteIdentifier {
		remoteIDStream, err := storage.Get(ctx, IDENTIFIER_FNAME, 0, -1)
		if err != nil {
			return err
		}
		remoteID, err := ioutil.ReadAll(remoteIDStream)
		remoteIDStream.Close()
		if err != nil {
			return err
		}

		if !fileExists(localIdentifierFile) {
			err := ioutil.WriteFile(localIdentifierFile, remoteID, os.ModePerm)
			if err != nil {
				return err
			}
			s.UUID, err = xid.FromBytes(remoteID)
		} else {
			localID, err := ioutil.ReadFile(localIdentifierFile)
			if err != nil {
				return err
			}

			if !bytes.Equal(remoteID, localID) {
				return ErrRemoteStorageDoesNotMatch
			}
		}
	}

	// Ensure all sub-folders are created, init code relies on this
	_, subFolders, err := storage.ListEntries(context.Background(), "")
	if err != nil {
		return err
	}
	for _, subFolder := range subFolders {
		err := os.MkdirAll(
			filepath.Join(s.Options.Dir, subFolder),
			store.DefaultFileMode,
		)
		if err != nil {
			return err
		}
	}

	return nil
Repository: codenotary/immudb
File: pkg/server/remote_storage_test.go (Go)

Code before:
	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	err := s.Initialize()
	require.Error(t, ErrNoStorageForIdentifier, err)
}

func TestInitializeWithRemoteStorageWithoutIdentifier(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	m := memory.Open()
	s.remoteStorage = m

	err := s.initializeRemoteStorage(m)
	require.Error(t, ErrNoRemoteIdentifier, err)
}

func TestInitializeRemoteStorageWithIdentifierWhenLocalIsPresent(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	m := memory.Open()
	storeData(t, m, "immudb.identifier", []byte{1, 2, 3, 4, 5})

	_, err := getOrSetUUID(dir, dir, false)
	require.NoError(t, err)

	err = s.initializeRemoteStorage(m)
	require.ErrorIs(t, err, ErrUnexpectedLocalIdentifier)
}

func TestInitializeRemoteStorageWithoutLocalIdentifier(t *testing.T) {
	dir := t.TempDir()


Review comment (suggestion):
`require.ErrorIs(t, err, ErrNoStorageForIdentifier) ?`

Code after:
	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	err := s.Initialize()
	require.ErrorIs(t, err, ErrNoStorageForIdentifier)
}

func TestInitializeWithRemoteStorageWithoutIdentifier(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	m := memory.Open()
	s.remoteStorage = m

	err := s.initializeRemoteStorage(m)
	require.ErrorIs(t, err, ErrNoStorageForIdentifier)
}

func TestInitializeRemoteStorageWithoutLocalIdentifier(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	m := memory.Open()
	storeData(t, m, "immudb.identifier", []byte{1, 2, 3, 4, 5})
	s.remoteStorage = m

	err := s.initializeRemoteStorage(m)
	require.NoError(t, err)

	uuidFilename := filepath.Join(dir, "immudb.identifier")

	require.FileExists(t, uuidFilename)

	id, err := ioutil.ReadFile(uuidFilename)
	require.NoError(t, err)
Repository: codenotary/immudb
File: pkg/server/remote_storage_test.go (Go)

Code before:
	storeData(t, m, "immudb.identifier", []byte{1, 2, 3, 4, 5})

	err := s.initializeRemoteStorage(m)
	require.NoError(t, err)

	uuidFilename := filepath.Join(dir, "immudb.identifier")

	require.FileExists(t, uuidFilename)

	id, err := ioutil.ReadFile(uuidFilename)
	require.NoError(t, err)
	require.Equal(t, []byte{1, 2, 3, 4, 5}, id)
}

func TestInitializeWithEmptyRemoteStorage(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	err := s.Initialize()
	require.Error(t, ErrNoStorageForIdentifier, err)
}

func TestInitializeWithRemoteStorageWithoutIdentifier(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	m := memory.Open()
	s.remoteStorage = m

	err := s.initializeRemoteStorage(m)
	require.Error(t, ErrNoRemoteIdentifier, err)
}

func TestInitializeRemoteStorageWithIdentifierWhenLocalIsPresent(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true


Review comment (suggestion):
```suggestion
	require.ErrorIs(t, err, ErrNoStorageForIdentifier)
```

Code after:
	storeData(t, m, "immudb.identifier", []byte{1, 2, 3, 4, 5})

	err := s.initializeRemoteStorage(m)
	require.NoError(t, err)

	uuidFilename := filepath.Join(dir, "immudb.identifier")

	require.FileExists(t, uuidFilename)

	id, err := ioutil.ReadFile(uuidFilename)
	require.NoError(t, err)
	require.Equal(t, []byte{1, 2, 3, 4, 5}, id)
}

func TestInitializeWithEmptyRemoteStorage(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	err := s.Initialize()
	require.ErrorIs(t, err, ErrNoStorageForIdentifier)
}

func TestInitializeWithRemoteStorageWithoutIdentifier(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true

	s := DefaultServer()

	s.WithOptions(opts)

	m := memory.Open()
	s.remoteStorage = m

	err := s.initializeRemoteStorage(m)
	require.ErrorIs(t, err, ErrNoStorageForIdentifier)
}

func TestInitializeRemoteStorageWithoutLocalIdentifier(t *testing.T) {
	dir := t.TempDir()

	opts := DefaultOptions().WithDir(dir)
	opts.RemoteStorageOptions.S3ExternalIdentifier = true