From 6688c29c37c0e91da1032f2e19ef4fbf81ad8b89 Mon Sep 17 00:00:00 2001 From: draxil Date: Sun, 1 Jun 2014 16:59:57 +0100 Subject: [PATCH 1/2] Enahanced Work() without Ready() behaviour: Now if you try to call Work() without calling Ready(), it will trigger an attempt to run Ready(), and will only panic if there is an error. --- worker/worker.go | 6 +++++- worker/worker_test.go | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/worker/worker.go b/worker/worker.go index f4d926e..a81f4ab 100644 --- a/worker/worker.go +++ b/worker/worker.go @@ -183,7 +183,11 @@ func (worker *Worker) Ready() (err error) { // Most of time, this should be evaluated in goroutine. func (worker *Worker) Work() { if ! worker.ready { - panic( "worker: Work() called before Ready()") + // didn't run Ready beforehand, so we'll have to do it: + err := worker.Ready() + if err != nil { + panic( err ) + } } defer func() { diff --git a/worker/worker_test.go b/worker/worker_test.go index 7fa8f0b..9960591 100644 --- a/worker/worker_test.go +++ b/worker/worker_test.go @@ -77,6 +77,33 @@ func TestWork(t *testing.T) { wg.Wait() } + func TestWorkerClose(t *testing.T) { worker.Close() } + +func TestWorkWithoutReady(t * testing.T){ + other_worker := New(Unlimited) + var wg sync.WaitGroup + + if err := other_worker.AddServer(Network, "127.0.0.1:4730"); err != nil { + t.Error(err) + } + if err := other_worker.AddFunc("foobar", foobar, 0); err != nil { + t.Error(err) + } + + other_worker.JobHandler = func( j Job ) error { + if( ! other_worker.ready ){ + t.Error("Worker not ready as expected"); + } + wg.Done() + return nil + } + + go other_worker.Work(); + + wg.Add(1) + worker.Echo([]byte("Hello")) + wg.Wait(); +} From 0a4489d1fea167b2558a5bb6fd81e8845af55569 Mon Sep 17 00:00:00 2001 From: Joe Higton Date: Wed, 4 Jun 2014 13:31:25 +0100 Subject: [PATCH 2/2] Fixed and improved Work() without Ready() test: * FIX: committed test froze * FIX: committed test had a race condition! * Added properly handled panic test * Timeouts so that these tests should fail now if something goes wrong instead of failing. --- worker/worker_test.go | 74 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 67 insertions(+), 7 deletions(-) diff --git a/worker/worker_test.go b/worker/worker_test.go index 9960591..06ce15f 100644 --- a/worker/worker_test.go +++ b/worker/worker_test.go @@ -3,6 +3,7 @@ package worker import ( "sync" "testing" + "time" ) var worker *Worker @@ -84,26 +85,85 @@ func TestWorkerClose(t *testing.T) { func TestWorkWithoutReady(t * testing.T){ other_worker := New(Unlimited) - var wg sync.WaitGroup if err := other_worker.AddServer(Network, "127.0.0.1:4730"); err != nil { t.Error(err) } - if err := other_worker.AddFunc("foobar", foobar, 0); err != nil { + if err := other_worker.AddFunc("gearman-go-workertest", foobar, 0); err != nil { t.Error(err) } + + timeout := make(chan bool, 1) + done := make( chan bool, 1) other_worker.JobHandler = func( j Job ) error { if( ! other_worker.ready ){ t.Error("Worker not ready as expected"); } - wg.Done() + done <-true return nil } + go func() { + time.Sleep(5 * time.Second) + timeout <- true + }() - go other_worker.Work(); + go func(){ + other_worker.Work(); + }() + + // With the all-in-one Work() we don't know if the + // worker is ready at this stage so we may have to wait a sec: + go func(){ + tries := 3 + for( tries > 0 ){ + if other_worker.ready { + other_worker.Echo([]byte("Hello")) + break + } + + // still waiting for it to be ready.. + time.Sleep(1 * time.Second) + tries-- + } + }() + + // determine if we've finished or timed out: + select{ + case <- timeout: + t.Error("Test timed out waiting for the worker") + case <- done: + } +} + +func TestWorkWithoutReadyWithPanic(t * testing.T){ + other_worker := New(Unlimited) + + timeout := make(chan bool, 1) + done := make( chan bool, 1) + + // Going to work with no worker setup. + // when Work (hopefully) calls Ready it will get an error which should cause it to panic() + go func(){ + defer func() { + if err := recover(); err != nil { + done <- true + return + } + t.Error("Work should raise a panic.") + done <- true + }() + other_worker.Work(); + }() + go func() { + time.Sleep(2 * time.Second) + timeout <- true + }() + + select{ + case <- timeout: + t.Error("Test timed out waiting for the worker") + case <- done: + } - wg.Add(1) - worker.Echo([]byte("Hello")) - wg.Wait(); }