github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/juju/environment/retryprovisioning_test.go (about)

     1  // Copyright 2014, 2015 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package environment_test
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"github.com/juju/cmd"
    11  	"github.com/juju/errors"
    12  	"github.com/juju/names"
    13  	jc "github.com/juju/testing/checkers"
    14  	gc "gopkg.in/check.v1"
    15  
    16  	"github.com/juju/juju/apiserver/common"
    17  	"github.com/juju/juju/apiserver/params"
    18  	"github.com/juju/juju/cmd/envcmd"
    19  	"github.com/juju/juju/cmd/juju/environment"
    20  	"github.com/juju/juju/testing"
    21  )
    22  
    23  type retryProvisioningSuite struct {
    24  	testing.FakeJujuHomeSuite
    25  	fake *fakeRetryProvisioningClient
    26  }
    27  
    28  var _ = gc.Suite(&retryProvisioningSuite{})
    29  
    30  // fakeRetryProvisioningClient contains some minimal information
    31  // about machines in the environment to mock out the behavior
    32  // of the real RetryProvisioning command.
    33  type fakeRetryProvisioningClient struct {
    34  	m   map[string]fakeMachine
    35  	err error
    36  }
    37  
    38  type fakeMachine struct {
    39  	info string
    40  	data map[string]interface{}
    41  }
    42  
    43  func (f *fakeRetryProvisioningClient) Close() error {
    44  	return nil
    45  }
    46  
    47  func (f *fakeRetryProvisioningClient) RetryProvisioning(machines ...names.MachineTag) (
    48  	[]params.ErrorResult, error) {
    49  
    50  	if f.err != nil {
    51  		return nil, f.err
    52  	}
    53  
    54  	results := make([]params.ErrorResult, len(machines))
    55  
    56  	// For each of the machines passed in, verify that we have the
    57  	// id and that the info string is "broken".
    58  	for i, machine := range machines {
    59  		m, ok := f.m[machine.Id()]
    60  		if ok {
    61  			if m.info == "broken" {
    62  				// The real RetryProvisioning command sets the
    63  				// status data "transient" : true.
    64  				m.data["transient"] = true
    65  			} else {
    66  				results[i].Error = common.ServerError(
    67  					fmt.Errorf("%s is not in an error state",
    68  						names.ReadableString(machine)))
    69  			}
    70  		} else {
    71  			results[i].Error = common.ServerError(
    72  				errors.NotFoundf("machine %s", machine.Id()))
    73  		}
    74  	}
    75  
    76  	return results, nil
    77  }
    78  
    79  func (s *retryProvisioningSuite) SetUpTest(c *gc.C) {
    80  	s.FakeJujuHomeSuite.SetUpTest(c)
    81  
    82  	// For all tests, create machine 0 (broken) and
    83  	// machine 1 (not broken).
    84  	s.fake = &fakeRetryProvisioningClient{
    85  		m: map[string]fakeMachine{
    86  			"0": {info: "broken",
    87  				data: make(map[string]interface{})},
    88  			"1": {info: "",
    89  				data: make(map[string]interface{})},
    90  		},
    91  	}
    92  }
    93  
    94  var resolvedMachineTests = []struct {
    95  	args   []string
    96  	err    string
    97  	stdErr string
    98  }{
    99  	{
   100  		err: `no machine specified`,
   101  	}, {
   102  		args: []string{"jeremy-fisher"},
   103  		err:  `invalid machine "jeremy-fisher"`,
   104  	}, {
   105  		args:   []string{"42"},
   106  		stdErr: `machine 42 not found`,
   107  	}, {
   108  		args:   []string{"1"},
   109  		stdErr: `machine 1 is not in an error state`,
   110  	}, {
   111  		args: []string{"0"},
   112  	}, {
   113  		args:   []string{"0", "1"},
   114  		stdErr: `machine 1 is not in an error state`,
   115  	}, {
   116  		args: []string{"1", "42"},
   117  		stdErr: `machine 1 is not in an error state` +
   118  			`machine 42 not found`,
   119  	}, {
   120  		args: []string{"0/lxc/0"},
   121  		err:  `invalid machine "0/lxc/0" retry-provisioning does not support containers`,
   122  	},
   123  }
   124  
   125  func (s *retryProvisioningSuite) TestRetryProvisioning(c *gc.C) {
   126  	for i, t := range resolvedMachineTests {
   127  		c.Logf("test %d: %v", i, t.args)
   128  		command := environment.NewRetryProvisioningCommand(s.fake)
   129  		context, err := testing.RunCommand(c, envcmd.Wrap(command), t.args...)
   130  		if t.err != "" {
   131  			c.Check(err, gc.ErrorMatches, t.err)
   132  			continue
   133  		}
   134  		c.Check(err, jc.ErrorIsNil)
   135  		output := testing.Stderr(context)
   136  		stripped := strings.Replace(output, "\n", "", -1)
   137  		c.Check(stripped, gc.Equals, t.stdErr)
   138  		if t.args[0] == "0" {
   139  			m := s.fake.m["0"]
   140  			c.Check(m.info, gc.Equals, "broken")
   141  			c.Check(m.data["transient"], jc.IsTrue)
   142  		}
   143  	}
   144  }
   145  
   146  func (s *retryProvisioningSuite) TestBlockRetryProvisioning(c *gc.C) {
   147  	s.fake.err = common.ErrOperationBlocked("TestBlockRetryProvisioning")
   148  	command := environment.NewRetryProvisioningCommand(s.fake)
   149  
   150  	for i, t := range resolvedMachineTests {
   151  		c.Logf("test %d: %v", i, t.args)
   152  		_, err := testing.RunCommand(c, envcmd.Wrap(command), t.args...)
   153  		if t.err != "" {
   154  			c.Check(err, gc.ErrorMatches, t.err)
   155  			continue
   156  		}
   157  		c.Assert(err, gc.ErrorMatches, cmd.ErrSilent.Error())
   158  		// msg is logged
   159  		stripped := strings.Replace(c.GetTestLog(), "\n", "", -1)
   160  		c.Check(stripped, gc.Matches, ".*TestBlockRetryProvisioning.*")
   161  	}
   162  }