Skip to content

Commit

Permalink
Unit tests for watch/migrations
Browse files Browse the repository at this point in the history
  • Loading branch information
admiyo committed Mar 8, 2017
1 parent 75ad608 commit 1a6aa0b
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 3 deletions.
3 changes: 2 additions & 1 deletion pkg/virt-controller/services/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/onsi/gomega/ghttp"
"k8s.io/client-go/kubernetes"
corev1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/util/uuid"
"k8s.io/client-go/rest"
"kubevirt.io/kubevirt/pkg/api/v1"
"kubevirt.io/kubevirt/pkg/kubecli"
Expand All @@ -21,7 +22,6 @@ var _ = Describe("VM", func() {
var server *ghttp.Server
var restClient *rest.RESTClient


BeforeEach(func() {
var g inject.Graph

Expand Down Expand Up @@ -54,6 +54,7 @@ var _ = Describe("VM", func() {
expected_migration.Status.Phase = v1.MigrationInProgress

vm.ObjectMeta.UID = "testUID"
vm.ObjectMeta.SetUID(uuid.NewUUID())

pod := corev1.Pod{}

Expand Down
8 changes: 6 additions & 2 deletions pkg/virt-controller/watch/migration.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ import (

func NewMigrationController(migrationService services.VMService, recorder record.EventRecorder, restClient *rest.RESTClient) (cache.Store, *kubecli.Controller) {
lw := cache.NewListWatchFromClient(restClient, "migrations", kubeapi.NamespaceDefault, fields.Everything())
return NewMigrationControllerWithListWatch(migrationService, recorder, lw, restClient)
}

func NewMigrationControllerWithListWatch(migrationService services.VMService, _ record.EventRecorder, lw cache.ListerWatcher, restClient *rest.RESTClient) (cache.Store, *kubecli.Controller) {

queue := workqueue.NewRateLimitingQueue(workqueue.DefaultControllerRateLimiter())
return kubecli.NewController(lw, queue, &v1.Migration{}, func(store cache.Store, queue workqueue.RateLimitingInterface) bool {
Expand Down Expand Up @@ -106,8 +110,8 @@ func copyMigration(migration *v1.Migration) v1.Migration {

func StartMigrationTargetPod(v services.VMService, migration *v1.Migration) error {
precond.MustNotBeNil(migration)
precond.MustNotBeEmpty(migration.GetObjectMeta().GetName())
precond.MustNotBeEmpty(string(migration.GetObjectMeta().GetUID()))
precond.MustNotBeEmpty(migration.ObjectMeta.Name)
precond.MustNotBeEmpty(string(migration.ObjectMeta.UID))

vm, err := v.FetchVM(migration.Spec.MigratingVMName)
if err != nil {
Expand Down
132 changes: 132 additions & 0 deletions pkg/virt-controller/watch/migration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package watch

import (
"net/http"

"github.com/facebookgo/inject"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/ghttp"
"k8s.io/client-go/kubernetes"
clientv1 "k8s.io/client-go/pkg/api/v1"
"k8s.io/client-go/pkg/conversion"
"k8s.io/client-go/pkg/util/uuid"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/tools/cache/testing"
"kubevirt.io/kubevirt/pkg/api/v1"
"kubevirt.io/kubevirt/pkg/kubecli"
"kubevirt.io/kubevirt/pkg/logging"
"kubevirt.io/kubevirt/pkg/virt-controller/services"
)

var _ = Describe("Migration", func() {
var server *ghttp.Server
var stopChan chan struct{}
var migrationController *kubecli.Controller
var lw *framework.FakeControllerSource
var migrationCache cache.Store

var vmService services.VMService
var restClient *rest.RESTClient

logging.DefaultLogger().SetIOWriter(GinkgoWriter)

BeforeEach(func() {
var g inject.Graph
vmService = services.NewVMService()
server = ghttp.NewServer()
config := rest.Config{}
config.Host = server.URL()
clientSet, _ := kubernetes.NewForConfig(&config)
templateService, _ := services.NewTemplateService("kubevirt/virt-launcher")
restClient, _ = kubecli.GetRESTClientFromFlags(server.URL(), "")

g.Provide(
&inject.Object{Value: restClient},
&inject.Object{Value: clientSet},
&inject.Object{Value: vmService},
&inject.Object{Value: templateService},
)
g.Populate()

stopChan = make(chan struct{})
lw = framework.NewFakeControllerSource()
migrationCache = cache.NewIndexer(cache.DeletionHandlingMetaNamespaceKeyFunc, nil)

_, migrationController = NewMigrationControllerWithListWatch(vmService, nil, lw, restClient)

// Start the controller
migrationController.StartInformer(stopChan)
go migrationController.Run(1, stopChan)
})

Context("Running Migration target Pod for a running VM given", func() {
It("should update the VM with the migration target node of the running Pod", func(done Done) {

// Create a VM which is being scheduled
vm := v1.NewMinimalVM("testvm")
vm.Status.Phase = v1.Running
vm.ObjectMeta.SetUID(uuid.NewUUID())

migration := v1.NewMinimalMigration(vm.ObjectMeta.Name+"-migration", vm.ObjectMeta.Name)
migration.ObjectMeta.SetUID(uuid.NewUUID())

// Create the expected VM after the update
obj, err := conversion.NewCloner().DeepCopy(vm)
Expect(err).ToNot(HaveOccurred())

// Create a target Pod for the VM
temlateService, err := services.NewTemplateService("whatever")
Expect(err).ToNot(HaveOccurred())
pod, err := temlateService.RenderLaunchManifest(vm)
Expect(err).ToNot(HaveOccurred())
pod.Spec.NodeName = "mynode"
pod.Status.Phase = clientv1.PodSucceeded
pod.Labels[v1.DomainLabel] = migration.ObjectMeta.Name

podList := clientv1.PodList{}
podList.Items = []clientv1.Pod{*pod}

expectedVM := obj.(*v1.VM)
expectedVM.Status.Phase = v1.Running
expectedVM.Status.MigrationNodeName = pod.Spec.NodeName

// Register the expected REST call
server.AppendHandlers(
ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", "/apis/kubevirt.io/v1alpha1/namespaces/default/vms/testvm"),
ghttp.RespondWithJSONEncoded(http.StatusOK, expectedVM),
),
ghttp.CombineHandlers(
ghttp.VerifyRequest("GET", "/api/v1/namespaces/default/pods"),
ghttp.RespondWithJSONEncoded(http.StatusOK, podList),
),
ghttp.CombineHandlers(
ghttp.VerifyRequest("POST", "/api/v1/namespaces/default/pods"),
ghttp.RespondWithJSONEncoded(http.StatusOK, pod),
),
ghttp.CombineHandlers(
ghttp.VerifyRequest("PUT", "/apis/kubevirt.io/v1alpha1/namespaces/default/migrations/testvm-migration"),
ghttp.RespondWithJSONEncoded(http.StatusOK, migration),
),
)

// Tell the controller that there is a new Migration
lw.Add(migration)

// Wait until we have processed the added item
migrationController.WaitForSync(stopChan)
migrationController.ShutDownQueue()
migrationController.WaitUntilDone()

Expect(len(server.ReceivedRequests())).To(Equal(4))
close(done)
}, 10)
})

AfterEach(func() {
close(stopChan)
server.Close()
})
})

0 comments on commit 1a6aa0b

Please sign in to comment.