Change:
From shippable, I noticed there are several failed cases, for example, E0413 17:34:38. ] watch of *api.Pod ended with: Stop requested --- FAIL: Example (0.61s) got: want: a-hello b-controller c-framework FAIL coverage: 85.9% of statements FAIL 7.652s cc/
another example:
ah-- this is a different thing. I will fix this, too.
I'm seeing this from an unrelated change
Yeah I think that's the one I expected to see.

Discussion:
fifo := cache.NewDeltaFIFO(cache.MetaNamespaceKeyFunc, nil, downstream) // Let's do threadsafe output to get predictable test results. <del> outputSetLock := sync.Mutex{} outputSet := util.StringSet{} </del> <ins> deletionCounter := make(chan string, 1000) </ins> cfg := &framework.Config{ Queue:            fifo,

return err } <ins> // Delete this object. </ins> source.Delete(newest.Object.(runtime.Object)) } else { // Update our downstream store.

return err } <del> // Record some output. outputSetLock.Lock() defer outputSetLock.Unlock() outputSet.Insert(key) </del> <ins> // Report this deletion. deletionCounter <- key </ins> } return nil },

// Create the controller and run it until we close stop. stop := make(chan struct{}) <ins> defer close(stop) </ins> go framework.New(cfg).Run(stop) // Let's add a few objects to the source. <del> for _, name := range []string{"a-hello", "b-controller", "c-framework"} { </del> <ins> testIDs := []string{"a-hello", "b-controller", "c-framework"} for _, name := range testIDs { </ins> // Note that these pods are not valid-- the fake source doesn't // call validation or anything. source.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: name}}) } // Let's wait for the controller to process the things we just added. <del> time.Sleep(500 * time.Millisecond) close(stop) </del> <ins> outputSet := util.StringSet{} for i := 0; i < len(testIDs); i++ { outputSet.Insert(<-deletionCounter) } </ins> <del> outputSetLock.Lock() </del> for _, key := range outputSet.List() { fmt.Println(key) }

source := framework.NewFakeControllerSource() // Let's do threadsafe output to get predictable test results. <del> outputSetLock := sync.Mutex{} outputSet := util.StringSet{} </del> <ins> deletionCounter := make(chan string, 1000) </ins> // Make a controller that immediately deletes anything added to it, and // logs anything deleted.

key = "oops something went wrong with the key" } <del> // Record some output when items are deleted. outputSetLock.Lock() defer outputSetLock.Unlock() outputSet.Insert(key) </del> <ins> // Report this deletion. deletionCounter <- key </ins> }, }, ) // Run the controller and run it until we close stop. stop := make(chan struct{}) <ins> defer close(stop) </ins> go controller.Run(stop) // Let's add a few objects to the source. <del> for _, name := range []string{"a-hello", "b-controller", "c-framework"} { </del> <ins> testIDs := []string{"a-hello", "b-controller", "c-framework"} for _, name := range testIDs { </ins> // Note that these pods are not valid-- the fake source doesn't <del> // call validation or perform any other checking. </del> <ins> // call validation or anything. </ins> source.Add(&api.Pod{ObjectMeta: api.ObjectMeta{Name: name}}) } // Let's wait for the controller to process the things we just added. <del> time.Sleep(500 * time.Millisecond) close(stop) </del> <ins> outputSet := util.StringSet{} for i := 0; i < len(testIDs); i++ { outputSet.Insert(<-deletionCounter) } </ins> <del> outputSetLock.Lock() </del> for _, key := range outputSet.List() { fmt.Println(key) }