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