Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove controller from unit tests #164

Merged
merged 8 commits into from
Mar 30, 2017

Conversation

admiyo
Copy link
Contributor

@admiyo admiyo commented Mar 23, 2017

No description provided.

@admiyo admiyo force-pushed the remove-controller-from-unit-tests branch from ce89023 to 6d17b9c Compare March 23, 2017 15:30
@@ -15,7 +15,7 @@ import (
"kubevirt.io/kubevirt/pkg/virt-controller/services"
)

func migrationJobSelector() kubeapi.ListOptions {
func MigrationJobSelector() kubeapi.ListOptions {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the rationale behind making this a public function? It's fine to do that, but the "panic" instruction in this code should instead return an error if this is to be a general purpose function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Returned to private naming

if err != nil {
logger.Error().Reason(err).Msg("updating migration state failed")
logger.Error().Reason(err).Msg("creating am migration target node failed")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo

@admiyo admiyo force-pushed the remove-controller-from-unit-tests branch 2 times, most recently from 371b3d5 to c95ce1e Compare March 24, 2017 18:18
@admiyo
Copy link
Contributor Author

admiyo commented Mar 27, 2017

retest this please

@admiyo admiyo force-pushed the remove-controller-from-unit-tests branch from c95ce1e to e3f0293 Compare March 27, 2017 18:28
Copy link
Member

@stu-gott stu-gott left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of my comments are nitpicky. The most important one to look at is the mergeConstraints question.

. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"github.com/onsi/gomega/ghttp"
"k8s.io/client-go/kubernetes"
"net/http"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like your IDE decided to move this line

}
}
vm.Spec.NodeSelector = merged
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might want to run this line after the "if len(conflicts) > 0" block. This makes a side-effect change since VM was passed in by pointer, so we should check that there are no errors first.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, that should be after the check.

close(done)
}, 10)

It("should fail if confliciting VM and Migration have conflicting Node Selectors", func(done Done) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "confliciting"

queue.AddRateLimited(key)
} else if !vmExists || obj.(*v1.VM).GetObjectMeta().GetUID() != domain.GetObjectMeta().GetUID() {
obj, vmExists, _ := d.vmStore.GetByKey(key.(string))
// GetByKey cannot return an error, leading the error handling code
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: Technically this comment refers to non-existent code.

Copy link
Contributor Author

@admiyo admiyo Mar 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It explains why the err in the above line is ignored.

"kubevirt.io/kubevirt/pkg/logging"
. "kubevirt.io/kubevirt/pkg/virt-handler"
"kubevirt.io/kubevirt/pkg/virt-handler/virtwrap"
"time"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wrong import order

Consistently(vmQueue.Len).Should(Equal(0))
})

It("should create not requeue even if domain reference if it is not in the cache", func() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should not create?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dropped the "create"

close(done)
}, 10)

It("Should mark Migation failed if VM not running ", func(done Done) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: "Migation"


Expect(len(server.ReceivedRequests())).To(Equal(5))
Expect(len(server.ReceivedRequests())).To(Equal(7))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wish there were a better way to test this (I'm not saying there is). The number of API calls made by any given section of code is a good candidate for something likely to change--so this test could unexpectedly fail in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that is all right, since we have to mock this layer, there is no way around it. I would not like to have rest calls lying aroung which are not even used.

But: Instead of checking this explicitly I would add one check in the AfterEach section which makes sure that the amount of registered calls equals the amount of expected calls. The nwe can remove this line from the test itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, but there is no way to get a count of the registered handlers, so the logic here is as simple as we can get.

@@ -55,12 +50,9 @@ type JobDispatch struct {

func (jd *JobDispatch) Execute(store cache.Store, queue workqueue.RateLimitingInterface, key interface{}) {
// Fetch the latest Job state from cache
obj, exists, err := store.GetByKey(key.(string))
// Cannot return an error
obj, exists, _ := store.GetByKey(key.(string))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The controller loop has no idea which cache implementation is used, so I would say that it is not it's job to guess about the internals.

@@ -55,12 +50,9 @@ func (md *MigrationDispatch) Execute(store cache.Store, queue workqueue.RateLimi
}

// Fetch the latest Migration state from cache
obj, exists, err := store.GetByKey(key.(string))
// error is always nil
obj, exists, _ := store.GetByKey(key.(string))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I would expect the error although, the current used store does not throw one ...

}
}
vm.Spec.NodeSelector = merged
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, that should be after the check.

expectedMigration := obj.(*v1.Migration)
expectedMigration.Status.Phase = expectedStatus
expectedMigration.Kind = "Migration"
expectedMigration.APIVersion = "kubevirt.io/v1alpha1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting all these fields looks strange. I think it is better if you only explicitly set fields which are relevant for the test.

Self link, ... are not something we need to check here ...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are set by the calling code, and we need to confirm a match. Any other logic would be more complicated.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant is that you are copying the object anyway already. So you are overriding for the test unimportant fields with the value which it already contains (like self link, ...).

Since you are copying it already, just overriding the fields with the expected changes should do ...

Copy link
Member

@rmohr rmohr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The checks need a few cleanups:

  • On requeue we need to check for the history of the key too
  • We always have to check if the queue is empty after a call which should be successful

doExecute()

Expect(len(server.ReceivedRequests())).To(Equal(2))
Eventually(jobQueue.Len()).Should(Equal(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A check if we have a history of the key is missing: queue.NumRequeues(key) == 1

doExecute()

Expect(len(server.ReceivedRequests())).To(Equal(3))
Eventually(jobQueue.Len()).Should(Equal(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A check if we have a history of the key is missing

Expect(len(server.ReceivedRequests())).To(Equal(4))
Eventually(jobQueue.Len()).Should(Equal(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A check if we have a history of the key is missing

)

doExecute()
Expect(len(server.ReceivedRequests())).To(Equal(4))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you are not testing if the queue is now empty.

// Create the expected VM after the update
obj, err := conversion.NewCloner().DeepCopy(vm)
Expect(err).ToNot(HaveOccurred())
Expect(len(server.ReceivedRequests())).To(Equal(4))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to check if the queue is empty.

doExecute()

Expect(len(server.ReceivedRequests())).To(Equal(1))
Eventually(queue.Len()).Should(Equal(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expect

doExecute()

Expect(len(server.ReceivedRequests())).To(Equal(3))
Eventually(queue.Len()).Should(Equal(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expect

doExecute()

Expect(len(server.ReceivedRequests())).To(Equal(3))
Eventually(queue.Len()).Should(Equal(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expect

doExecute()

Expect(len(server.ReceivedRequests())).To(Equal(3))
Eventually(queue.Len()).Should(Equal(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expect

doExecute()

Expect(len(server.ReceivedRequests())).To(Equal(3))
Eventually(queue.Len()).Should(Equal(1))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expect

@rmohr
Copy link
Member

rmohr commented Mar 28, 2017

@admiyo one of the functional tests failed, could you check if there is something behind it?

@admiyo admiyo force-pushed the remove-controller-from-unit-tests branch from e3f0293 to 8fc7024 Compare March 28, 2017 15:35
@admiyo
Copy link
Contributor Author

admiyo commented Mar 28, 2017

That is just the rebase: have not addressed comments yet.

return
}
obj, exists, _ := indexer.GetByKey(key.(string))
// GetByKey can never return anything but nil for the error
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@admiyo , you could use your own store implementation (A store is an interface) which can throw an error, if that is your line of agrumentation. Every code in kubernetes itself is also taking this error into account.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a bug, then, in the library we are using.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why? There is an interface which says, return an error if there is one, but that does not mean that every implementation necessarily is written in a way that there can happen an error to report.

The most extreme examples: Think of an in memory map, which can't have an error when looking up a key. It is a valid implementation of a store and when accessed through the interface, you always return nil as an error. Now think of a file based store. When looking something there up, it can fail.

The interface is the contract I would want to implement. I don't think it is nice, to assume a concrete implementation behind an interface.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that, if I add it back in, we'll still be under the threshold for untestable code. Let's see.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of course this can be tested. create a cache class that throws an error.

@rmohr rmohr merged commit 0b7a627 into kubevirt:master Mar 30, 2017
@admiyo admiyo deleted the remove-controller-from-unit-tests branch April 7, 2017 17:17
kubevirt-bot pushed a commit to kubevirt-bot/kubevirt that referenced this pull request Nov 6, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants