github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/worker/workertest/check.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package workertest
     5  
     6  import (
     7  	"time"
     8  
     9  	"github.com/juju/errors"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	coretesting "github.com/juju/juju/testing"
    14  	"github.com/juju/juju/worker"
    15  )
    16  
    17  var (
    18  	// AliveDelay is the minimum time an Alive helper will Wait for its worker
    19  	// to stop before returning successfully.
    20  	aliveDelay = coretesting.ShortWait
    21  
    22  	// KillTimeout is the maximum time a Kill helper will Wait for its worker
    23  	// before failing the test.
    24  	killTimeout = coretesting.LongWait
    25  )
    26  
    27  // CheckAlive Wait()s a short time for the supplied worker to return an error,
    28  // and fails the test if it does. If it doesn't fail, it'll leave a goroutine
    29  // running in the background, blocked on the worker's death; but that doesn't
    30  // matter, because of *course* you correctly deferred a suitable Kill helper
    31  // as soon as you created the worker in the first place. Right? Right.
    32  //
    33  // It doesn't Assert and is therefore suitable for use from any goroutine.
    34  func CheckAlive(c *gc.C, w worker.Worker) {
    35  	wait := make(chan error, 1)
    36  	go func() {
    37  		wait <- w.Wait()
    38  	}()
    39  	select {
    40  	case <-time.After(aliveDelay):
    41  	case err := <-wait:
    42  		c.Errorf("expected alive worker; failed with %v", err)
    43  	}
    44  }
    45  
    46  // CheckKilled Wait()s for the supplied worker's error, which it returns for
    47  // further analysis, or fails the test after a timeout expires. It doesn't
    48  // Assert and is therefore suitable for use from any goroutine.
    49  func CheckKilled(c *gc.C, w worker.Worker) error {
    50  	wait := make(chan error, 1)
    51  	go func() {
    52  		wait <- w.Wait()
    53  	}()
    54  	select {
    55  	case err := <-wait:
    56  		return err
    57  	case <-time.After(killTimeout):
    58  		c.Errorf("timed out waiting for worker to stop")
    59  		return errors.New("workertest: worker not stopping")
    60  	}
    61  }
    62  
    63  // CheckKill Kill()s the supplied worker and Wait()s for its error, which it
    64  // returns for further analysis, or fails the test after a timeout expires.
    65  // It doesn't Assert and is therefore suitable for use from any goroutine.
    66  func CheckKill(c *gc.C, w worker.Worker) error {
    67  	w.Kill()
    68  	return CheckKilled(c, w)
    69  }
    70  
    71  // CleanKill calls CheckKill with the supplied arguments, and Checks that the
    72  // returned error is nil. It's particularly suitable for deferring:
    73  //
    74  //     someWorker, err := some.NewWorker()
    75  //     c.Assert(err, jc.ErrorIsNil)
    76  //     defer workertest.CleanKill(c, someWorker)
    77  //
    78  // ...in the large number (majority?) of situations where a worker is expected
    79  // to run successfully; and it doesn't Assert, and is therefore suitable for use
    80  // from any goroutine.
    81  func CleanKill(c *gc.C, w worker.Worker) {
    82  	err := CheckKill(c, w)
    83  	c.Check(err, jc.ErrorIsNil)
    84  }
    85  
    86  // DirtyKill calls CheckKill with the supplied arguments, and logs the returned
    87  // error. It's particularly suitable for deferring:
    88  //
    89  //     someWorker, err := some.NewWorker()
    90  //     c.Assert(err, jc.ErrorIsNil)
    91  //     defer workertest.DirtyKill(c, someWorker)
    92  //
    93  // ...in the cases where we expect a worker to fail, but aren't specifically
    94  // testing that failure; and it doesn't Assert, and is therefore suitable for
    95  // use from any goroutine.
    96  func DirtyKill(c *gc.C, w worker.Worker) {
    97  	err := CheckKill(c, w)
    98  	c.Logf("ignoring error: %v", err)
    99  }
   100  
   101  // CheckNilOrKill has no effect if w is nil; otherwise, it fails the test
   102  // and tries to stop the (non-nil) worker via CleanKill(). It's suitable
   103  // for testing constructor failure:
   104  //
   105  //     someWorker, err := some.NewWorker(badConfig)
   106  //     workertest.CheckNilOrKill(c, someWorker)
   107  //     c.Check(err, ...
   108  //
   109  // ...because it will do the right thing if your constructor succeeds
   110  // unexpectedly, and make every effort to prevent a rogue worker living
   111  // beyond its test.
   112  func CheckNilOrKill(c *gc.C, w worker.Worker) {
   113  	if !c.Check(w, gc.IsNil) {
   114  		c.Logf("stopping rogue worker...")
   115  		CleanKill(c, w)
   116  	}
   117  }