github.com/makyo/juju@v0.0.0-20160425123129-2608902037e9/cmd/juju/model/retryprovisioning_test.go (about)

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