From 8a8d69032038c8ae837eb59ed6f2cfa55ee1c0d7 Mon Sep 17 00:00:00 2001 From: Dongsu Park Date: Tue, 26 Jul 2016 16:54:41 +0200 Subject: [PATCH] agent: make TestUnitStatePublisher wait for each goroutine to finish TestUnitStatePublisherRunWithDelays() has not exactly initiated each service sequentially, but let it run in parallel. That's why the unit test sometimes fails with messages like: ``` --- FAIL: TestUnitStatePublisherRunWithDelays-2 (0.00 seconds) unit_state_test.go:626: bad published UnitStates: got []string{"0.service", "2.service", "4.service", "1.service", "3.service"}, want []string{"0.service", "1.service", "2.service", "3.service", "4.service"} unit_state_test.go:640: bad published UnitStates: got []string{"0.service", "2.service", "4.service", "1.service", "3.service"}, want []string{"0.service", "1.service", "2.service", "3.service", "4.service"} unit_state_test.go:658: bad UnitStates: got []string{"foo.service", "baz.service", "bar.service"}, want []string{"foo.service", "bar.service", "baz.service"} ``` To fix that, for each goroutine, check that the channel toPublish contains the expected unit name. Suggested by @jonboulle Fixes https://github.com/coreos/fleet/issues/1248 --- agent/unit_state_test.go | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/agent/unit_state_test.go b/agent/unit_state_test.go index 0a239c623..710571404 100644 --- a/agent/unit_state_test.go +++ b/agent/unit_state_test.go @@ -625,13 +625,36 @@ func TestUnitStatePublisherRunWithDelays(t *testing.T) { ) } + waitUnitToPublish := func(uName string) { + select { + case name := <-usp.toPublish: + if name != uName { + t.Errorf("unexpected name on toPublish channel: %v", name) + } + case <-time.After(time.Second): + t.Fatal("did not receive on toPublish channel as expected") + } + } + // now queue some more unit states for publishing - expect them to hang - go usp.queueForPublish("foo.service", &unit.UnitState{UnitName: "foo.service", ActiveState: "active"}) + go usp.queueForPublish("foo.service", &unit.UnitState{ + UnitName: "foo.service", + ActiveState: "active", + }) + waitUnitToPublish("foo.service") + go usp.queueForPublish("bar.service", &unit.UnitState{}) + waitUnitToPublish("bar.service") + go usp.queueForPublish("baz.service", &unit.UnitState{}) + waitUnitToPublish("baz.service") // re-queue one of the states; this should replace the above - go usp.queueForPublish("foo.service", &unit.UnitState{UnitName: "foo.service", ActiveState: "inactive"}) + go usp.queueForPublish("foo.service", &unit.UnitState{ + UnitName: "foo.service", + ActiveState: "inactive", + }) + waitUnitToPublish("foo.service") // wait for all publish workers to start wgs.Wait()