github.com/altoros/juju-vmware@v0.0.0-20150312064031-f19ae857ccca/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  }
   121  
   122  func (s *retryProvisioningSuite) TestRetryProvisioning(c *gc.C) {
   123  	for i, t := range resolvedMachineTests {
   124  		c.Logf("test %d: %v", i, t.args)
   125  		command := environment.NewRetryProvisioningCommand(s.fake)
   126  		context, err := testing.RunCommand(c, envcmd.Wrap(command), t.args...)
   127  		if t.err != "" {
   128  			c.Check(err, gc.ErrorMatches, t.err)
   129  			continue
   130  		}
   131  		c.Check(err, jc.ErrorIsNil)
   132  		output := testing.Stderr(context)
   133  		stripped := strings.Replace(output, "\n", "", -1)
   134  		c.Check(stripped, gc.Equals, t.stdErr)
   135  		if t.args[0] == "0" {
   136  			m := s.fake.m["0"]
   137  			c.Check(m.info, gc.Equals, "broken")
   138  			c.Check(m.data["transient"], jc.IsTrue)
   139  		}
   140  	}
   141  }
   142  
   143  func (s *retryProvisioningSuite) TestBlockRetryProvisioning(c *gc.C) {
   144  	s.fake.err = &params.Error{Code: params.CodeOperationBlocked}
   145  	command := environment.NewRetryProvisioningCommand(s.fake)
   146  
   147  	for i, t := range resolvedMachineTests {
   148  		c.Logf("test %d: %v", i, t.args)
   149  		_, err := testing.RunCommand(c, envcmd.Wrap(command), t.args...)
   150  		if t.err != "" {
   151  			c.Check(err, gc.ErrorMatches, t.err)
   152  			continue
   153  		}
   154  		c.Assert(err, gc.ErrorMatches, cmd.ErrSilent.Error())
   155  		// msg is logged
   156  		stripped := strings.Replace(c.GetTestLog(), "\n", "", -1)
   157  		c.Check(stripped, gc.Matches, ".*To unblock changes.*")
   158  	}
   159  }