github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/watcher/watchertest/strings.go (about)

     1  // Copyright 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package watchertest
     5  
     6  import (
     7  	"time"
     8  
     9  	jc "github.com/juju/testing/checkers"
    10  	"github.com/juju/utils/set"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/testing"
    14  	"github.com/juju/juju/watcher"
    15  )
    16  
    17  func NewStringsWatcherC(c *gc.C, watcher watcher.StringsWatcher, preAssert func()) StringsWatcherC {
    18  	if preAssert == nil {
    19  		preAssert = func() {}
    20  	}
    21  	return StringsWatcherC{
    22  		C:         c,
    23  		Watcher:   watcher,
    24  		PreAssert: preAssert,
    25  	}
    26  }
    27  
    28  type StringsWatcherC struct {
    29  	*gc.C
    30  	Watcher   watcher.StringsWatcher
    31  	PreAssert func()
    32  }
    33  
    34  // AssertChanges fails if it cannot read a value from Changes despite waiting a
    35  // long time. It logs, but does not check, the received changes; but will fail
    36  // if the Changes chan is closed.
    37  func (c StringsWatcherC) AssertChanges() {
    38  	c.PreAssert()
    39  	select {
    40  	case change, ok := <-c.Watcher.Changes():
    41  		c.Logf("received change: %#v", change)
    42  		c.Assert(ok, jc.IsTrue)
    43  	case <-time.After(testing.LongWait):
    44  		c.Fatalf("watcher did not send change")
    45  	}
    46  	c.AssertNoChange()
    47  }
    48  
    49  // AssertNoChange fails if it manages to read a value from Changes before a
    50  // short time has passed.
    51  func (c StringsWatcherC) AssertNoChange() {
    52  	c.PreAssert()
    53  	select {
    54  	case change, ok := <-c.Watcher.Changes():
    55  		c.Fatalf("watcher sent unexpected change: (%#v, %v)", change, ok)
    56  	case <-time.After(testing.ShortWait):
    57  	}
    58  }
    59  
    60  // AssertStops Kills the watcher and asserts (1) that Wait completes without
    61  // error before a long time has passed; and (2) that Changes remains open but
    62  // no values are being sent.
    63  func (c StringsWatcherC) AssertStops() {
    64  	c.Watcher.Kill()
    65  	wait := make(chan error)
    66  	go func() {
    67  		c.PreAssert()
    68  		wait <- c.Watcher.Wait()
    69  	}()
    70  	select {
    71  	case <-time.After(testing.LongWait):
    72  		c.Fatalf("watcher never stopped")
    73  	case err := <-wait:
    74  		c.Assert(err, jc.ErrorIsNil)
    75  	}
    76  
    77  	c.PreAssert()
    78  	select {
    79  	case change, ok := <-c.Watcher.Changes():
    80  		c.Fatalf("watcher sent unexpected change: (%#v, %v)", change, ok)
    81  	default:
    82  	}
    83  }
    84  
    85  func (c StringsWatcherC) AssertChange(expect ...string) {
    86  	c.assertChange(false, expect...)
    87  }
    88  
    89  func (c StringsWatcherC) AssertChangeInSingleEvent(expect ...string) {
    90  	c.assertChange(true, expect...)
    91  }
    92  
    93  // AssertChangeMaybeIncluding verifies that there is a change that may
    94  // contain zero to all of the passed in strings, and no other changes.
    95  func (c StringsWatcherC) AssertChangeMaybeIncluding(expect ...string) {
    96  	maxCount := len(expect)
    97  	actual := c.collectChanges(true, maxCount)
    98  
    99  	if maxCount == 0 {
   100  		c.Assert(actual, gc.HasLen, 0)
   101  	} else {
   102  		actualCount := len(actual)
   103  		c.Assert(actualCount <= maxCount, jc.IsTrue, gc.Commentf("expected at most %d, got %d", maxCount, actualCount))
   104  		unexpected := set.NewStrings(actual...).Difference(set.NewStrings(expect...))
   105  		c.Assert(unexpected.Values(), gc.HasLen, 0)
   106  	}
   107  }
   108  
   109  // assertChange asserts the given list of changes was reported by
   110  // the watcher, but does not assume there are no following changes.
   111  func (c StringsWatcherC) assertChange(single bool, expect ...string) {
   112  	actual := c.collectChanges(single, len(expect))
   113  	if len(expect) == 0 {
   114  		c.Assert(actual, gc.HasLen, 0)
   115  	} else {
   116  		c.Assert(actual, jc.SameContents, expect)
   117  	}
   118  }
   119  
   120  // collectChanges gets up to the max number of changes within the
   121  // testing.LongWait period.
   122  func (c StringsWatcherC) collectChanges(single bool, max int) []string {
   123  	timeout := time.After(testing.LongWait)
   124  	var actual []string
   125  	gotOneChange := false
   126  loop:
   127  	for {
   128  		c.PreAssert()
   129  		select {
   130  		case changes, ok := <-c.Watcher.Changes():
   131  			c.Assert(ok, jc.IsTrue)
   132  			gotOneChange = true
   133  			actual = append(actual, changes...)
   134  			if single || len(actual) >= max {
   135  				break loop
   136  			}
   137  		case <-timeout:
   138  			if !gotOneChange {
   139  				c.Fatalf("watcher did not send change")
   140  			}
   141  		}
   142  	}
   143  	return actual
   144  }