github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/state/prechecker_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package state_test
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/juju/errors"
    10  	jc "github.com/juju/testing/checkers"
    11  	gc "gopkg.in/check.v1"
    12  
    13  	"github.com/juju/juju/agent"
    14  	"github.com/juju/juju/constraints"
    15  	"github.com/juju/juju/environs/config"
    16  	"github.com/juju/juju/instance"
    17  	"github.com/juju/juju/state"
    18  )
    19  
    20  type PrecheckerSuite struct {
    21  	ConnSuite
    22  	prechecker mockPrechecker
    23  }
    24  
    25  var _ = gc.Suite(&PrecheckerSuite{})
    26  
    27  type mockPrechecker struct {
    28  	precheckInstanceError       error
    29  	precheckInstanceSeries      string
    30  	precheckInstanceConstraints constraints.Value
    31  	precheckInstancePlacement   string
    32  }
    33  
    34  func (p *mockPrechecker) PrecheckInstance(series string, cons constraints.Value, placement string) error {
    35  	p.precheckInstanceSeries = series
    36  	p.precheckInstanceConstraints = cons
    37  	p.precheckInstancePlacement = placement
    38  	return p.precheckInstanceError
    39  }
    40  
    41  func (s *PrecheckerSuite) SetUpTest(c *gc.C) {
    42  	s.ConnSuite.SetUpTest(c)
    43  	s.prechecker = mockPrechecker{}
    44  	s.policy.GetPrechecker = func(*config.Config) (state.Prechecker, error) {
    45  		return &s.prechecker, nil
    46  	}
    47  }
    48  
    49  func (s *PrecheckerSuite) TestPrecheckInstance(c *gc.C) {
    50  	// PrecheckInstance should be called with the specified
    51  	// series and placement, and the specified constraints
    52  	// merged with the model constraints, when attempting
    53  	// to create an instance.
    54  	envCons := constraints.MustParse("mem=4G")
    55  	placement := "abc123"
    56  	template, err := s.addOneMachine(c, envCons, placement)
    57  	c.Assert(err, jc.ErrorIsNil)
    58  	c.Assert(s.prechecker.precheckInstanceSeries, gc.Equals, template.Series)
    59  	c.Assert(s.prechecker.precheckInstancePlacement, gc.Equals, placement)
    60  	validator := constraints.NewValidator()
    61  	cons, err := validator.Merge(envCons, template.Constraints)
    62  	c.Assert(err, jc.ErrorIsNil)
    63  	c.Assert(s.prechecker.precheckInstanceConstraints, gc.DeepEquals, cons)
    64  }
    65  
    66  func (s *PrecheckerSuite) TestPrecheckErrors(c *gc.C) {
    67  	// Ensure that AddOneMachine fails when PrecheckInstance returns an error.
    68  	s.prechecker.precheckInstanceError = fmt.Errorf("no instance for you")
    69  	_, err := s.addOneMachine(c, constraints.Value{}, "placement")
    70  	c.Assert(err, gc.ErrorMatches, ".*no instance for you")
    71  
    72  	// If the policy's Prechecker method fails, that will be returned first.
    73  	s.policy.GetPrechecker = func(*config.Config) (state.Prechecker, error) {
    74  		return nil, fmt.Errorf("no prechecker for you")
    75  	}
    76  	_, err = s.addOneMachine(c, constraints.Value{}, "placement")
    77  	c.Assert(err, gc.ErrorMatches, ".*no prechecker for you")
    78  }
    79  
    80  func (s *PrecheckerSuite) TestPrecheckPrecheckerUnimplemented(c *gc.C) {
    81  	var precheckerErr error
    82  	s.policy.GetPrechecker = func(*config.Config) (state.Prechecker, error) {
    83  		return nil, precheckerErr
    84  	}
    85  	_, err := s.addOneMachine(c, constraints.Value{}, "placement")
    86  	c.Assert(err, gc.ErrorMatches, "cannot add a new machine: policy returned nil prechecker without an error")
    87  	precheckerErr = errors.NotImplementedf("Prechecker")
    88  	_, err = s.addOneMachine(c, constraints.Value{}, "placement")
    89  	c.Assert(err, jc.ErrorIsNil)
    90  }
    91  
    92  func (s *PrecheckerSuite) TestPrecheckNoPolicy(c *gc.C) {
    93  	s.policy.GetPrechecker = func(*config.Config) (state.Prechecker, error) {
    94  		c.Errorf("should not have been invoked")
    95  		return nil, nil
    96  	}
    97  	state.SetPolicy(s.State, nil)
    98  	_, err := s.addOneMachine(c, constraints.Value{}, "placement")
    99  	c.Assert(err, jc.ErrorIsNil)
   100  }
   101  
   102  func (s *PrecheckerSuite) addOneMachine(c *gc.C, envCons constraints.Value, placement string) (state.MachineTemplate, error) {
   103  	err := s.State.SetModelConstraints(envCons)
   104  	c.Assert(err, jc.ErrorIsNil)
   105  	oneJob := []state.MachineJob{state.JobHostUnits}
   106  	extraCons := constraints.MustParse("cpu-cores=4")
   107  	template := state.MachineTemplate{
   108  		Series:      "precise",
   109  		Constraints: extraCons,
   110  		Jobs:        oneJob,
   111  		Placement:   placement,
   112  	}
   113  	_, err = s.State.AddOneMachine(template)
   114  	return template, err
   115  }
   116  
   117  func (s *PrecheckerSuite) TestPrecheckInstanceInjectMachine(c *gc.C) {
   118  	template := state.MachineTemplate{
   119  		InstanceId: instance.Id("bootstrap"),
   120  		Series:     "precise",
   121  		Nonce:      agent.BootstrapNonce,
   122  		Jobs:       []state.MachineJob{state.JobManageModel},
   123  		Placement:  "anyoldthing",
   124  	}
   125  	_, err := s.State.AddOneMachine(template)
   126  	c.Assert(err, jc.ErrorIsNil)
   127  	// PrecheckInstance should not have been called, as we've
   128  	// injected a machine with an existing instance.
   129  	c.Assert(s.prechecker.precheckInstanceSeries, gc.Equals, "")
   130  	c.Assert(s.prechecker.precheckInstancePlacement, gc.Equals, "")
   131  }
   132  
   133  func (s *PrecheckerSuite) TestPrecheckContainerNewMachine(c *gc.C) {
   134  	// Attempting to add a container to a new machine should cause
   135  	// PrecheckInstance to be called.
   136  	template := state.MachineTemplate{
   137  		Series:    "precise",
   138  		Jobs:      []state.MachineJob{state.JobHostUnits},
   139  		Placement: "intertubes",
   140  	}
   141  	_, err := s.State.AddMachineInsideNewMachine(template, template, instance.LXC)
   142  	c.Assert(err, jc.ErrorIsNil)
   143  	c.Assert(s.prechecker.precheckInstanceSeries, gc.Equals, template.Series)
   144  	c.Assert(s.prechecker.precheckInstancePlacement, gc.Equals, template.Placement)
   145  }