diff --git a/store/etcdv3/helper.go b/store/etcdv3/helper.go index be6b9fede..91f2083f4 100644 --- a/store/etcdv3/helper.go +++ b/store/etcdv3/helper.go @@ -5,10 +5,13 @@ import ( "os" "strings" + enginetypes "github.com/docker/docker/api/types" engineapi "github.com/docker/docker/client" "github.com/docker/go-connections/tlsconfig" + enginemock "github.com/projecteru2/core/3rdmocks" "github.com/projecteru2/core/types" log "github.com/sirupsen/logrus" + "github.com/stretchr/testify/mock" ) func dumpFromString(ca, cert, key *os.File, caStr, certStr, keyStr string) error { @@ -29,6 +32,13 @@ func dumpFromString(ca, cert, key *os.File, caStr, certStr, keyStr string) error return nil } +func makeMockClient() (engineapi.APIClient, error) { + engine := &enginemock.APIClient{} + engine.On("Info", mock.AnythingOfType("*context.emptyCtx")).Return( + enginetypes.Info{NCPU: 1, MemTotal: types.GByte + 100}, nil) + return engine, nil +} + func makeRawClient(endpoint, apiversion string) (engineapi.APIClient, error) { return engineapi.NewClient(endpoint, apiversion, nil, nil) } diff --git a/store/etcdv3/mercury.go b/store/etcdv3/mercury.go index ab3d7eb9f..4d5045d89 100644 --- a/store/etcdv3/mercury.go +++ b/store/etcdv3/mercury.go @@ -18,6 +18,7 @@ import ( const ( nodeTCPPrefixKey = "tcp://" nodeSockPrefixKey = "unix://" + nodeMockPrefixKey = "mock://" podInfoKey = "/pod/info/%s" podNodesKey = "/pod/nodes/%s" // /pod/nodes/pod1/node1 /pod/nodes/pod1/node2 diff --git a/store/etcdv3/node.go b/store/etcdv3/node.go index b25ad3379..7c18bd4e9 100644 --- a/store/etcdv3/node.go +++ b/store/etcdv3/node.go @@ -20,7 +20,9 @@ import ( // storage path in etcd is `/pod/nodes/:podname/:nodename` // node->pod path in etcd is `/node/pod/:nodename` func (m *Mercury) AddNode(ctx context.Context, name, endpoint, podname, ca, cert, key string, cpu, share int, memory int64, labels map[string]string) (*types.Node, error) { - if !strings.HasPrefix(endpoint, nodeTCPPrefixKey) && !strings.HasPrefix(endpoint, nodeSockPrefixKey) { + if !strings.HasPrefix(endpoint, nodeTCPPrefixKey) && + !strings.HasPrefix(endpoint, nodeSockPrefixKey) && + !strings.HasPrefix(endpoint, nodeMockPrefixKey) { return nil, types.NewDetailedErr(types.ErrNodeFormat, fmt.Sprintf("endpoint must starts with %s or %s %q", nodeTCPPrefixKey, nodeSockPrefixKey, endpoint)) @@ -315,6 +317,9 @@ func (m *Mercury) makeDockerClient(ctx context.Context, podname, nodename, endpo } func (m *Mercury) doMakeDockerClient(ctx context.Context, nodename, endpoint, ca, cert, key string) (engineapi.APIClient, error) { + if strings.HasPrefix(endpoint, nodeMockPrefixKey) { + return makeMockClient() + } if m.config.Docker.CertPath == "" || (ca == "" || cert == "" || key == "") { return makeRawClient(endpoint, m.config.Docker.APIVersion) } diff --git a/store/etcdv3/node_test.go b/store/etcdv3/node_test.go index 837d84796..485b80693 100644 --- a/store/etcdv3/node_test.go +++ b/store/etcdv3/node_test.go @@ -15,6 +15,7 @@ func TestNode(t *testing.T) { m := NewMercury(t, etcd.RandClient()) ctx := context.Background() nodename := "testnode" + nodename2 := "testnode2" endpoint := "tcp://127.0.0.1:2376" podname := "testpod" _, err := m.AddPod(ctx, podname, "CPU", "") @@ -22,24 +23,35 @@ func TestNode(t *testing.T) { cpu := 1 share := 100 memory := int64(100) + m.config.Scheduler.ShareBase = 100 labels := map[string]string{"test": "1"} + // wrong endpoint _, err = m.AddNode(ctx, nodename, "abc", podname, "", "", "", cpu, share, memory, labels) assert.Error(t, err) + // wrong because engine not mocked _, err = m.AddNode(ctx, nodename, endpoint, podname, "", "", "", cpu, share, memory, labels) - // wrong endpoint assert.Error(t, err) - // TODO there is no way to mock docker client, may be run a docker to do it. - // So we test doAddNode - node, err := m.doAddNode(ctx, nodename, endpoint, podname, "", "", "", cpu, share, memory, labels) + + endpoint = "mock://mockdocker" + // AddNode + node, err := m.AddNode(ctx, nodename, endpoint, podname, "", "", "", cpu, share, memory, labels) assert.NoError(t, err) assert.Equal(t, node.Name, nodename) assert.Equal(t, node.CPU["0"], 100) - _, err = m.doAddNode(ctx, nodename, endpoint, podname, "", "", "", cpu, share, memory, labels) + // Addnode again will failed + _, err = m.AddNode(ctx, nodename, endpoint, podname, "", "", "", cpu, share, memory, labels) assert.Error(t, err) + // Check etcd has node data key := fmt.Sprintf(nodeInfoKey, podname, nodename) ev, err := m.GetOne(ctx, key) assert.NoError(t, err) + // AddNode with mocked engine and default value + node3, err := m.AddNode(ctx, nodename2, endpoint, podname, "", "", "", 0, 0, 0, labels) + assert.NoError(t, err) + assert.Equal(t, node3.CPU["0"], 100) + assert.Equal(t, len(node3.CPU), 1) + assert.Equal(t, node3.MemCap, int64(100)) // GetNode _, err = m.GetNode(ctx, "nil", nodename) assert.Error(t, err) @@ -65,14 +77,14 @@ func TestNode(t *testing.T) { assert.Equal(t, len(nodes), 0) nodes, err = m.GetNodesByPod(ctx, podname) assert.NoError(t, err) - assert.Equal(t, len(nodes), 1) + assert.Equal(t, len(nodes), 2) savedNode = nodes[0] assert.Equal(t, savedNode.Name, node.Name) assert.Equal(t, savedNode.Endpoint, node.Endpoint) // GetAllNodes nodes, err = m.GetAllNodes(ctx) assert.NoError(t, err) - assert.Equal(t, len(nodes), 1) + assert.Equal(t, len(nodes), 2) savedNode = nodes[0] assert.Equal(t, savedNode.Name, node.Name) assert.Equal(t, savedNode.Endpoint, node.Endpoint) @@ -165,11 +177,11 @@ Dl0aR0+ZbHq5hv5feDdpeKxMxKkKnCu1cl47gKAyFet5nvK7htBUk9aIph8zDBZj cmag5uyTcIogsd5GyOg06jDD1aCqz3FbTX1KQLeSFQUCTT+m100rohrc2rW5m4Al RdCPRPt513WozkJZZAjUSP2U -----END PRIVATE KEY-----` - nodename2 := "n2" - node2, err := m.doAddNode(ctx, nodename2, endpoint, podname, ca, cert, certkey, cpu, share, memory, labels) + nodename3 := "nodename3" + node2, err := m.AddNode(ctx, nodename3, endpoint, podname, ca, cert, certkey, cpu, share, memory, labels) assert.NoError(t, err) m.config.Docker.CertPath = "/tmp" - _, err = m.makeDockerClient(ctx, podname, nodename2, endpoint, true) + _, err = m.makeDockerClient(ctx, podname, nodename3, endpoint, true) assert.NoError(t, err) // DeleteNode m.DeleteNode(ctx, node2)