Repository: milvus-io/milvus-sdk-go
Pull request #576 (2023-09-05 16:10:36)

Use DescribeCollection for HasCollection impl
See also #575 
/kind improvement

sre-ci-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/milvus-io/milvus-sdk-go/pull/576#" title="Author self-approved">congqixia</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=milvus-io%2Fmilvus-sdk-go).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/milvus-io/milvus-sdk-go/blob/v2.2.x/OWNERS)~~ [congqixia]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
codecov[bot]: ## [Codecov](https://app.codecov.io/gh/milvus-io/milvus-sdk-go/pull/576?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=milvus-io) Report
> Merging [#576](https://app.codecov.io/gh/milvus-io/milvus-sdk-go/pull/576?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=milvus-io) (32d50d0) into [v2.2.x](https://app.codecov.io/gh/milvus-io/milvus-sdk-go/commit/8e265cf31751d39817d88e2214ef0dcf9e3758f1?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=milvus-io) (8e265cf) will **decrease** coverage by `0.06%`.
> The diff coverage is `66.66%`.

[![Impacted file tree graph](https://app.codecov.io/gh/milvus-io/milvus-sdk-go/pull/576/graphs/tree.svg?width=650&height=150&src=pr&token=WJK43PV390&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=milvus-io)](https://app.codecov.io/gh/milvus-io/milvus-sdk-go/pull/576?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=milvus-io)

```diff
@@            Coverage Diff             @@
##           v2.2.x     #576      +/-   ##
==========================================
- Coverage   80.15%   80.09%   -0.06%     
==========================================
  Files          36       36              
  Lines        2847     2849       +2     
==========================================
  Hits         2282     2282              
- Misses        454      455       +1     
- Partials      111      112       +1     
```


| [Files Changed](https://app.codecov.io/gh/milvus-io/milvus-sdk-go/pull/576?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=milvus-io) | Coverage Δ | |
|---|---|---|
| [entity/schema.go](https://app.codecov.io/gh/milvus-io/milvus-sdk-go/pull/576?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=milvus-io#diff-ZW50aXR5L3NjaGVtYS5nbw==) | `90.44% <0.00%> (-1.03%)` | :arrow_down: |
| [client/collection.go](https://app.codecov.io/gh/milvus-io/milvus-sdk-go/pull/576?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=milvus-io#diff-Y2xpZW50L2NvbGxlY3Rpb24uZ28=) | `89.18% <100.00%> (+2.40%)` | :arrow_up: |

... and [3 files with indirect coverage changes](https://app.codecov.io/gh/milvus-io/milvus-sdk-go/pull/576/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=milvus-io)

weiliu1031: /lgtm

Patch:
diff --git a/client/collection.go b/client/collection.go
index 0b896e3..3459885 100644
--- a/client/collection.go
+++ b/client/collection.go
@@ -14,6 +14,7 @@ package client
 import (
 	"context"
 	"fmt"
+	"strings"
 	"time"
 
 	"github.com/cockroachdb/errors"
@@ -332,20 +333,31 @@ func (c *GrpcClient) HasCollection(ctx context.Context, collName string) (bool,
 		return false, ErrClientNotReady
 	}
 
-	req := &server.HasCollectionRequest{
+	req := &server.DescribeCollectionRequest{
 		DbName:         "", // reserved
 		CollectionName: collName,
 		TimeStamp:      0, // 0 for now
 	}
 
-	resp, err := c.Service.HasCollection(ctx, req)
+	resp, err := c.Service.DescribeCollection(ctx, req)
 	if err != nil {
 		return false, err
 	}
+
+	if resp.GetStatus().GetErrorCode() == common.ErrorCode_CollectionNotExists {
+		return false, nil
+	}
+	// backward compatibility
+	if resp.GetStatus().GetErrorCode() == common.ErrorCode_UnexpectedError {
+		if strings.Contains(resp.GetStatus().GetReason(), "can't find collection") {
+			return false, nil
+		}
+	}
 	if err := handleRespStatus(resp.GetStatus()); err != nil {
 		return false, err
 	}
-	return resp.GetValue(), nil
+
+	return true, nil
 }
 
 // GetCollectionStatistcis show collection statistics
diff --git a/entity/schema.go b/entity/schema.go
index ae094fc..12edff9 100644
--- a/entity/schema.go
+++ b/entity/schema.go
@@ -89,6 +89,9 @@ func (s *Schema) WithField(f *Field) *Schema {
 
 // ProtoMessage returns corresponding server.CollectionSchema
 func (s *Schema) ProtoMessage() *schema.CollectionSchema {
+	if s == nil {
+		return nil
+	}
 	r := &schema.CollectionSchema{
 		Name:               s.CollectionName,
 		Description:        s.Description,


Test patch:
diff --git a/client/client_mock_test.go b/client/client_mock_test.go
index 0e1954a..d9722d4 100644
--- a/client/client_mock_test.go
+++ b/client/client_mock_test.go
@@ -76,6 +76,7 @@ func (s *MockSuiteBase) TearDownTest() {
 }
 
 func (s *MockSuiteBase) resetMock() {
+	s.mock.AssertExpectations(s.T())
 	MetaCache.reset()
 	if s.mock != nil {
 		s.mock.Calls = nil
@@ -134,14 +135,33 @@ func (s *MockSuiteBase) setupDescribeCollection(_ string, schema *entity.Schema)
 			Status: &common.Status{ErrorCode: common.ErrorCode_Success},
 			Schema: schema.ProtoMessage(),
 		}
-	}, nil)
+	}, nil).Maybe()
 }
 
 func (s *MockSuiteBase) setupDescribeCollectionError(errorCode common.ErrorCode, err error) {
 	s.mock.EXPECT().DescribeCollection(mock.Anything, mock.AnythingOfType("*milvuspb.DescribeCollectionRequest")).
 		Return(&server.DescribeCollectionResponse{
 			Status: &common.Status{ErrorCode: errorCode},
-		}, err)
+		}, err).Maybe()
+}
+
+func (s *MockSuiteBase) setupShowCollection(collectionName string) {
+	s.setupDescribeCollection(testCollectionName, nil)
+	s.mock.EXPECT().ShowCollections(mock.Anything, mock.Anything).
+		Return(&server.ShowCollectionsResponse{
+			Status:              &common.Status{ErrorCode: common.ErrorCode_Success},
+			CollectionNames:     []string{collectionName},
+			CollectionIds:       []int64{testCollectionID},
+			InMemoryPercentages: []int64{100},
+		}, nil).Maybe()
+}
+
+func (s *MockSuiteBase) setupShowCollectionError(errorCode common.ErrorCode, err error) {
+	s.setupDescribeCollection(testCollectionName, nil)
+	s.mock.EXPECT().ShowCollections(mock.Anything, mock.Anything).
+		Return(&server.ShowCollectionsResponse{
+			Status: &common.Status{ErrorCode: errorCode},
+		}, err).Maybe()
 }
 
 func (s *MockSuiteBase) getInt64FieldData(name string, data []int64) *schema.FieldData {
diff --git a/client/collection_test.go b/client/collection_test.go
index f97222a..91dddff 100644
--- a/client/collection_test.go
+++ b/client/collection_test.go
@@ -33,103 +33,9 @@ var hasCollectionDefault = func(_ context.Context, raw proto.Message) (proto.Mes
 	return resp, err
 }
 
-func TestGrpcClientDropCollection(t *testing.T) {
-	ctx := context.Background()
-	c := testClient(ctx, t)
-
-	mockServer.SetInjection(MHasCollection, hasCollectionDefault)
-	mockServer.SetInjection(MDropCollection, func(_ context.Context, raw proto.Message) (proto.Message, error) {
-		req, ok := (raw).(*server.DropCollectionRequest)
-		if !ok {
-			return BadRequestStatus()
-		}
-		if req.GetCollectionName() != testCollectionName { // in mock server, assume testCollection exists only
-			return BadRequestStatus()
-		}
-		return SuccessStatus()
-	})
-
-	t.Run("Test Normal drop", func(t *testing.T) {
-		assert.Nil(t, c.DropCollection(ctx, testCollectionName))
-	})
-
-	t.Run("Test drop non-existing collection", func(t *testing.T) {
-		assert.NotNil(t, c.DropCollection(ctx, "AAAAAAAAAANonExists"))
-	})
-}
-
-func TestReleaseCollection(t *testing.T) {
-	ctx := context.Background()
-
-	c := testClient(ctx, t)
-
-	mockServer.SetInjection(MReleaseCollection, func(_ context.Context, raw proto.Message) (proto.Message, error) {
-		req, ok := raw.(*server.ReleaseCollectionRequest)
-		if !ok {
-			return BadRequestStatus()
-		}
-		assert.Equal(t, testCollectionName, req.GetCollectionName())
-		return SuccessStatus()
-	})
-
-	c.ReleaseCollection(ctx, testCollectionName)
-}
-
-func TestGrpcClientHasCollection(t *testing.T) {
-	ctx := context.Background()
-
-	c := testClient(ctx, t)
-
-	mockServer.SetInjection(MHasCollection, func(_ context.Context, raw proto.Message) (proto.Message, error) {
-		req, ok := raw.(*server.HasCollectionRequest)
-		resp := &server.BoolResponse{}
-		if !ok {
-			s, err := BadRequestStatus()
-			assert.Fail(t, err.Error())
-			resp.Status = s
-			return resp, err
-		}
-		assert.Equal(t, req.CollectionName, testCollectionName)
-
-		s, err := SuccessStatus()
-		resp.Status, resp.Value = s, true
-		return resp, err
-	})
-
-	has, err := c.HasCollection(ctx, testCollectionName)
-	assert.Nil(t, err)
-	assert.True(t, has)
-}
-
-// return injection asserts collection name matchs
-// partition name request in partitionNames if flag is true
-func hasCollectionInjection(t *testing.T, mustIn bool, collNames ...string) func(context.Context, proto.Message) (proto.Message, error) {
-	return func(_ context.Context, raw proto.Message) (proto.Message, error) {
-		req, ok := raw.(*server.HasCollectionRequest)
-		resp := &server.BoolResponse{}
-		if !ok {
-			s, err := BadRequestStatus()
-			resp.Status = s
-			return resp, err
-		}
-		if mustIn {
-			resp.Value = assert.Contains(t, collNames, req.GetCollectionName())
-		} else {
-			for _, pn := range collNames {
-				if pn == req.GetCollectionName() {
-					resp.Value = true
-				}
-			}
-		}
-		s, err := SuccessStatus()
-		resp.Status = s
-		return resp, err
-	}
-}
-
-func describeCollectionInjection(t *testing.T, collID int64, collName string, sch *entity.Schema) func(_ context.Context, raw proto.Message) (proto.Message, error) {
+func describeCollectionInjection(_ *testing.T, collID int64, collName string, sch *entity.Schema) func(_ context.Context, raw proto.Message) (proto.Message, error) {
 	return func(_ context.Context, raw proto.Message) (proto.Message, error) {
-		req, ok := raw.(*server.DescribeCollectionRequest)
+		_, ok := raw.(*server.DescribeCollectionRequest)
 		resp := &server.DescribeCollectionResponse{}
 		if !ok {
 			s, err := BadRequestStatus()
@@ -137,11 +43,10 @@ func describeCollectionInjection(t *testing.T, collID int64, collName string, sc
 			return resp, err
 		}
 
-		assert.Equal(t, collName, req.GetCollectionName())
-
 		sch := sch
 		resp.Schema = sch.ProtoMessage()
 		resp.CollectionID = collID
+		resp.CollectionName = collName
 
 		s, err := SuccessStatus()
 		resp.Status = s
@@ -199,98 +104,6 @@ func TestGrpcClientGetCollectionStatistics(t *testing.T) {
 	}
 }
 
-func TestGrpcClientGetReplicas(t *testing.T) {
-	ctx := context.Background()
-	c := testClient(ctx, t)
-
-	replicaID := rand.Int63()
-	nodeIds := []int64{1, 2, 3, 4}
-	mockServer.SetInjection(MHasCollection, hasCollectionDefault)
-	defer mockServer.DelInjection(MHasCollection)
-
-	mockServer.SetInjection(MShowCollections, func(_ context.Context, raw proto.Message) (proto.Message, error) {
-		s, err := SuccessStatus()
-		resp := &server.ShowCollectionsResponse{
-			Status:              s,
-			CollectionIds:       []int64{testCollectionID},
-			CollectionNames:     []string{testCollectionName},
-			InMemoryPercentages: []int64{100},
-		}
-		return resp, err
-	})
-	defer mockServer.DelInjection(MShowCollections)
-
-	mockServer.SetInjection(MGetReplicas, func(ctx context.Context, raw proto.Message) (proto.Message, error) {
-		req, ok := raw.(*server.GetReplicasRequest)
-		resp := &server.GetReplicasResponse{}
-		if !ok {
-			s, err := BadRequestStatus()
-			resp.Status = s
-			return resp, err
-		}
-
-		assert.Equal(t, testCollectionID, req.CollectionID)
-
-		s, err := SuccessStatus()
-		resp.Status = s
-		resp.Replicas = []*server.ReplicaInfo{{
-			ReplicaID: replicaID,
-			ShardReplicas: []*server.ShardReplica{
-				{
-					LeaderID:      1,
-					DmChannelName: "DML_channel_v1",
-				},
-				{
-					LeaderID:   2,
-					LeaderAddr: "DML_channel_v2",
-				},
-			},
-			NodeIds: nodeIds,
-		}}
-		return resp, err
-	})
-
-	t.Run("get replicas normal", func(t *testing.T) {
-		groups, err := c.GetReplicas(ctx, testCollectionName)
-		assert.Nil(t, err)
-		assert.NotNil(t, groups)
-		assert.Equal(t, 1, len(groups))
-
-		assert.Equal(t, replicaID, groups[0].ReplicaID)
-		assert.Equal(t, nodeIds, groups[0].NodeIDs)
-		assert.Equal(t, 2, len(groups[0].ShardReplicas))
-	})
-
-	t.Run("get replicas invalid name", func(t *testing.T) {
-		_, err := c.GetReplicas(ctx, "invalid name")
-		assert.Error(t, err)
-	})
-
-	t.Run("get replicas grpc error", func(t *testing.T) {
-		mockServer.SetInjection(MGetReplicas, func(ctx context.Context, raw proto.Message) (proto.Message, error) {
-			return &server.GetReplicasResponse{}, errors.New("mocked grpc error")
-		})
-		_, err := c.GetReplicas(ctx, testCollectionName)
-		assert.Error(t, err)
-	})
-
-	t.Run("get replicas server error", func(t *testing.T) {
-		mockServer.SetInjection(MGetReplicas, func(ctx context.Context, raw proto.Message) (proto.Message, error) {
-			return &server.GetReplicasResponse{
-				Status: &common.Status{
-					ErrorCode: common.ErrorCode_UnexpectedError,
-					Reason:    "Service is not healthy",
-				},
-				Replicas: nil,
-			}, nil
-		})
-		_, err := c.GetReplicas(ctx, testCollectionName)
-		assert.Error(t, err)
-	})
-
-	mockServer.DelInjection(MGetReplicas)
-}
-
 func TestGrpcClientGetLoadingProgress(t *testing.T) {
 	ctx := context.Background()
 	c := testClient(ctx, t)
@@ -317,7 +130,6 @@ func TestGrpcClientGetLoadingProgress(t *testing.T) {
 	progress, err := c.GetLoadingProgress(ctx, testCollectionName, []string{})
 	assert.NoError(t, err)
 	assert.Equal(t, int64(100), progress)
-
 }
 
 func TestGrpcClientGetLoadState(t *testing.T) {
@@ -455,7 +267,6 @@ func (s *CollectionSuite) TestCreateCollection() {
 				s.Equal(common.ConsistencyLevel_Bounded, req.GetConsistencyLevel())
 			}).
 			Return(&common.Status{ErrorCode: common.ErrorCode_Success}, nil)
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).Return(&server.BoolResponse{Status: &common.Status{}, Value: false}, nil)
 
 		err := c.CreateCollection(ctx, ds, shardsNum)
 		s.NoError(err)
@@ -482,7 +293,6 @@ func (s *CollectionSuite) TestCreateCollection() {
 
 			}).
 			Return(&common.Status{ErrorCode: common.ErrorCode_Success}, nil)
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).Return(&server.BoolResponse{Status: &common.Status{}, Value: false}, nil)
 
 		err := c.CreateCollection(ctx, ds, shardsNum, WithConsistencyLevel(entity.ClEventually))
 		s.NoError(err)
@@ -506,14 +316,14 @@ func (s *CollectionSuite) TestCreateCollection() {
 					WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithDim(128)),
 			},
 			{
-				name: "multiple primary key",
+				name: "multiple_primary_key",
 				schema: entity.NewSchema().WithName(testCollectionName).
 					WithField(entity.NewField().WithName("int64").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true)).
 					WithField(entity.NewField().WithName("int64_2").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true)).
 					WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithDim(128)),
 			},
 			{
-				name: "multiple auto id",
+				name: "multiple_auto_id",
 				schema: entity.NewSchema().WithName(testCollectionName).
 					WithField(entity.NewField().WithName("int64").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true).WithIsAutoID(true)).
 					WithField(entity.NewField().WithName("int64_2").WithDataType(entity.FieldTypeInt64).WithIsAutoID(true)).
@@ -538,7 +348,6 @@ func (s *CollectionSuite) TestCreateCollection() {
 	s.Run("server_returns_error", func() {
 		s.Run("create_collection_error", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).Return(&server.BoolResponse{Status: &common.Status{}, Value: false}, nil)
 			s.mock.EXPECT().CreateCollection(mock.Anything, mock.AnythingOfType("*milvuspb.CreateCollectionRequest")).
 				Return(nil, errors.New("mocked grpc error"))
 
@@ -548,7 +357,6 @@ func (s *CollectionSuite) TestCreateCollection() {
 
 		s.Run("create_collection_fail", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).Return(&server.BoolResponse{Status: &common.Status{}, Value: false}, nil)
 			s.mock.EXPECT().CreateCollection(mock.Anything, mock.AnythingOfType("*milvuspb.CreateCollectionRequest")).
 				Return(&common.Status{ErrorCode: common.ErrorCode_UnexpectedError}, nil)
 
@@ -617,9 +425,7 @@ func (s *CollectionSuite) TestNewCollection() {
 				created = true
 			}).
 			Return(&common.Status{ErrorCode: common.ErrorCode_Success}, nil)
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).Call.Return(func(_ context.Context, _ *server.HasCollectionRequest) *server.BoolResponse {
-			return &server.BoolResponse{Status: &common.Status{}, Value: created}
-		}, nil)
+
 		s.mock.EXPECT().CreateIndex(mock.Anything, mock.Anything).Return(&common.Status{ErrorCode: common.ErrorCode_Success}, nil)
 		s.mock.EXPECT().Flush(mock.Anything, mock.Anything).Return(&server.FlushResponse{
 			Status:     &common.Status{ErrorCode: common.ErrorCode_Success},
@@ -636,14 +442,19 @@ func (s *CollectionSuite) TestNewCollection() {
 			Status:   &common.Status{ErrorCode: common.ErrorCode_Success},
 			Progress: 100,
 		}, nil)
-		s.mock.EXPECT().DescribeCollection(mock.Anything, mock.Anything).Return(&server.DescribeCollectionResponse{
-			Status: &common.Status{ErrorCode: common.ErrorCode_Success},
-			Schema: &schema.CollectionSchema{
-				Fields: []*schema.FieldSchema{
-					{Name: "id", DataType: schema.DataType_VarChar},
-					{Name: "vector", DataType: schema.DataType_FloatVector},
-				},
-			},
+		s.mock.EXPECT().DescribeCollection(mock.Anything, mock.Anything).Call.Return(func(_ context.Context, _ *server.DescribeCollectionRequest) *server.DescribeCollectionResponse {
+			if created {
+				return &server.DescribeCollectionResponse{
+					Status: &common.Status{},
+					Schema: &schema.CollectionSchema{
+						Fields: []*schema.FieldSchema{
+							{Name: "id", DataType: schema.DataType_VarChar},
+							{Name: "vector", DataType: schema.DataType_FloatVector},
+						},
+					},
+				}
+			}
+			return &server.DescribeCollectionResponse{Status: &common.Status{ErrorCode: common.ErrorCode_CollectionNotExists}}
 		}, nil)
 
 		err := c.NewCollection(ctx, testCollectionName, testVectorDim)
@@ -673,9 +484,6 @@ func (s *CollectionSuite) TestNewCollection() {
 				created = true
 			}).
 			Return(&common.Status{ErrorCode: common.ErrorCode_Success}, nil)
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).Call.Return(func(_ context.Context, _ *server.HasCollectionRequest) *server.BoolResponse {
-			return &server.BoolResponse{Status: &common.Status{}, Value: created}
-		}, nil)
 		s.mock.EXPECT().CreateIndex(mock.Anything, mock.Anything).Return(&common.Status{ErrorCode: common.ErrorCode_Success}, nil)
 		s.mock.EXPECT().Flush(mock.Anything, mock.Anything).Return(&server.FlushResponse{
 			Status:     &common.Status{ErrorCode: common.ErrorCode_Success},
@@ -692,14 +500,19 @@ func (s *CollectionSuite) TestNewCollection() {
 			Status:   &common.Status{ErrorCode: common.ErrorCode_Success},
 			Progress: 100,
 		}, nil)
-		s.mock.EXPECT().DescribeCollection(mock.Anything, mock.Anything).Return(&server.DescribeCollectionResponse{
-			Status: &common.Status{ErrorCode: common.ErrorCode_Success},
-			Schema: &schema.CollectionSchema{
-				Fields: []*schema.FieldSchema{
-					{Name: "my_pk", DataType: schema.DataType_VarChar},
-					{Name: "embedding", DataType: schema.DataType_FloatVector},
-				},
-			},
+		s.mock.EXPECT().DescribeCollection(mock.Anything, mock.Anything).Call.Return(func(_ context.Context, _ *server.DescribeCollectionRequest) *server.DescribeCollectionResponse {
+			if created {
+				return &server.DescribeCollectionResponse{
+					Status: &common.Status{},
+					Schema: &schema.CollectionSchema{
+						Fields: []*schema.FieldSchema{
+							{Name: "my_pk", DataType: schema.DataType_VarChar},
+							{Name: "embedding", DataType: schema.DataType_FloatVector},
+						},
+					},
+				}
+			}
+			return &server.DescribeCollectionResponse{Status: &common.Status{ErrorCode: common.ErrorCode_CollectionNotExists}}
 		}, nil)
 
 		err := c.NewCollection(ctx, testCollectionName, testVectorDim, WithPKFieldName("my_pk"), WithPKFieldType(entity.FieldTypeVarChar), WithVectorFieldName("embedding"), WithConsistencyLevel(entity.ClEventually))
@@ -722,7 +535,7 @@ func (s *CollectionSuite) TestAlterCollection() {
 	s.Run("normal_run", func() {
 		defer s.resetMock()
 
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.mock.EXPECT().AlterCollection(mock.Anything, mock.AnythingOfType("*milvuspb.AlterCollectionRequest")).
 			Return(&common.Status{}, nil)
 
@@ -733,11 +546,7 @@ func (s *CollectionSuite) TestAlterCollection() {
 	s.Run("collection_not_exist", func() {
 		defer s.resetMock()
 
-		s.mock.EXPECT().HasCollection(mock.Anything, mock.AnythingOfType("*milvuspb.HasCollectionRequest")).
-			Return(&server.BoolResponse{
-				Status: &common.Status{},
-				Value:  false,
-			}, nil)
+		s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, nil)
 
 		err := c.AlterCollection(ctx, testCollectionName, entity.CollectionTTL(100000))
 		s.Error(err)
@@ -746,7 +555,7 @@ func (s *CollectionSuite) TestAlterCollection() {
 	s.Run("no_attributes", func() {
 		defer s.resetMock()
 
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		err := c.AlterCollection(ctx, testCollectionName)
 		s.Error(err)
 	})
@@ -754,7 +563,7 @@ func (s *CollectionSuite) TestAlterCollection() {
 	s.Run("request_fails", func() {
 		defer s.resetMock()
 
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.mock.EXPECT().AlterCollection(mock.Anything, mock.AnythingOfType("*milvuspb.AlterCollectionRequest")).
 			Return(nil, errors.New("mocked"))
 
@@ -765,7 +574,7 @@ func (s *CollectionSuite) TestAlterCollection() {
 	s.Run("server_return_error", func() {
 		defer s.resetMock()
 
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.mock.EXPECT().AlterCollection(mock.Anything, mock.AnythingOfType("*milvuspb.AlterCollectionRequest")).
 			Return(&common.Status{ErrorCode: common.ErrorCode_UnexpectedError}, nil)
 
@@ -788,8 +597,7 @@ func (s *CollectionSuite) TestLoadCollection() {
 
 	s.Run("normal_run_async", func() {
 		defer s.resetMock()
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-			Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+		s.setupDescribeCollection(testCollectionName, nil)
 
 		s.mock.EXPECT().LoadCollection(mock.Anything, mock.Anything).Return(&common.Status{ErrorCode: common.ErrorCode_Success}, nil)
 
@@ -799,8 +607,7 @@ func (s *CollectionSuite) TestLoadCollection() {
 
 	s.Run("normal_run_sync", func() {
 		defer s.resetMock()
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-			Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+		s.setupDescribeCollection(testCollectionName, nil)
 
 		s.mock.EXPECT().LoadCollection(mock.Anything, mock.Anything).Return(&common.Status{ErrorCode: common.ErrorCode_Success}, nil)
 		s.mock.EXPECT().GetLoadingProgress(mock.Anything, mock.Anything).
@@ -809,14 +616,13 @@ func (s *CollectionSuite) TestLoadCollection() {
 				Progress: 100,
 			}, nil)
 
-		err := c.LoadCollection(ctx, testCollectionName, true)
+		err := c.LoadCollection(ctx, testCollectionName, false)
 		s.NoError(err)
 	})
 
 	s.Run("load_default_replica", func() {
 		defer s.resetMock()
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-			Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+		s.setupDescribeCollection(testCollectionName, nil)
 
 		s.mock.EXPECT().LoadCollection(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.LoadCollectionRequest) {
 			s.Equal(testDefaultReplicaNumber, req.GetReplicaNumber())
@@ -829,8 +635,7 @@ func (s *CollectionSuite) TestLoadCollection() {
 
 	s.Run("load_multiple_replica", func() {
 		defer s.resetMock()
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-			Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+		s.setupDescribeCollection(testCollectionName, nil)
 
 		s.mock.EXPECT().LoadCollection(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.LoadCollectionRequest) {
 			s.Equal(testMultiReplicaNumber, req.GetReplicaNumber())
@@ -844,8 +649,7 @@ func (s *CollectionSuite) TestLoadCollection() {
 	s.Run("has_collection_failure", func() {
 		s.Run("return_false", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(&server.BoolResponse{Status: &common.Status{}, Value: false}, nil)
+			s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, nil)
 
 			err := c.LoadCollection(ctx, testCollectionName, true)
 			s.Error(err)
@@ -853,8 +657,7 @@ func (s *CollectionSuite) TestLoadCollection() {
 
 		s.Run("return_error", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(nil, errors.New("mock error"))
+			s.setupDescribeCollectionError(common.ErrorCode_UnexpectedError, errors.New("mocked error"))
 
 			err := c.LoadCollection(ctx, testCollectionName, true)
 			s.Error(err)
@@ -864,8 +667,7 @@ func (s *CollectionSuite) TestLoadCollection() {
 	s.Run("load_collection_failure", func() {
 		s.Run("failure_status", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+			s.setupDescribeCollection(testCollectionName, nil)
 
 			s.mock.EXPECT().LoadCollection(mock.Anything, mock.Anything).
 				Return(&common.Status{ErrorCode: common.ErrorCode_UnexpectedError}, nil)
@@ -875,8 +677,8 @@ func (s *CollectionSuite) TestLoadCollection() {
 		})
 
 		s.Run("return_error", func() {
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+			defer s.resetMock()
+			s.setupDescribeCollection(testCollectionName, nil)
 
 			s.mock.EXPECT().LoadCollection(mock.Anything, mock.Anything).
 				Return(nil, errors.New("mock error"))
@@ -888,8 +690,7 @@ func (s *CollectionSuite) TestLoadCollection() {
 
 	s.Run("get_loading_progress_failure", func() {
 		defer s.resetMock()
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-			Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+		s.setupDescribeCollection(testCollectionName, nil)
 
 		s.mock.EXPECT().LoadCollection(mock.Anything, mock.Anything).Return(&common.Status{ErrorCode: common.ErrorCode_Success}, nil)
 		s.mock.EXPECT().GetLoadingProgress(mock.Anything, mock.Anything).
@@ -906,6 +707,320 @@ func (s *CollectionSuite) TestLoadCollection() {
 	})
 }
 
+func (s *CollectionSuite) TestDropCollection() {
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	c := s.client
+
+	s.Run("normal_run", func() {
+		defer s.resetMock()
+
+		s.setupDescribeCollection(testCollectionName, nil)
+		s.mock.EXPECT().DropCollection(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.DropCollectionRequest) {
+			s.Equal(testCollectionName, req.GetCollectionName())
+		}).Return(&common.Status{}, nil)
+
+		err := c.DropCollection(ctx, testCollectionName)
+		s.NoError(err)
+	})
+
+	s.Run("coll_not_exists", func() {
+		defer s.resetMock()
+
+		s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, nil)
+
+		err := c.DropCollection(ctx, testCollectionName)
+		s.Error(err)
+	})
+
+	s.Run("drop_collection_fail", func() {
+		s.Run("return_error", func() {
+			defer s.resetMock()
+
+			s.setupDescribeCollection(testCollectionName, nil)
+			s.mock.EXPECT().DropCollection(mock.Anything, mock.Anything).Return(nil, errors.New("mocked"))
+
+			err := c.DropCollection(ctx, testCollectionName)
+			s.Error(err)
+		})
+
+		s.Run("return_error_status", func() {
+			defer s.resetMock()
+
+			s.setupDescribeCollection(testCollectionName, nil)
+			s.mock.EXPECT().DropCollection(mock.Anything, mock.Anything).
+				Return(&common.Status{ErrorCode: common.ErrorCode_UnexpectedError}, nil)
+
+			err := c.DropCollection(ctx, testCollectionName)
+			s.Error(err)
+		})
+	})
+
+	s.Run("service_not_ready", func() {
+		c := &GrpcClient{}
+		err := c.DropCollection(ctx, testCollectionName)
+		s.ErrorIs(err, ErrClientNotReady)
+	})
+}
+
+func (s *CollectionSuite) TestReleaseCollection() {
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	c := s.client
+
+	s.Run("normal_run", func() {
+		defer s.resetMock()
+
+		s.setupDescribeCollection(testCollectionName, nil)
+		s.mock.EXPECT().ReleaseCollection(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.ReleaseCollectionRequest) {
+			s.Equal(testCollectionName, req.GetCollectionName())
+		}).Return(&common.Status{}, nil)
+
+		err := c.ReleaseCollection(ctx, testCollectionName)
+		s.NoError(err)
+	})
+
+	s.Run("coll_not_exists", func() {
+		defer s.resetMock()
+
+		s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, nil)
+
+		err := c.ReleaseCollection(ctx, testCollectionName)
+		s.Error(err)
+	})
+
+	s.Run("release_collection_fail", func() {
+		s.Run("return_error", func() {
+			defer s.resetMock()
+
+			s.setupDescribeCollection(testCollectionName, nil)
+			s.mock.EXPECT().ReleaseCollection(mock.Anything, mock.Anything).Return(nil, errors.New("mocked"))
+
+			err := c.ReleaseCollection(ctx, testCollectionName)
+			s.Error(err)
+		})
+
+		s.Run("return_error_status", func() {
+			defer s.resetMock()
+
+			s.setupDescribeCollection(testCollectionName, nil)
+			s.mock.EXPECT().ReleaseCollection(mock.Anything, mock.Anything).
+				Return(&common.Status{ErrorCode: common.ErrorCode_UnexpectedError}, nil)
+
+			err := c.ReleaseCollection(ctx, testCollectionName)
+			s.Error(err)
+		})
+	})
+
+	s.Run("service_not_ready", func() {
+		c := &GrpcClient{}
+		err := c.ReleaseCollection(ctx, testCollectionName)
+		s.ErrorIs(err, ErrClientNotReady)
+	})
+}
+
+func (s *CollectionSuite) TestHasCollection() {
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	c := s.client
+
+	s.Run("normal_run", func() {
+		defer s.resetMock()
+
+		s.setupDescribeCollection(testCollectionName, nil)
+		s.mock.EXPECT().DescribeCollection(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.DescribeCollectionRequest) {
+			s.Equal(testCollectionName, req.GetCollectionName())
+		}).Return(&server.DescribeCollectionResponse{Status: &common.Status{ErrorCode: common.ErrorCode_Success}}, nil)
+
+		result, err := c.HasCollection(ctx, testCollectionName)
+		s.NoError(err)
+		s.True(result)
+	})
+
+	s.Run("coll_not_exists", func() {
+		defer s.resetMock()
+
+		s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, nil)
+
+		result, err := c.HasCollection(ctx, testCollectionName)
+		s.NoError(err)
+		s.False(result)
+	})
+
+	s.Run("return_unexpected_oldreason", func() {
+		defer s.resetMock()
+
+		s.mock.EXPECT().DescribeCollection(mock.Anything, mock.Anything).
+			Return(&server.DescribeCollectionResponse{
+				Status: &common.Status{ErrorCode: common.ErrorCode_UnexpectedError, Reason: "can't find collection"},
+			}, nil)
+
+		result, err := c.HasCollection(ctx, testCollectionName)
+		s.NoError(err)
+		s.False(result)
+	})
+
+	s.Run("return_unexpected_other", func() {
+		defer s.resetMock()
+
+		s.mock.EXPECT().DescribeCollection(mock.Anything, mock.Anything).
+			Return(&server.DescribeCollectionResponse{
+				Status: &common.Status{ErrorCode: common.ErrorCode_UnexpectedError, Reason: "server not ready"},
+			}, nil)
+
+		result, err := c.HasCollection(ctx, testCollectionName)
+		s.Error(err)
+		s.False(result)
+	})
+
+	s.Run("return_error", func() {
+		defer s.resetMock()
+
+		s.setupDescribeCollectionError(common.ErrorCode_UnexpectedError, errors.New("mocked"))
+		_, err := c.HasCollection(ctx, testCollectionName)
+		s.Error(err)
+	})
+
+	s.Run("service_not_ready", func() {
+		c := &GrpcClient{}
+		_, err := c.HasCollection(ctx, testCollectionName)
+		s.ErrorIs(err, ErrClientNotReady)
+	})
+}
+
+func (s *CollectionSuite) TestDescribeCollection() {
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	c := s.client
+	sch := entity.NewSchema().WithName(testCollectionName).
+		WithField(entity.NewField().WithName("ID").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true)).
+		WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithDim(testVectorDim))
+
+	s.Run("normal_run", func() {
+		defer s.resetMock()
+
+		s.setupDescribeCollection(testCollectionName, sch)
+
+		coll, err := c.DescribeCollection(ctx, testCollectionName)
+		s.NoError(err)
+		s.Equal(testCollectionName, coll.Schema.CollectionName)
+	})
+
+	s.Run("describe_fail", func() {
+		s.Run("return_err", func() {
+			defer s.resetMock()
+
+			s.setupDescribeCollectionError(common.ErrorCode_UnexpectedError, errors.New("mocked"))
+
+			_, err := c.DescribeCollection(ctx, testCollectionName)
+			s.Error(err)
+		})
+
+		s.Run("return_err_status", func() {
+			defer s.resetMock()
+
+			s.setupDescribeCollectionError(common.ErrorCode_UnexpectedError, nil)
+
+			_, err := c.DescribeCollection(ctx, testCollectionName)
+			s.Error(err)
+		})
+	})
+
+	s.Run("service_not_ready", func() {
+		c := &GrpcClient{}
+		_, err := c.DescribeCollection(ctx, testCollectionName)
+		s.ErrorIs(err, ErrClientNotReady)
+	})
+}
+
+func (s *CollectionSuite) TestGetReplicas() {
+	ctx, cancel := context.WithCancel(context.Background())
+	defer cancel()
+
+	c := s.client
+	replicaID := rand.Int63()
+	nodeIds := []int64{1, 2, 3, 4}
+
+	s.Run("normal_run", func() {
+		defer s.resetMock()
+
+		s.setupShowCollection(testCollectionName)
+		s.mock.EXPECT().GetReplicas(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.GetReplicasRequest) {
+			s.Equal(testCollectionID, req.GetCollectionID())
+			s.True(req.GetWithShardNodes())
+		}).Return(&server.GetReplicasResponse{
+			Status: &common.Status{},
+			Replicas: []*server.ReplicaInfo{{
+				ReplicaID: replicaID,
+				ShardReplicas: []*server.ShardReplica{
+					{
+						LeaderID:      1,
+						DmChannelName: "DML_channel_v1",
+					},
+					{
+						LeaderID:   2,
+						LeaderAddr: "DML_channel_v2",
+					},
+				},
+				NodeIds: nodeIds,
+			}},
+		}, nil)
+
+		groups, err := c.GetReplicas(ctx, testCollectionName)
+		s.NoError(err)
+		s.NotNil(groups)
+		s.Equal(1, len(groups))
+
+		s.Equal(replicaID, groups[0].ReplicaID)
+		s.Equal(nodeIds, groups[0].NodeIDs)
+		s.Equal(2, len(groups[0].ShardReplicas))
+	})
+
+	s.Run("collection_not_exists", func() {
+		defer s.resetMock()
+
+		s.setupShowCollectionError(common.ErrorCode_CollectionNotExists, nil)
+
+		_, err := c.GetReplicas(ctx, testCollectionName)
+		s.Error(err)
+	})
+
+	s.Run("get_replica_fail", func() {
+		s.Run("return_err", func() {
+			defer s.resetMock()
+
+			s.setupShowCollection(testCollectionName)
+			s.mock.EXPECT().GetReplicas(mock.Anything, mock.Anything).
+				Return(nil, errors.New("mocked"))
+
+			_, err := c.GetReplicas(ctx, testCollectionName)
+			s.Error(err)
+		})
+
+		s.Run("return_fail_status", func() {
+			defer s.resetMock()
+
+			s.setupShowCollection(testCollectionName)
+			s.mock.EXPECT().GetReplicas(mock.Anything, mock.Anything).
+				Return(&server.GetReplicasResponse{
+					Status: &common.Status{ErrorCode: common.ErrorCode_UnexpectedError}}, nil)
+
+			_, err := c.GetReplicas(ctx, testCollectionName)
+			s.Error(err)
+		})
+	})
+
+	s.Run("service_not_ready", func() {
+		c := &GrpcClient{}
+		_, err := c.GetReplicas(ctx, testCollectionName)
+		s.ErrorIs(err, ErrClientNotReady)
+	})
+}
+
 func TestCollectionSuite(t *testing.T) {
 	suite.Run(t, new(CollectionSuite))
 }
diff --git a/client/insert_test.go b/client/insert_test.go
index fc78d34..9365b00 100644
--- a/client/insert_test.go
+++ b/client/insert_test.go
@@ -35,14 +35,14 @@ func (s *InsertSuite) TestInsertFail() {
 
 	s.Run("collection_not_exist", func() {
 		defer s.resetMock()
-		s.setupHasCollection()
+		s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, nil)
 		_, err := c.Insert(ctx, testCollectionName, "")
 		s.Error(err)
 	})
 
 	s.Run("partition_not_exist", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.setupHasPartition(testCollectionName)
 
 		_, err := c.Insert(ctx, testCollectionName, "partition_name")
@@ -51,7 +51,7 @@ func (s *InsertSuite) TestInsertFail() {
 
 	s.Run("field_not_exist", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.setupHasPartition(testCollectionName, "partition_1")
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
 			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
@@ -66,7 +66,7 @@ func (s *InsertSuite) TestInsertFail() {
 
 	s.Run("missing_field", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
@@ -82,7 +82,7 @@ func (s *InsertSuite) TestInsertFail() {
 
 	s.Run("column_len_not_match", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
@@ -99,28 +99,12 @@ func (s *InsertSuite) TestInsertFail() {
 
 	s.Run("duplicated column", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
 			WithField(entity.NewField().WithIsPrimaryKey(true).WithIsAutoID(true).WithName("ID").WithDataType(entity.FieldTypeInt64)).
 			WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
 		)
-
-		s.mock.EXPECT().Insert(mock.Anything, mock.AnythingOfType("*milvuspb.InsertRequest")).
-			Run(func(ctx context.Context, req *server.InsertRequest) {
-				s.Equal(1, len(req.GetFieldsData()))
-			}).Return(&server.MutationResult{
-			Status: &common.Status{},
-			IDs: &schema.IDs{
-				IdField: &schema.IDs_IntId{
-					IntId: &schema.LongArray{
-						Data: []int64{1},
-					},
-				},
-			},
-		}, nil)
-
 		_, err := c.Insert(ctx, testCollectionName, "partition_1",
 			entity.NewColumnFloatVector("vector", 128, generateFloatVector(1, 128)),
 			entity.NewColumnFloatVector("vector", 128, generateFloatVector(1, 128)),
@@ -131,7 +115,7 @@ func (s *InsertSuite) TestInsertFail() {
 
 	s.Run("dim_not_match", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
@@ -148,7 +132,6 @@ func (s *InsertSuite) TestInsertFail() {
 
 	s.Run("server_insert_fail", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
@@ -169,7 +152,6 @@ func (s *InsertSuite) TestInsertFail() {
 
 	s.Run("server_connection_error", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
@@ -196,7 +178,6 @@ func (s *InsertSuite) TestInsertSuccess() {
 
 	s.Run("non_dynamic_schema", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
@@ -228,7 +209,6 @@ func (s *InsertSuite) TestInsertSuccess() {
 
 	s.Run("dynamic_field_schema", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, "partition_1")
 
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
diff --git a/client/partition_test.go b/client/partition_test.go
index 8479698..5c18a18 100644
--- a/client/partition_test.go
+++ b/client/partition_test.go
@@ -50,7 +50,7 @@ func TestGrpcClientCreatePartition(t *testing.T) {
 
 	partitionName := fmt.Sprintf("_part_%d", rand.Int())
 
-	mockServer.SetInjection(MHasCollection, hasCollectionDefault)
+	mockServer.SetInjection(MDescribeCollection, describeCollectionInjection(t, testCollectionID, testCollectionName, nil))
 	mockServer.SetInjection(MHasPartition, func(_ context.Context, raw proto.Message) (proto.Message, error) {
 		req, ok := raw.(*server.HasPartitionRequest)
 		resp := &server.BoolResponse{}
@@ -74,7 +74,7 @@ func TestGrpcClientDropPartition(t *testing.T) {
 	partitionName := fmt.Sprintf("_part_%d", rand.Int())
 	ctx := context.Background()
 	c := testClient(ctx, t)
-	mockServer.SetInjection(MHasCollection, hasCollectionDefault)
+	mockServer.SetInjection(MDescribeCollection, describeCollectionInjection(t, testCollectionID, testCollectionName, nil))
 	mockServer.SetInjection(MHasPartition, hasPartitionInjection(t, testCollectionName, true, partitionName)) // injection has assertion of collName & parition name
 	assert.Nil(t, c.DropPartition(ctx, testCollectionName, partitionName))
 }
@@ -83,7 +83,7 @@ func TestGrpcClientHasPartition(t *testing.T) {
 	partitionName := fmt.Sprintf("_part_%d", rand.Int())
 	ctx := context.Background()
 	c := testClient(ctx, t)
-	mockServer.SetInjection(MHasCollection, hasCollectionDefault)
+	mockServer.SetInjection(MDescribeCollection, describeCollectionInjection(t, testCollectionID, testCollectionName, nil))
 	mockServer.SetInjection(MHasPartition, hasPartitionInjection(t, testCollectionName, false, partitionName)) // injection has assertion of collName & parition name
 
 	r, err := c.HasPartition(ctx, testCollectionName, "_default_part")
@@ -173,7 +173,7 @@ func TestGrpcClientReleasePartitions(t *testing.T) {
 	c := testClient(ctx, t)
 
 	parts := []string{"_part1", "_part2"}
-	mockServer.SetInjection(MHasCollection, hasCollectionDefault)
+	mockServer.SetInjection(MDescribeCollection, describeCollectionInjection(t, testCollectionID, testCollectionName, nil))
 	mockServer.SetInjection(MHasPartition, hasPartitionInjection(t, testCollectionName, true, "_part1", "_part2", "_part3", "_part4"))
 	mockServer.SetInjection(MReleasePartitions, func(_ context.Context, raw proto.Message) (proto.Message, error) {
 		req, ok := raw.(*server.ReleasePartitionsRequest)
@@ -263,8 +263,7 @@ func (s *PartitionSuite) TestLoadPartitions() {
 
 	s.Run("normal_run_async", func() {
 		defer s.resetMock()
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-			Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.mock.EXPECT().HasPartition(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.HasPartitionRequest) {
 			s.Equal(testCollectionName, req.GetCollectionName())
 			_, ok := mPartNames[req.GetPartitionName()]
@@ -281,8 +280,7 @@ func (s *PartitionSuite) TestLoadPartitions() {
 
 	s.Run("normal_run_sync", func() {
 		defer s.resetMock()
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-			Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.mock.EXPECT().HasPartition(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.HasPartitionRequest) {
 			s.Equal(testCollectionName, req.GetCollectionName())
 			_, ok := mPartNames[req.GetPartitionName()]
@@ -302,8 +300,7 @@ func (s *PartitionSuite) TestLoadPartitions() {
 	s.Run("has_collection_failure", func() {
 		s.Run("return_false", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(&server.BoolResponse{Status: &common.Status{}, Value: false}, nil)
+			s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, nil)
 
 			err := c.LoadPartitions(ctx, testCollectionName, partNames, false)
 			s.Error(err)
@@ -311,8 +308,7 @@ func (s *PartitionSuite) TestLoadPartitions() {
 
 		s.Run("return_error", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(nil, errors.New("mock error"))
+			s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, errors.New("mocked"))
 
 			err := c.LoadPartitions(ctx, testCollectionName, partNames, false)
 			s.Error(err)
@@ -322,8 +318,7 @@ func (s *PartitionSuite) TestLoadPartitions() {
 	s.Run("has_partition_failure", func() {
 		s.Run("return_false", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+			s.setupDescribeCollection(testCollectionName, nil)
 			s.mock.EXPECT().HasPartition(mock.Anything, mock.Anything).
 				Return(&server.BoolResponse{Status: &common.Status{}, Value: false}, nil)
 
@@ -333,8 +328,7 @@ func (s *PartitionSuite) TestLoadPartitions() {
 
 		s.Run("return_error", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+			s.setupDescribeCollection(testCollectionName, nil)
 			s.mock.EXPECT().HasPartition(mock.Anything, mock.Anything).
 				Return(nil, errors.New("mock"))
 
@@ -346,8 +340,7 @@ func (s *PartitionSuite) TestLoadPartitions() {
 	s.Run("load_partitions_failure", func() {
 		s.Run("fail_status_code", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+			s.setupDescribeCollection(testCollectionName, nil)
 			s.mock.EXPECT().HasPartition(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.HasPartitionRequest) {
 				s.Equal(testCollectionName, req.GetCollectionName())
 				_, ok := mPartNames[req.GetPartitionName()]
@@ -364,8 +357,7 @@ func (s *PartitionSuite) TestLoadPartitions() {
 
 		s.Run("return_error", func() {
 			defer s.resetMock()
-			s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-				Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+			s.setupDescribeCollection(testCollectionName, nil)
 			s.mock.EXPECT().HasPartition(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.HasPartitionRequest) {
 				s.Equal(testCollectionName, req.GetCollectionName())
 				_, ok := mPartNames[req.GetPartitionName()]
@@ -383,8 +375,7 @@ func (s *PartitionSuite) TestLoadPartitions() {
 
 	s.Run("get_loading_progress_failure", func() {
 		defer s.resetMock()
-		s.mock.EXPECT().HasCollection(mock.Anything, &server.HasCollectionRequest{CollectionName: testCollectionName}).
-			Return(&server.BoolResponse{Status: &common.Status{}, Value: true}, nil)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.mock.EXPECT().HasPartition(mock.Anything, mock.Anything).Run(func(_ context.Context, req *server.HasPartitionRequest) {
 			s.Equal(testCollectionName, req.GetCollectionName())
 			_, ok := mPartNames[req.GetPartitionName()]
diff --git a/client/row_test.go b/client/row_test.go
index 89c7f20..119a186 100644
--- a/client/row_test.go
+++ b/client/row_test.go
@@ -34,6 +34,17 @@ func TestCreateCollectionByRow(t *testing.T) {
 	}
 	t.Run("Test normal creation", func(t *testing.T) {
 		mockServer.DelInjection(MHasCollection)
+		mockServer.DelInjection(MDescribeCollection)
+		mockServer.SetInjection(MDescribeCollection, func(_ context.Context, raw proto.Message) (proto.Message, error) {
+			_, ok := raw.(*server.DescribeCollectionRequest)
+			resp := &server.DescribeCollectionResponse{}
+			if !ok {
+				return BadRequestStatus()
+			}
+			resp.Status = &common.Status{ErrorCode: common.ErrorCode_CollectionNotExists}
+
+			return resp, nil
+		})
 		shardsNum := int32(1)
 		mockServer.SetInjection(MCreateCollection, func(ctx context.Context, raw proto.Message) (proto.Message, error) {
 			req, ok := raw.(*server.CreateCollectionRequest)
@@ -64,17 +75,23 @@ func TestCreateCollectionByRow(t *testing.T) {
 
 			return SuccessStatus()
 		})
-		mockServer.SetInjection(MHasCollection, func(_ context.Context, raw proto.Message) (proto.Message, error) {
-			req, ok := raw.(*server.HasCollectionRequest)
-			resp := &server.BoolResponse{}
+		mockServer.SetInjection(MDescribeCollection, func(_ context.Context, raw proto.Message) (proto.Message, error) {
+			req, ok := raw.(*server.DescribeCollectionRequest)
+			resp := &server.DescribeCollectionResponse{}
 			if !ok {
 				return BadRequestStatus()
 			}
 
 			_, has := m[req.GetCollectionName()]
-			resp.Value = has
-			s, err := SuccessStatus()
+			var err error
+			var s *common.Status
+			if has {
+				s, err = SuccessStatus()
+			} else {
+				s = &common.Status{ErrorCode: common.ErrorCode_CollectionNotExists}
+			}
 			resp.Status = s
+
 			return resp, err
 		})
 		assert.Nil(t, c.CreateCollectionByRow(ctx, &ValidStruct{}, 1))
@@ -108,28 +125,21 @@ func (s *InsertByRowsSuite) TestFails() {
 
 	s.Run("fail_collection_not_found", func() {
 		defer s.resetMock()
-		s.setupHasCollection()
-		_, err := c.InsertByRows(ctx, testCollectionName, partName, []entity.Row{entity.RowBase{}})
-		s.Error(err)
-	})
-
-	s.Run("fail_hascollection_errcode", func() {
-		defer s.resetMock()
-		s.setupHasCollectionError(common.ErrorCode_UnexpectedError, nil)
+		s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, nil)
 		_, err := c.InsertByRows(ctx, testCollectionName, partName, []entity.Row{entity.RowBase{}})
 		s.Error(err)
 	})
 
 	s.Run("fail_hascollection_error", func() {
 		defer s.resetMock()
-		s.setupHasCollectionError(common.ErrorCode_Success, errors.New("mock error"))
+		s.setupDescribeCollectionError(common.ErrorCode_CollectionNotExists, errors.New("mocked"))
 		_, err := c.InsertByRows(ctx, testCollectionName, partName, []entity.Row{entity.RowBase{}})
 		s.Error(err)
 	})
 
 	s.Run("fail_partition_not_found", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.setupHasPartition(testCollectionName)
 		_, err := c.InsertByRows(ctx, testCollectionName, partName, []entity.Row{entity.RowBase{}})
 		s.Error(err)
@@ -137,7 +147,7 @@ func (s *InsertByRowsSuite) TestFails() {
 
 	s.Run("fail_haspartition_error", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.setupHasPartitionError(common.ErrorCode_Success, errors.New("mock error"))
 		_, err := c.InsertByRows(ctx, testCollectionName, partName, []entity.Row{entity.RowBase{}})
 		s.Error(err)
@@ -145,7 +155,7 @@ func (s *InsertByRowsSuite) TestFails() {
 
 	s.Run("fail_haspartition_errcode", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
+		s.setupDescribeCollection(testCollectionName, nil)
 		s.setupHasPartitionError(common.ErrorCode_UnexpectedError, nil)
 		_, err := c.InsertByRows(ctx, testCollectionName, partName, []entity.Row{entity.RowBase{}})
 		s.Error(err)
@@ -153,8 +163,6 @@ func (s *InsertByRowsSuite) TestFails() {
 
 	s.Run("fail_describecollection_error", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
-		s.setupHasPartition(testCollectionName, partName)
 		s.setupDescribeCollectionError(common.ErrorCode_Success, errors.New("mock error"))
 		_, err := c.InsertByRows(ctx, testCollectionName, partName, []entity.Row{entity.RowBase{}})
 		s.Error(err)
@@ -162,8 +170,6 @@ func (s *InsertByRowsSuite) TestFails() {
 
 	s.Run("fail_describecollection_errcode", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
-		s.setupHasPartition(testCollectionName, partName)
 		s.setupDescribeCollectionError(common.ErrorCode_UnexpectedError, nil)
 		_, err := c.InsertByRows(ctx, testCollectionName, partName, []entity.Row{entity.RowBase{}})
 		s.Error(err)
@@ -171,7 +177,6 @@ func (s *InsertByRowsSuite) TestFails() {
 
 	s.Run("fail_field_missing", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, partName)
 		s.setupDescribeCollection(testCollectionName,
 			entity.NewSchema().
@@ -188,7 +193,6 @@ func (s *InsertByRowsSuite) TestFails() {
 
 	s.Run("fail_field_type_not_match", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, partName)
 		s.setupDescribeCollection(testCollectionName,
 			entity.NewSchema().
@@ -206,7 +210,6 @@ func (s *InsertByRowsSuite) TestFails() {
 
 	s.Run("fail_extra_field", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, partName)
 		s.setupDescribeCollection(testCollectionName,
 			entity.NewSchema().
@@ -225,12 +228,11 @@ func (s *InsertByRowsSuite) TestFails() {
 
 	s.Run("vector_dim_not_match", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, partName)
 		s.setupDescribeCollection(testCollectionName,
 			entity.NewSchema().
 				WithField(entity.NewField().WithName("ID").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true).WithIsAutoID(true)).
-				WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithTypeParams(entity.TypeParamDim, "128")),
+				WithField(entity.NewField().WithName("vector").WithDataType(entity.FieldTypeFloatVector).WithDim(128)),
 		)
 		type row struct {
 			entity.RowBase
@@ -250,7 +252,6 @@ func (s *InsertByRowsSuite) TestSuccess() {
 
 	s.Run("non_dynamic", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, partName)
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().WithName(testCollectionName).
 			WithField(entity.NewField().WithName("ID").WithDataType(entity.FieldTypeInt64).WithIsPrimaryKey(true)).
@@ -280,7 +281,6 @@ func (s *InsertByRowsSuite) TestSuccess() {
 
 	s.Run("dynamic", func() {
 		defer s.resetMock()
-		s.setupHasCollection(testCollectionName)
 		s.setupHasPartition(testCollectionName, partName)
 		s.setupDescribeCollection(testCollectionName, entity.NewSchema().
 			WithName(testCollectionName).WithDynamicFieldEnabled(true).
diff --git a/test/testcases/search_test.go b/test/testcases/search_test.go
index ddbf4a6..1f91712 100644
--- a/test/testcases/search_test.go
+++ b/test/testcases/search_test.go
@@ -65,7 +65,7 @@ func TestSearchCollectionNotExist(t *testing.T) {
 		common.DefaultTopK,
 		sp,
 	)
-	common.CheckErr(t, errSearch, false, "can't find collection: collName")
+	common.CheckErr(t, errSearch, false, "can't find collection")
 }
 
 // test search empty collection -> return empty