clh: add Client Interface and bootVM test

Add interface with the same methods of client,
this will help to decouple the implementation
and help use to do mock testing.

Add Mock client and add bootVM unit test

Signed-off-by: Jose Carlos Venegas Munoz <jose.carlos.venegas.munoz@intel.com>
This commit is contained in:
Jose Carlos Venegas Munoz 2019-12-13 22:42:06 +00:00
parent a198efcf1d
commit 8a439eab9d
2 changed files with 63 additions and 5 deletions

View File

@ -44,6 +44,11 @@ const (
clhReady clhReady
) )
const (
clhStateCreated = "Created"
clhStateRunning = "Running"
)
const ( const (
// Values are mandatory by http API // Values are mandatory by http API
// Values based on: // Values based on:
@ -63,6 +68,19 @@ const (
maxClhVcpus = uint32(64) maxClhVcpus = uint32(64)
) )
// Interface that hides the implementation of openAPI client
// If the client changes its methods, this interface should do it as well,
// The main purpose is to hide the client in an interface to allow mock testing.
// This is an interface that has to match with OpenAPI CLH client
type clhClient interface {
VmmPingGet(ctx context.Context) (chclient.VmmPingResponse, *http.Response, error)
ShutdownVMM(ctx context.Context) (*http.Response, error)
CreateVM(ctx context.Context, vmConfig chclient.VmConfig) (*http.Response, error)
// No lint: golint suggest to rename to VMInfoGet.
VmInfoGet(ctx context.Context) (chclient.VmInfo, *http.Response, error) //nolint:golint
BootVM(ctx context.Context) (*http.Response, error)
}
type CloudHypervisorVersion struct { type CloudHypervisorVersion struct {
Major int Major int
Minor int Minor int
@ -91,7 +109,7 @@ type cloudHypervisor struct {
store *store.VCStore store *store.VCStore
config HypervisorConfig config HypervisorConfig
ctx context.Context ctx context.Context
APIClient *chclient.DefaultApiService APIClient clhClient
version CloudHypervisorVersion version CloudHypervisorVersion
vmconfig chclient.VmConfig vmconfig chclient.VmConfig
cmdOutput bytes.Buffer cmdOutput bytes.Buffer
@ -927,7 +945,7 @@ func (clh *cloudHypervisor) isClhRunning(timeout uint) (bool, error) {
} }
func (clh *cloudHypervisor) client() *chclient.DefaultApiService { func (clh *cloudHypervisor) client() clhClient {
if clh.APIClient == nil { if clh.APIClient == nil {
clh.APIClient = clh.newAPIClient() clh.APIClient = clh.newAPIClient()
} }
@ -996,7 +1014,7 @@ func (clh *cloudHypervisor) bootVM(ctx context.Context) error {
clh.Logger().Debugf("VM state after create: %#v", info) clh.Logger().Debugf("VM state after create: %#v", info)
if info.State != "Created" { if info.State != clhStateCreated {
return fmt.Errorf("VM state is not 'Created' after 'CreateVM'") return fmt.Errorf("VM state is not 'Created' after 'CreateVM'")
} }
@ -1015,7 +1033,7 @@ func (clh *cloudHypervisor) bootVM(ctx context.Context) error {
clh.Logger().Debugf("VM state after boot: %#v", info) clh.Logger().Debugf("VM state after boot: %#v", info)
if info.State != "Running" { if info.State != clhStateRunning {
return fmt.Errorf("VM state is not 'Running' after 'BootVM'") return fmt.Errorf("VM state is not 'Running' after 'BootVM'")
} }

View File

@ -6,10 +6,41 @@
package virtcontainers package virtcontainers
import ( import (
"github.com/stretchr/testify/assert" "context"
"net/http"
"testing" "testing"
chclient "github.com/kata-containers/runtime/virtcontainers/pkg/cloud-hypervisor/client"
"github.com/stretchr/testify/assert"
) )
type clhClientMock struct {
vmInfo chclient.VmInfo
}
func (c *clhClientMock) VmmPingGet(ctx context.Context) (chclient.VmmPingResponse, *http.Response, error) {
return chclient.VmmPingResponse{}, nil, nil
}
func (c *clhClientMock) ShutdownVMM(ctx context.Context) (*http.Response, error) {
return nil, nil
}
func (c *clhClientMock) CreateVM(ctx context.Context, vmConfig chclient.VmConfig) (*http.Response, error) {
c.vmInfo.State = clhStateCreated
return nil, nil
}
//nolint:golint
func (c *clhClientMock) VmInfoGet(ctx context.Context) (chclient.VmInfo, *http.Response, error) {
return c.vmInfo, nil, nil
}
func (c *clhClientMock) BootVM(ctx context.Context) (*http.Response, error) {
c.vmInfo.State = clhStateRunning
return nil, nil
}
func TestCloudHypervisorAddVSock(t *testing.T) { func TestCloudHypervisorAddVSock(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
clh := cloudHypervisor{} clh := cloudHypervisor{}
@ -22,3 +53,12 @@ func TestCloudHypervisorAddVSock(t *testing.T) {
assert.Equal(clh.vmconfig.Vsock[1].Cid, int64(2)) assert.Equal(clh.vmconfig.Vsock[1].Cid, int64(2))
assert.Equal(clh.vmconfig.Vsock[1].Sock, "path2") assert.Equal(clh.vmconfig.Vsock[1].Sock, "path2")
} }
func TestCloudHypervisorBootVM(t *testing.T) {
clh := &cloudHypervisor{}
clh.APIClient = &clhClientMock{}
var ctx context.Context
if err := clh.bootVM(ctx); err != nil {
t.Errorf("cloudHypervisor.bootVM() error = %v", err)
}
}