github.com/cloud-green/juju@v0.0.0-20151002100041-a00291338d3d/cmd/juju/action/package_test.go (about) 1 // Copyright 2014-2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package action_test 5 6 import ( 7 "errors" 8 "io/ioutil" 9 "regexp" 10 "testing" 11 "time" 12 13 "github.com/juju/cmd" 14 jujutesting "github.com/juju/testing" 15 jc "github.com/juju/testing/checkers" 16 gc "gopkg.in/check.v1" 17 "gopkg.in/juju/charm.v6-unstable" 18 19 "github.com/juju/juju/apiserver/params" 20 "github.com/juju/juju/cmd/juju/action" 21 coretesting "github.com/juju/juju/testing" 22 ) 23 24 const ( 25 validActionTagString = "action-f47ac10b-58cc-4372-a567-0e02b2c3d479" 26 invalidActionTagString = "action-f47ac10b-58cc-4372-a567-0e02b2c3d47" 27 validActionId = "f47ac10b-58cc-4372-a567-0e02b2c3d479" 28 invalidActionId = "f47ac10b-58cc-4372-a567-0e02b2c3d47" 29 validUnitId = "mysql/0" 30 invalidUnitId = "something-strange-" 31 validServiceId = "mysql" 32 invalidServiceId = "something-strange-" 33 ) 34 35 func TestPackage(t *testing.T) { 36 gc.TestingT(t) 37 } 38 39 type BaseActionSuite struct { 40 jujutesting.IsolationSuite 41 command cmd.Command 42 } 43 44 var _ = gc.Suite(&FetchSuite{}) 45 46 func (s *BaseActionSuite) SetUpTest(c *gc.C) { 47 s.command = action.NewSuperCommand() 48 } 49 50 func (s *BaseActionSuite) patchAPIClient(client *fakeAPIClient) func() { 51 return jujutesting.PatchValue(action.NewActionAPIClient, 52 func(c *action.ActionCommandBase) (action.APIClient, error) { 53 return client, nil 54 }, 55 ) 56 } 57 58 func (s *BaseActionSuite) checkHelp(c *gc.C, subcmd cmd.Command) { 59 ctx, err := coretesting.RunCommand(c, s.command, subcmd.Info().Name, "--help") 60 c.Assert(err, gc.IsNil) 61 62 expected := "(?sm).*^usage: juju action " + 63 regexp.QuoteMeta(subcmd.Info().Name) + 64 ` \[options\] ` + regexp.QuoteMeta(subcmd.Info().Args) + ".+" 65 c.Check(coretesting.Stdout(ctx), gc.Matches, expected) 66 67 expected = "(?sm).*^purpose: " + regexp.QuoteMeta(subcmd.Info().Purpose) + "$.*" 68 c.Check(coretesting.Stdout(ctx), gc.Matches, expected) 69 70 expected = "(?sm).*^" + regexp.QuoteMeta(subcmd.Info().Doc) + "$.*" 71 c.Check(coretesting.Stdout(ctx), gc.Matches, expected) 72 } 73 74 var someCharmActions = &charm.Actions{ 75 ActionSpecs: map[string]charm.ActionSpec{ 76 "snapshot": { 77 Description: "Take a snapshot of the database.", 78 Params: map[string]interface{}{ 79 "foo": map[string]interface{}{ 80 "bar": "baz", 81 }, 82 "baz": "bar", 83 }, 84 }, 85 "kill": { 86 Description: "Kill the database.", 87 Params: map[string]interface{}{ 88 "bar": map[string]interface{}{ 89 "baz": "foo", 90 }, 91 "foo": "baz", 92 }, 93 }, 94 "no-description": { 95 Params: map[string]interface{}{ 96 "bar": map[string]interface{}{ 97 "baz": "foo", 98 }, 99 "foo": "baz", 100 }, 101 }, 102 "no-params": { 103 Description: "An action with no parameters.", 104 }, 105 }, 106 } 107 108 // tagsForIdPrefix builds a params.FindTagResults for a given id prefix 109 // and 0..n given tags. This is useful for stubbing out the API and 110 // ensuring that the API returns expected tags for a given id prefix. 111 func tagsForIdPrefix(prefix string, tags ...string) params.FindTagsResults { 112 entities := make([]params.Entity, len(tags)) 113 for i, t := range tags { 114 entities[i] = params.Entity{Tag: t} 115 } 116 return params.FindTagsResults{Matches: map[string][]params.Entity{prefix: entities}} 117 } 118 119 // setupValueFile creates a file containing one value for testing. 120 // cf. cmd/juju/set_test.go 121 func setupValueFile(c *gc.C, dir, filename, value string) string { 122 ctx := coretesting.ContextForDir(c, dir) 123 path := ctx.AbsPath(filename) 124 content := []byte(value) 125 err := ioutil.WriteFile(path, content, 0666) 126 c.Assert(err, jc.ErrorIsNil) 127 return path 128 } 129 130 type fakeAPIClient struct { 131 delay *time.Timer 132 timeout *time.Timer 133 actionResults []params.ActionResult 134 enqueuedActions params.Actions 135 actionsByReceivers []params.ActionsByReceiver 136 actionTagMatches params.FindTagsResults 137 charmActions *charm.Actions 138 apiErr error 139 } 140 141 var _ action.APIClient = (*fakeAPIClient)(nil) 142 143 // EnqueuedActions is a testing method which shows what Actions got enqueued 144 // by our Enqueue stub. 145 func (c *fakeAPIClient) EnqueuedActions() params.Actions { 146 return c.enqueuedActions 147 } 148 149 func (c *fakeAPIClient) Close() error { 150 return nil 151 } 152 153 func (c *fakeAPIClient) Enqueue(args params.Actions) (params.ActionResults, error) { 154 c.enqueuedActions = args 155 return params.ActionResults{Results: c.actionResults}, c.apiErr 156 } 157 158 func (c *fakeAPIClient) ListAll(args params.Entities) (params.ActionsByReceivers, error) { 159 return params.ActionsByReceivers{ 160 Actions: c.actionsByReceivers, 161 }, c.apiErr 162 } 163 164 func (c *fakeAPIClient) ListPending(args params.Entities) (params.ActionsByReceivers, error) { 165 return params.ActionsByReceivers{ 166 Actions: c.actionsByReceivers, 167 }, c.apiErr 168 } 169 170 func (c *fakeAPIClient) ListCompleted(args params.Entities) (params.ActionsByReceivers, error) { 171 return params.ActionsByReceivers{ 172 Actions: c.actionsByReceivers, 173 }, c.apiErr 174 } 175 176 func (c *fakeAPIClient) Cancel(args params.Actions) (params.ActionResults, error) { 177 return params.ActionResults{ 178 Results: c.actionResults, 179 }, c.apiErr 180 } 181 182 func (c *fakeAPIClient) ServiceCharmActions(params.Entity) (*charm.Actions, error) { 183 return c.charmActions, c.apiErr 184 } 185 186 func (c *fakeAPIClient) Actions(args params.Entities) (params.ActionResults, error) { 187 // If the test supplies a delay time too long, we'll return an error 188 // to prevent the test hanging. If the given wait is up, then return 189 // the results; otherwise, return a pending status. 190 191 // First, sync. 192 _ = <-time.NewTimer(0 * time.Second).C 193 194 select { 195 case _ = <-c.delay.C: 196 // The API delay timer is up. Pass pre-canned results back. 197 return params.ActionResults{Results: c.actionResults}, c.apiErr 198 case _ = <-c.timeout.C: 199 // Timeout to prevent tests from hanging. 200 return params.ActionResults{}, errors.New("test timed out before wait time") 201 default: 202 // Timeout should only be nonzero in case we want to test 203 // pending behavior with a --wait flag on FetchCommand. 204 return params.ActionResults{Results: []params.ActionResult{{ 205 Status: params.ActionPending, 206 Output: map[string]interface{}{}, 207 Started: time.Date(2015, time.February, 14, 8, 15, 0, 0, time.UTC), 208 Enqueued: time.Date(2015, time.February, 14, 8, 13, 0, 0, time.UTC), 209 }}}, nil 210 } 211 } 212 213 func (c *fakeAPIClient) FindActionTagsByPrefix(arg params.FindTags) (params.FindTagsResults, error) { 214 return c.actionTagMatches, c.apiErr 215 }