github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/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 "testing" 10 "time" 11 12 "github.com/juju/cmd" 13 jujutesting "github.com/juju/testing" 14 jc "github.com/juju/testing/checkers" 15 gc "gopkg.in/check.v1" 16 17 "github.com/juju/juju/apiserver/params" 18 "github.com/juju/juju/cmd/juju/action" 19 "github.com/juju/juju/jujuclient" 20 "github.com/juju/juju/jujuclient/jujuclienttesting" 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 coretesting.FakeJujuXDGDataHomeSuite 41 command cmd.Command 42 43 modelFlags []string 44 store *jujuclienttesting.MemStore 45 } 46 47 func (s *BaseActionSuite) SetUpTest(c *gc.C) { 48 s.FakeJujuXDGDataHomeSuite.SetUpTest(c) 49 50 s.modelFlags = []string{"-m", "--model"} 51 52 s.store = jujuclienttesting.NewMemStore() 53 s.store.CurrentControllerName = "ctrl" 54 s.store.Accounts["ctrl"] = jujuclient.AccountDetails{ 55 User: "admin", 56 } 57 } 58 59 func (s *BaseActionSuite) patchAPIClient(client *fakeAPIClient) func() { 60 return jujutesting.PatchValue(action.NewActionAPIClient, 61 func(c *action.ActionCommandBase) (action.APIClient, error) { 62 return client, nil 63 }, 64 ) 65 } 66 67 var someCharmActions = map[string]params.ActionSpec{ 68 "snapshot": { 69 Description: "Take a snapshot of the database.", 70 Params: map[string]interface{}{ 71 "foo": map[string]interface{}{ 72 "bar": "baz", 73 }, 74 "baz": "bar", 75 }, 76 }, 77 "kill": { 78 Description: "Kill the database.", 79 Params: map[string]interface{}{ 80 "bar": map[string]interface{}{ 81 "baz": "foo", 82 }, 83 "foo": "baz", 84 }, 85 }, 86 "no-description": { 87 Params: map[string]interface{}{ 88 "bar": map[string]interface{}{ 89 "baz": "foo", 90 }, 91 "foo": "baz", 92 }, 93 }, 94 "no-params": { 95 Description: "An action with no parameters.\n", 96 }, 97 } 98 99 // tagsForIdPrefix builds a params.FindTagResults for a given id prefix 100 // and 0..n given tags. This is useful for stubbing out the API and 101 // ensuring that the API returns expected tags for a given id prefix. 102 func tagsForIdPrefix(prefix string, tags ...string) params.FindTagsResults { 103 entities := make([]params.Entity, len(tags)) 104 for i, t := range tags { 105 entities[i] = params.Entity{Tag: t} 106 } 107 return params.FindTagsResults{Matches: map[string][]params.Entity{prefix: entities}} 108 } 109 110 // setupValueFile creates a file containing one value for testing. 111 // cf. cmd/juju/set_test.go 112 func setupValueFile(c *gc.C, dir, filename, value string) string { 113 ctx := coretesting.ContextForDir(c, dir) 114 path := ctx.AbsPath(filename) 115 content := []byte(value) 116 err := ioutil.WriteFile(path, content, 0666) 117 c.Assert(err, jc.ErrorIsNil) 118 return path 119 } 120 121 type fakeAPIClient struct { 122 delay *time.Timer 123 timeout *time.Timer 124 actionResults []params.ActionResult 125 enqueuedActions params.Actions 126 actionsByReceivers []params.ActionsByReceiver 127 actionTagMatches params.FindTagsResults 128 actionsByNames params.ActionsByNames 129 charmActions map[string]params.ActionSpec 130 apiErr error 131 } 132 133 var _ action.APIClient = (*fakeAPIClient)(nil) 134 135 // EnqueuedActions is a testing method which shows what Actions got enqueued 136 // by our Enqueue stub. 137 func (c *fakeAPIClient) EnqueuedActions() params.Actions { 138 return c.enqueuedActions 139 } 140 141 func (c *fakeAPIClient) Close() error { 142 return nil 143 } 144 145 func (c *fakeAPIClient) Enqueue(args params.Actions) (params.ActionResults, error) { 146 c.enqueuedActions = args 147 return params.ActionResults{Results: c.actionResults}, c.apiErr 148 } 149 150 func (c *fakeAPIClient) ListAll(args params.Entities) (params.ActionsByReceivers, error) { 151 return params.ActionsByReceivers{ 152 Actions: c.actionsByReceivers, 153 }, c.apiErr 154 } 155 156 func (c *fakeAPIClient) ListPending(args params.Entities) (params.ActionsByReceivers, error) { 157 return params.ActionsByReceivers{ 158 Actions: c.actionsByReceivers, 159 }, c.apiErr 160 } 161 162 func (c *fakeAPIClient) ListCompleted(args params.Entities) (params.ActionsByReceivers, error) { 163 return params.ActionsByReceivers{ 164 Actions: c.actionsByReceivers, 165 }, c.apiErr 166 } 167 168 func (c *fakeAPIClient) Cancel(args params.Actions) (params.ActionResults, error) { 169 return params.ActionResults{ 170 Results: c.actionResults, 171 }, c.apiErr 172 } 173 174 func (c *fakeAPIClient) ApplicationCharmActions(params.Entity) (map[string]params.ActionSpec, error) { 175 return c.charmActions, c.apiErr 176 } 177 178 func (c *fakeAPIClient) Actions(args params.Entities) (params.ActionResults, error) { 179 // If the test supplies a delay time too long, we'll return an error 180 // to prevent the test hanging. If the given wait is up, then return 181 // the results; otherwise, return a pending status. 182 183 // First, sync. 184 _ = <-time.NewTimer(0 * time.Second).C 185 186 select { 187 case _ = <-c.delay.C: 188 // The API delay timer is up. Pass pre-canned results back. 189 return params.ActionResults{Results: c.actionResults}, c.apiErr 190 case _ = <-c.timeout.C: 191 // Timeout to prevent tests from hanging. 192 return params.ActionResults{}, errors.New("test timed out before wait time") 193 default: 194 // Timeout should only be nonzero in case we want to test 195 // pending behavior with a --wait flag on FetchCommand. 196 return params.ActionResults{Results: []params.ActionResult{{ 197 Status: params.ActionPending, 198 Output: map[string]interface{}{}, 199 Started: time.Date(2015, time.February, 14, 8, 15, 0, 0, time.UTC), 200 Enqueued: time.Date(2015, time.February, 14, 8, 13, 0, 0, time.UTC), 201 }}}, nil 202 } 203 } 204 205 func (c *fakeAPIClient) FindActionTagsByPrefix(arg params.FindTags) (params.FindTagsResults, error) { 206 return c.actionTagMatches, c.apiErr 207 } 208 209 func (c *fakeAPIClient) FindActionsByNames(args params.FindActionsByNames) (params.ActionsByNames, error) { 210 return c.actionsByNames, c.apiErr 211 }