Skip to content
This repository has been archived by the owner on May 6, 2021. It is now read-only.

Issue #143 Check the DELETED event on Watch Builds #276

Closed

Conversation

kishansagathiya
Copy link
Member

Currently we look at Object.Status.Phase to check the status of build.
This approach works, except for DELETED event. OpenShift would show the
previous phase on deleting, giving us a wrong impression of build
status.
Check for o.Type as well.

After this change, if we reset the environment, we won't see any active builds as well used to see earlier (OK Tested Locally)
but the previous build of the user will still be shown in the done build, which I think is appropriate, so no need to change that.

Fixed #143

@alien-ike
Copy link

alien-ike commented Sep 27, 2018

Ike Plugins (test-keeper)

Thank you @kishansagathiya for this contribution!

It seems that this PR already contains some added or changed tests. Good job!

For more information please head over to official documentation. You can find there how to configure the plugin.

@@ -89,7 +89,7 @@ func (c *controllerImpl) HandleBuild(o model.Object) error {
sendUserToIdler := false
userIdler := c.userIdlerForNamespace(ns)
user := userIdler.GetUser()
if c.isActive(&o.Object) {
if c.isActive(&o.Object) && o.Type != "DELETED" {
Copy link
Contributor

Choose a reason for hiding this comment

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

shoudn't we change isActive instead to return false if o.Type == "DELETED" ?

@@ -52,6 +52,10 @@ func Test_handle_build(t *testing.T) {

err := controller.HandleBuild(obj)
assert.NoError(t, err)

obj.Type = "DELETED"
Copy link
Contributor

Choose a reason for hiding this comment

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

can you add a test for the case where the type isn't "DELETED" ?

Copy link
Member Author

Choose a reason for hiding this comment

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

There is already one test above that is not DELETED, but let me add tests for all WatchEvents https://github.com/kubernetes/kubernetes/blob/932e657d5d0e98624fb9907ea34a55ac604253d3/pkg/watch/json/types.go#L35

Copy link
Member Author

Choose a reason for hiding this comment

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

Added extra WatchEvent types. but whatever tests that we have don't seem to do much. Do you want me to add some better tests?
(sorry for rebase. I made a mistake while using git. Had to do it.)

Copy link
Contributor

Choose a reason for hiding this comment

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

Do you want me to add some better tests?

Yes, please. the current tests do not assert changes to controllers internals i.e. other than testing that it does not result in an error. Ideally you would want tests to invoke the method and assert that the internal state changes are as expected.

@kishansagathiya
Copy link
Member Author

upstream issue filed for this openshift/origin#21112

@@ -23,3 +25,8 @@ func Contains(list []string, s string) bool {
}
return false
}

// RandomString returns random string of length len
func RandomString(len int) string {
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Member Author

Choose a reason for hiding this comment

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

I don't see how that is better than what is proposed.

Copy link
Contributor

Choose a reason for hiding this comment

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

in general i would say it's better to use standard function from the go std package than rolling your own,

Copy link
Member Author

@kishansagathiya kishansagathiya Oct 12, 2018

Choose a reason for hiding this comment

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

I will get rid of this function. But still using the same body. strconv.Itoa(rand.Intn(1000))(go std package) is still better than rand.Read(p []byte). Why? https://syslog.ravelin.com/byte-vs-string-in-go-d645b67ca7ff (you would mostly be aware of contents in that link, just keeping there for reference)

@chmouel May be I am guilty of premature optimization here 😜

Copy link
Member Author

Choose a reason for hiding this comment

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

func (c *controllerImpl) isActive(b *model.Build) bool {
return model.Phases[b.Status.Phase] == 1
func isActive(b model.Object) bool {
return model.Phases[b.Object.Status.Phase] == 1 && b.Type != "DELETED"
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you know what different values can 'b.Type` hold?

Copy link
Contributor

Choose a reason for hiding this comment

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

https://github.com/kubernetes/apimachinery/blob/76721d167b7088b203cf9873c616b0cfec5c77bb/pkg/watch/watch.go#L44

2 things

  1. there are other values as well. I guess error should ignored as well or rather only look at Added, Modfied

  2. can we just the enum defined there instead of the "DELETED" magic word?

Copy link
Member Author

@kishansagathiya kishansagathiya Oct 10, 2018

Choose a reason for hiding this comment

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

Yes, there are other types. You should be able to find this link and all the types used in the proposed change.
Yes, we can check for other types, but why? The function is sufficient to check what we need. Checking those types add no value, you would still need to check for the phase.

testWithStateChange(t, obj)
}

func testWithStateChange(t *testing.T, obj model.Object) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Good stuff!

@@ -89,7 +89,7 @@ func (c *controllerImpl) HandleBuild(o model.Object) error {
sendUserToIdler := false
userIdler := c.userIdlerForNamespace(ns)
user := userIdler.GetUser()
if c.isActive(&o.Object) {
if c.isActive(&o.Object) && o.Type != "DELETED" {
Copy link
Contributor

Choose a reason for hiding this comment

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

this sound okay to me althoiugh it would be nice to have a comment explaining what you are saying in the commit message.

If that's the default behaviour of k8/openshfit can we have a bug report on openshift origin issues because I don't think it should behave like this,

@@ -14,6 +14,7 @@ import (
"github.com/fabric8-services/fabric8-jenkins-idler/internal/tenant"
"github.com/fabric8-services/fabric8-jenkins-idler/internal/toggles"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/watch"
Copy link
Contributor

Choose a reason for hiding this comment

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

I believe that If you aAre you adding this you need to modify the gopkg.toml too, or regenerate the lock file

@@ -138,7 +137,7 @@ func (c *controllerImpl) HandleBuild(o model.Object) error {
// So we need to clean up the Active build ref.
if user.ActiveBuild.Metadata.Name == user.DoneBuild.Metadata.Name {
log.Infof("Active and Done builds are the same (%s), cleaning active builds", user.ActiveBuild.Metadata.Name)
user.ActiveBuild = model.Build{Status: model.Status{Phase: "New"}}
user.ActiveBuild = model.Build{}
Copy link
Contributor

Choose a reason for hiding this comment

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

is it implied?

Copy link
Member Author

Choose a reason for hiding this comment

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

So, on finding the current build to be done, it would move it to done, but it would also mark a new active build with status New, without checking whether there actually is a new build or not.
That seemed wrong to me. It should instead use an empty Build object.

@@ -23,3 +25,8 @@ func Contains(list []string, s string) bool {
}
return false
}

// RandomString returns random string of length len
func RandomString(len int) string {
Copy link
Contributor

Choose a reason for hiding this comment

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

in general i would say it's better to use standard function from the go std package than rolling your own,

packages = ["."]
revision = "298182f68c66c05229eb03ac171abe6e309ee79a"
version = "v1.0.3"

Copy link
Member Author

Choose a reason for hiding this comment

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

@chmouel This gets generated with dep ensure. It not being used in idler, but it is one of the dependencies in k8s.io/apimachinery. So, I think that's why it is here.

@kishansagathiya
Copy link
Member Author

@chmouel @sthaha Rebased against master

Currently we look at Object.Status.Phase to check the status of build.
This approach works, except for DELETED event. OpenShift would show the
previous phase on deleting, giving us a wrong impression of build
status.
Check for o.Type as well.

Added tests for HandleBuilds

No such phase as `Finished`, add `Error` phase

Some method could just be functions
Added dependencies and regerated lock file
@hrishin hrishin added this to the 159/L milestone Dec 21, 2018
@hrishin hrishin modified the milestones: 159/L, 160/L Jan 7, 2019
@kishansagathiya kishansagathiya closed this by deleting the head repository Dec 17, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants