github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/worker/instancepoller/worker_test.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // TODO(wallyworld) - move to instancepoller_test
     5  package instancepoller
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"time"
    11  
    12  	"github.com/juju/errors"
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/instance"
    17  	"github.com/juju/juju/juju/testing"
    18  	"github.com/juju/juju/network"
    19  	"github.com/juju/juju/provider/dummy"
    20  	"github.com/juju/juju/state"
    21  	coretesting "github.com/juju/juju/testing"
    22  	"github.com/juju/juju/worker"
    23  )
    24  
    25  var _ = gc.Suite(&workerSuite{})
    26  
    27  type workerSuite struct {
    28  	testing.JujuConnSuite
    29  }
    30  
    31  func (*workerSuite) instId(i int) instance.Id {
    32  	return instance.Id(fmt.Sprint(i))
    33  }
    34  
    35  func (*workerSuite) addressesForIndex(i int) []network.Address {
    36  	return network.NewAddresses(fmt.Sprintf("127.0.0.%d", i))
    37  }
    38  
    39  func (s *workerSuite) TestWorker(c *gc.C) {
    40  	// Most functionality is already tested in detail - we
    41  	// just need to test that things are wired together
    42  	// correctly.
    43  	s.PatchValue(&ShortPoll, 10*time.Millisecond)
    44  	s.PatchValue(&LongPoll, 10*time.Millisecond)
    45  	s.PatchValue(&gatherTime, 10*time.Millisecond)
    46  	machines, insts := s.setupScenario(c)
    47  	s.State.StartSync()
    48  	w := NewWorker(s.State)
    49  	defer func() {
    50  		c.Assert(worker.Stop(w), gc.IsNil)
    51  	}()
    52  
    53  	checkInstanceInfo := func(index int, m machine, expectedStatus string) bool {
    54  		isProvisioned := true
    55  		status, err := m.InstanceStatus()
    56  		if errors.IsNotProvisioned(err) {
    57  			isProvisioned = false
    58  		} else {
    59  			c.Assert(err, jc.ErrorIsNil)
    60  		}
    61  		return reflect.DeepEqual(m.Addresses(), s.addressesForIndex(index)) && (!isProvisioned || status == expectedStatus)
    62  	}
    63  
    64  	// Wait for the odd numbered machines in the
    65  	// first half of the machine slice to be given their
    66  	// addresses and status.
    67  	for a := coretesting.LongAttempt.Start(); a.Next(); {
    68  		if !a.HasNext() {
    69  			c.Fatalf("timed out waiting for instance info")
    70  		}
    71  
    72  		if machinesSatisfy(c, machines, func(i int, m *state.Machine) bool {
    73  			if i < len(machines)/2 && i%2 == 1 {
    74  				return checkInstanceInfo(i, m, "running")
    75  			}
    76  			status, err := m.InstanceStatus()
    77  			if i%2 == 0 {
    78  				// Even machines not provisioned yet.
    79  				c.Assert(err, jc.Satisfies, errors.IsNotProvisioned)
    80  			} else {
    81  				c.Assert(status, gc.Equals, "")
    82  			}
    83  			return len(m.Addresses()) == 0
    84  		}) {
    85  			break
    86  		}
    87  	}
    88  	// Now provision the even machines in the first half and watch them get addresses.
    89  	for i := 0; i < len(insts)/2; i += 2 {
    90  		m := machines[i]
    91  		err := m.SetProvisioned(insts[i].Id(), "nonce", nil)
    92  		c.Assert(err, jc.ErrorIsNil)
    93  		dummy.SetInstanceAddresses(insts[i], s.addressesForIndex(i))
    94  		dummy.SetInstanceStatus(insts[i], "running")
    95  	}
    96  	for a := coretesting.LongAttempt.Start(); a.Next(); {
    97  		if !a.HasNext() {
    98  			c.Fatalf("timed out waiting for machine instance info")
    99  		}
   100  		if machinesSatisfy(c, machines, func(i int, m *state.Machine) bool {
   101  			if i < len(machines)/2 {
   102  				return checkInstanceInfo(i, m, "running")
   103  			}
   104  			// Machines in second half still have no addresses, nor status.
   105  			status, err := m.InstanceStatus()
   106  			if i%2 == 0 {
   107  				// Even machines not provisioned yet.
   108  				c.Assert(err, jc.Satisfies, errors.IsNotProvisioned)
   109  			} else {
   110  				c.Assert(status, gc.Equals, "")
   111  			}
   112  			return len(m.Addresses()) == 0
   113  		}) {
   114  			break
   115  		}
   116  	}
   117  
   118  	// Provision the remaining machines and check the address and status.
   119  	for i := len(insts) / 2; i < len(insts); i++ {
   120  		if i%2 == 0 {
   121  			m := machines[i]
   122  			err := m.SetProvisioned(insts[i].Id(), "nonce", nil)
   123  			c.Assert(err, jc.ErrorIsNil)
   124  		}
   125  		dummy.SetInstanceAddresses(insts[i], s.addressesForIndex(i))
   126  		dummy.SetInstanceStatus(insts[i], "running")
   127  	}
   128  	for a := coretesting.LongAttempt.Start(); a.Next(); {
   129  		if !a.HasNext() {
   130  			c.Fatalf("timed out waiting for machine instance info")
   131  		}
   132  		if machinesSatisfy(c, machines, func(i int, m *state.Machine) bool {
   133  			return checkInstanceInfo(i, m, "running")
   134  		}) {
   135  			break
   136  		}
   137  	}
   138  }
   139  
   140  // TODO(rog)
   141  // - check that the environment observer is actually hooked up.
   142  // - check that the environment observer is stopped.
   143  // - check that the errors propagate correctly.
   144  
   145  func machinesSatisfy(c *gc.C, machines []*state.Machine, f func(i int, m *state.Machine) bool) bool {
   146  	for i, m := range machines {
   147  		err := m.Refresh()
   148  		c.Assert(err, jc.ErrorIsNil)
   149  		if !f(i, m) {
   150  			return false
   151  		}
   152  	}
   153  	return true
   154  }
   155  
   156  func (s *workerSuite) setupScenario(c *gc.C) ([]*state.Machine, []instance.Instance) {
   157  	var machines []*state.Machine
   158  	var insts []instance.Instance
   159  	for i := 0; i < 10; i++ {
   160  		m, err := s.State.AddMachine("series", state.JobHostUnits)
   161  		c.Assert(err, jc.ErrorIsNil)
   162  		machines = append(machines, m)
   163  		inst, _ := testing.AssertStartInstance(c, s.Environ, m.Id())
   164  		insts = append(insts, inst)
   165  	}
   166  	// Associate the odd-numbered machines with an instance.
   167  	for i := 1; i < len(machines); i += 2 {
   168  		m := machines[i]
   169  		err := m.SetProvisioned(insts[i].Id(), "nonce", nil)
   170  		c.Assert(err, jc.ErrorIsNil)
   171  	}
   172  	// Associate the first half of the instances with an address and status.
   173  	for i := 0; i < len(machines)/2; i++ {
   174  		dummy.SetInstanceAddresses(insts[i], s.addressesForIndex(i))
   175  		dummy.SetInstanceStatus(insts[i], "running")
   176  	}
   177  	// Make sure the second half of the instances have no addresses.
   178  	for i := len(machines) / 2; i < len(machines); i++ {
   179  		dummy.SetInstanceAddresses(insts[i], nil)
   180  	}
   181  	return machines, insts
   182  }