github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/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  	"github.com/juju/cmd/cmdtesting"
    14  	jujutesting "github.com/juju/testing"
    15  	jc "github.com/juju/testing/checkers"
    16  	gc "gopkg.in/check.v1"
    17  
    18  	"github.com/juju/juju/apiserver/params"
    19  	"github.com/juju/juju/cmd/juju/action"
    20  	"github.com/juju/juju/jujuclient"
    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  	validUnitId            = "mysql/0"
    29  	validUnitId2           = "mysql/1"
    30  	invalidUnitId          = "something-strange-"
    31  	validApplicationId     = "mysql"
    32  	invalidApplicationId   = "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      *jujuclient.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 = jujuclient.NewMemStore()
    53  	s.store.CurrentControllerName = "ctrl"
    54  	s.store.Controllers["ctrl"] = jujuclient.ControllerDetails{}
    55  	s.store.Models["ctrl"] = &jujuclient.ControllerModels{
    56  		Models: map[string]jujuclient.ModelDetails{"admin/admin": {ModelType: "iaas"}}}
    57  	s.store.Accounts["ctrl"] = jujuclient.AccountDetails{
    58  		User: "admin",
    59  	}
    60  }
    61  
    62  func (s *BaseActionSuite) patchAPIClient(client *fakeAPIClient) func() {
    63  	return jujutesting.PatchValue(action.NewActionAPIClient,
    64  		func(c *action.ActionCommandBase) (action.APIClient, error) {
    65  			return client, nil
    66  		},
    67  	)
    68  }
    69  
    70  var someCharmActions = map[string]params.ActionSpec{
    71  	"snapshot": {
    72  		Description: "Take a snapshot of the database.",
    73  		Params: map[string]interface{}{
    74  			"foo": map[string]interface{}{
    75  				"bar": "baz",
    76  			},
    77  			"baz": "bar",
    78  		},
    79  	},
    80  	"kill": {
    81  		Description: "Kill the database.",
    82  		Params: map[string]interface{}{
    83  			"bar": map[string]interface{}{
    84  				"baz": "foo",
    85  			},
    86  			"foo": "baz",
    87  		},
    88  	},
    89  	"no-description": {
    90  		Params: map[string]interface{}{
    91  			"bar": map[string]interface{}{
    92  				"baz": "foo",
    93  			},
    94  			"foo": "baz",
    95  		},
    96  	},
    97  	"no-params": {
    98  		Description: "An action with no parameters.\n",
    99  	},
   100  }
   101  
   102  // tagsForIdPrefix builds a params.FindTagResults for a given id prefix
   103  // and 0..n given tags. This is useful for stubbing out the API and
   104  // ensuring that the API returns expected tags for a given id prefix.
   105  func tagsForIdPrefix(prefix string, tags ...string) params.FindTagsResults {
   106  	entities := make([]params.Entity, len(tags))
   107  	for i, t := range tags {
   108  		entities[i] = params.Entity{Tag: t}
   109  	}
   110  	return params.FindTagsResults{Matches: map[string][]params.Entity{prefix: entities}}
   111  }
   112  
   113  // setupValueFile creates a file containing one value for testing.
   114  // cf. cmd/juju/set_test.go
   115  func setupValueFile(c *gc.C, dir, filename, value string) string {
   116  	ctx := cmdtesting.ContextForDir(c, dir)
   117  	path := ctx.AbsPath(filename)
   118  	content := []byte(value)
   119  	err := ioutil.WriteFile(path, content, 0666)
   120  	c.Assert(err, jc.ErrorIsNil)
   121  	return path
   122  }
   123  
   124  type fakeAPIClient struct {
   125  	delay              *time.Timer
   126  	timeout            *time.Timer
   127  	actionResults      []params.ActionResult
   128  	enqueuedActions    params.Actions
   129  	actionsByReceivers []params.ActionsByReceiver
   130  	actionTagMatches   params.FindTagsResults
   131  	actionsByNames     params.ActionsByNames
   132  	charmActions       map[string]params.ActionSpec
   133  	apiVersion         int
   134  	apiErr             error
   135  }
   136  
   137  var _ action.APIClient = (*fakeAPIClient)(nil)
   138  
   139  // EnqueuedActions is a testing method which shows what Actions got enqueued
   140  // by our Enqueue stub.
   141  func (c *fakeAPIClient) EnqueuedActions() params.Actions {
   142  	return c.enqueuedActions
   143  }
   144  
   145  func (c *fakeAPIClient) Close() error {
   146  	return nil
   147  }
   148  
   149  func (c *fakeAPIClient) BestAPIVersion() int {
   150  	return c.apiVersion
   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.Entities) (params.ActionResults, error) {
   177  	return params.ActionResults{
   178  		Results: c.actionResults,
   179  	}, c.apiErr
   180  }
   181  
   182  func (c *fakeAPIClient) ApplicationCharmActions(params.Entity) (map[string]params.ActionSpec, 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  }
   216  
   217  func (c *fakeAPIClient) FindActionsByNames(args params.FindActionsByNames) (params.ActionsByNames, error) {
   218  	return c.actionsByNames, c.apiErr
   219  }