Repository: dragonflyoss/Dragonfly2
Pull request #844 (2021-12-01 04:01:45)

feat: searcher plugin change return params
Signed-off-by: Gaius <gaius.qi@gmail.com>

<!--- Provide a general summary of your changes in the Title above -->

## Description
- searcher plugin change return params.
<!--- Describe your changes in detail -->

## Related Issue

<!--- This project only accepts pull requests related to open issues -->
<!--- If suggesting a new feature or change, please discuss it in an issue first -->
<!--- If fixing a bug, there should be an issue describing it with steps to reproduce -->
<!--- Please link to the issue here: -->

## Motivation and Context

<!--- Why is this change required? What problem does it solve? -->

## Screenshots (if appropriate):

## Types of changes

<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->

- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Documentation Update (if none of the other choices apply)

## Checklist:

<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->

- [x] Code compiles correctly.
- [x] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [x] I have read the **CONTRIBUTING** document.
- [x] I have added tests to cover my changes.
- [x] All new and existing tests passed.



Patch:
diff --git a/manager/searcher/searcher.go b/manager/searcher/searcher.go
index 1e8c87ca..63a588c5 100644
--- a/manager/searcher/searcher.go
+++ b/manager/searcher/searcher.go
@@ -18,6 +18,8 @@ package searcher
 
 import (
 	"context"
+	"errors"
+	"fmt"
 	"strings"
 
 	"github.com/mitchellh/mapstructure"
@@ -73,7 +75,7 @@ type Scopes struct {
 }
 
 type Searcher interface {
-	FindSchedulerCluster(context.Context, []model.SchedulerCluster, *manager.ListSchedulersRequest) (model.SchedulerCluster, bool)
+	FindSchedulerCluster(context.Context, []model.SchedulerCluster, *manager.ListSchedulersRequest) (model.SchedulerCluster, error)
 }
 
 type searcher struct{}
@@ -89,10 +91,14 @@ func New() Searcher {
 	return s
 }
 
-func (s *searcher) FindSchedulerCluster(ctx context.Context, schedulerClusters []model.SchedulerCluster, client *manager.ListSchedulersRequest) (model.SchedulerCluster, bool) {
+func (s *searcher) FindSchedulerCluster(ctx context.Context, schedulerClusters []model.SchedulerCluster, client *manager.ListSchedulersRequest) (model.SchedulerCluster, error) {
 	conditions := client.HostInfo
-	if len(schedulerClusters) <= 0 || len(conditions) <= 0 {
-		return model.SchedulerCluster{}, false
+	if len(conditions) <= 0 {
+		return model.SchedulerCluster{}, errors.New("empty conditions")
+	}
+
+	if len(schedulerClusters) <= 0 {
+		return model.SchedulerCluster{}, errors.New("empty scheduler clusters")
 	}
 
 	// If there are security domain conditions, match clusters of the same security domain.
@@ -121,10 +127,10 @@ func (s *searcher) FindSchedulerCluster(ctx context.Context, schedulerClusters [
 	switch len(clusters) {
 	case 0:
 		// If the security domain does not match, there is no cluster available
-		return model.SchedulerCluster{}, false
+		return model.SchedulerCluster{}, fmt.Errorf("security domain %s does not match", securityDomain)
 	case 1:
 		// If only one cluster matches the security domain, return the cluster directly
-		return clusters[0], true
+		return clusters[0], nil
 	default:
 		// If there are multiple clusters matching the security domain,
 		// select the schuelder cluster with a higher score
@@ -143,7 +149,7 @@ func (s *searcher) FindSchedulerCluster(ctx context.Context, schedulerClusters [
 				result = cluster
 			}
 		}
-		return result, true
+		return result, nil
 	}
 }
 
diff --git a/manager/service/service_grpc.go b/manager/service/service_grpc.go
index a52f6cc2..047ecc8d 100644
--- a/manager/service/service_grpc.go
+++ b/manager/service/service_grpc.go
@@ -385,9 +385,9 @@ func (s *GRPC) ListSchedulers(ctx context.Context, req *manager.ListSchedulersRe
 
 	// Search optimal scheduler cluster
 	log.Infof("list scheduler clusters %+v with hostInfo %+v", schedulerClusters, req.HostInfo)
-	schedulerCluster, ok := s.searcher.FindSchedulerCluster(ctx, schedulerClusters, req)
-	if !ok {
-		log.Errorf("can not matching scheduler cluster")
+	schedulerCluster, err := s.searcher.FindSchedulerCluster(ctx, schedulerClusters, req)
+	if err != nil {
+		log.Errorf("can not matching scheduler cluster %v", err)
 		return nil, status.Error(codes.NotFound, "scheduler cluster not found")
 	}
 	log.Infof("find matching scheduler cluster %v", schedulerCluster)


Test patch:
diff --git a/manager/searcher/searcher_test.go b/manager/searcher/searcher_test.go
index 71cfd5c7..ceff2b87 100644
--- a/manager/searcher/searcher_test.go
+++ b/manager/searcher/searcher_test.go
@@ -31,24 +31,53 @@ func TestSchedulerCluster(t *testing.T) {
 		name              string
 		schedulerClusters []model.SchedulerCluster
 		conditions        map[string]string
-		expect            func(t *testing.T, data model.SchedulerCluster, ok bool)
+		expect            func(t *testing.T, data model.SchedulerCluster, err error)
 	}{
 		{
 			name:              "conditions is empty",
 			schedulerClusters: []model.SchedulerCluster{{Name: "foo"}},
 			conditions:        map[string]string{},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
-				assert.Equal(ok, false)
+				assert.EqualError(err, "empty conditions")
 			},
 		},
 		{
 			name:              "scheduler clusters is empty",
 			schedulerClusters: []model.SchedulerCluster{},
 			conditions:        map[string]string{"location": "foo"},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
-				assert.Equal(ok, false)
+				assert.EqualError(err, "empty scheduler clusters")
+			},
+		},
+		{
+			name: "security_domain does not match",
+			schedulerClusters: []model.SchedulerCluster{
+				{
+					Name: "foo",
+					SecurityGroup: model.SecurityGroup{
+						SecurityRules: []model.SecurityRule{
+							{
+								Domain: "domain-2",
+							},
+						},
+					},
+					Schedulers: []model.Scheduler{
+						{
+							HostName: "foo",
+							State:    "active",
+						},
+					},
+				},
+				{
+					Name: "bar",
+				},
+			},
+			conditions: map[string]string{"security_domain": "domain-1"},
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
+				assert := assert.New(t)
+				assert.EqualError(err, "security domain domain-1 does not match")
 			},
 		},
 		{
@@ -75,10 +104,10 @@ func TestSchedulerCluster(t *testing.T) {
 				},
 			},
 			conditions: map[string]string{"security_domain": "domain-1"},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
 				assert.Equal(data.Name, "foo")
-				assert.Equal(ok, true)
+				assert.NoError(err)
 			},
 		},
 		{
@@ -107,10 +136,10 @@ func TestSchedulerCluster(t *testing.T) {
 				},
 			},
 			conditions: map[string]string{"location": "location-1"},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
 				assert.Equal(data.Name, "foo")
-				assert.Equal(ok, true)
+				assert.NoError(err)
 			},
 		},
 		{
@@ -139,10 +168,10 @@ func TestSchedulerCluster(t *testing.T) {
 				},
 			},
 			conditions: map[string]string{"idc": "idc-1"},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
 				assert.Equal(data.Name, "foo")
-				assert.Equal(ok, true)
+				assert.NoError(err)
 			},
 		},
 		{
@@ -171,10 +200,10 @@ func TestSchedulerCluster(t *testing.T) {
 				},
 			},
 			conditions: map[string]string{"net_topology": "net-topology-1"},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
 				assert.Equal(data.Name, "foo")
-				assert.Equal(ok, true)
+				assert.NoError(err)
 			},
 		},
 		{
@@ -207,10 +236,10 @@ func TestSchedulerCluster(t *testing.T) {
 				"location": "location-1",
 				"idc":      "idc-1",
 			},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
 				assert.Equal(data.Name, "foo")
-				assert.Equal(ok, true)
+				assert.NoError(err)
 			},
 		},
 		{
@@ -249,10 +278,10 @@ func TestSchedulerCluster(t *testing.T) {
 				"security_domain": "domain-1",
 				"location":        "location-1",
 			},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
 				assert.Equal(data.Name, "foo")
-				assert.Equal(ok, true)
+				assert.NoError(err)
 			},
 		},
 		{
@@ -291,10 +320,10 @@ func TestSchedulerCluster(t *testing.T) {
 				"security_domain": "domain-1",
 				"idc":             "idc-1",
 			},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
 				assert.Equal(data.Name, "foo")
-				assert.Equal(ok, true)
+				assert.NoError(err)
 			},
 		},
 		{
@@ -335,10 +364,10 @@ func TestSchedulerCluster(t *testing.T) {
 				"idc":             "idc-1",
 				"location":        "location-1",
 			},
-			expect: func(t *testing.T, data model.SchedulerCluster, ok bool) {
+			expect: func(t *testing.T, data model.SchedulerCluster, err error) {
 				assert := assert.New(t)
 				assert.Equal(data.Name, "foo")
-				assert.Equal(ok, true)
+				assert.NoError(err)
 			},
 		},
 	}
diff --git a/manager/searcher/testdata/main.go b/manager/searcher/testdata/main.go
index 1bb5d373..7240adee 100644
--- a/manager/searcher/testdata/main.go
+++ b/manager/searcher/testdata/main.go
@@ -41,8 +41,8 @@ func main() {
 		os.Exit(1)
 	}
 
-	cluster, ok := s.FindSchedulerCluster(context.Background(), []model.SchedulerCluster{}, &manager.ListSchedulersRequest{})
-	if !ok {
+	cluster, err := s.FindSchedulerCluster(context.Background(), []model.SchedulerCluster{}, &manager.ListSchedulersRequest{})
+	if err != nil {
 		fmt.Println("scheduler cluster not found")
 		os.Exit(1)
 	}
diff --git a/manager/searcher/testdata/plugin/searcher.go b/manager/searcher/testdata/plugin/searcher.go
index c28d90e0..2f9b581f 100644
--- a/manager/searcher/testdata/plugin/searcher.go
+++ b/manager/searcher/testdata/plugin/searcher.go
@@ -25,8 +25,8 @@ import (
 
 type searcher struct{}
 
-func (s *searcher) FindSchedulerCluster(ctx context.Context, schedulerClusters []model.SchedulerCluster, client *manager.ListSchedulersRequest) (model.SchedulerCluster, bool) {
-	return model.SchedulerCluster{Name: "foo"}, true
+func (s *searcher) FindSchedulerCluster(ctx context.Context, schedulerClusters []model.SchedulerCluster, client *manager.ListSchedulersRequest) (model.SchedulerCluster, error) {
+	return model.SchedulerCluster{Name: "foo"}, nil
 }
 
 func DragonflyPluginInit(option map[string]string) (interface{}, map[string]string, error) {