From c0e26850eb5acbd6019961a5e22a3fb187601065 Mon Sep 17 00:00:00 2001 From: Simon Richardson Date: Tue, 17 Dec 2019 11:20:14 +0000 Subject: [PATCH] Display clouds integration tests The following changes introduce the idea of a display clouds integration tests. Unfortunately it required to change how we handle machine interactions. For formatting directives such as json or yaml, we never want to be prompted for anything, we just either want an empty output in the right format (json being {}) or the data. Bringing in the changes is the first drive into doing so, the PR doesn't enforce the changes through out, although it is a first step in doing so. Adding redirection of the stderr to /dev/null for machine directives is pointless, so in the future checking for ctx.IsSerial() should be used. If the value is true then omitting the information and the noise is probably the wisest. --- Gopkg.lock | 6 +- Gopkg.toml | 2 +- cmd/juju/application/show.go | 2 +- cmd/juju/cloud/list.go | 7 +++ tests/suites/cli/clouds/public-clouds.yaml | 7 +++ tests/suites/cli/display_clouds.sh | 57 +++++++++++++++++++ .../{use_local_charm.sh => local_charms.sh} | 0 tests/suites/cli/task.sh | 7 ++- worker/uniter/runner/jujuc/action-get.go | 2 +- worker/uniter/runner/jujuc/config-get.go | 2 +- worker/uniter/runner/jujuc/credential-get.go | 2 +- worker/uniter/runner/jujuc/is-leader.go | 2 +- worker/uniter/runner/jujuc/leader-get.go | 2 +- worker/uniter/runner/jujuc/network-get.go | 2 +- worker/uniter/runner/jujuc/opened-ports.go | 2 +- worker/uniter/runner/jujuc/relation-get.go | 2 +- worker/uniter/runner/jujuc/relation-ids.go | 2 +- worker/uniter/runner/jujuc/relation-list.go | 2 +- worker/uniter/runner/jujuc/status-get.go | 2 +- worker/uniter/runner/jujuc/storage-get.go | 2 +- worker/uniter/runner/jujuc/storage-list.go | 2 +- worker/uniter/runner/jujuc/unit-get.go | 2 +- 22 files changed, 95 insertions(+), 21 deletions(-) create mode 100644 tests/suites/cli/clouds/public-clouds.yaml create mode 100644 tests/suites/cli/display_clouds.sh rename tests/suites/cli/{use_local_charm.sh => local_charms.sh} (100%) diff --git a/Gopkg.lock b/Gopkg.lock index bf56debefcfb..2cfa50c1bf54 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -457,14 +457,14 @@ revision = "9c5c9712527c7986f012361e7d13756b4d99543d" [[projects]] - digest = "1:68bc775aba55be0a3e178439988ba7daf3a86b805942a251146277ea506f935f" + digest = "1:b42ffaefe5a54402a7ff3c1f1540ec4c89d8d5a7ce1dac4eff994bff759f6388" name = "github.com/juju/cmd" packages = [ ".", "cmdtesting", ] pruneopts = "" - revision = "74922f23f6436a661dacd8c5fdf9cb15641e7a2e" + revision = "3494531d4f0091d4d43a19b4ace7b87e13995c74" [[projects]] digest = "1:243ec2217cb77ad028a956bf4d886b0f070d2dbfe861ceadfcf270412c2e7b90" @@ -1505,7 +1505,9 @@ packages = [ "bakery", "bakery/checkers", + "bakery/identchecker", "bakery/internal/macaroonpb", + "bakerytest", "httpbakery", "httpbakery/form", "internal/httputil", diff --git a/Gopkg.toml b/Gopkg.toml index 5c5ef5ae52f5..f8f3d3ad53ca 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -285,7 +285,7 @@ [[constraint]] name = "github.com/juju/cmd" - revision = "74922f23f6436a661dacd8c5fdf9cb15641e7a2e" + revision = "3494531d4f0091d4d43a19b4ace7b87e13995c74" [[constraint]] name = "github.com/juju/collections" diff --git a/cmd/juju/application/show.go b/cmd/juju/application/show.go index 06d00ca76ac1..e8f5f6e5bff8 100644 --- a/cmd/juju/application/show.go +++ b/cmd/juju/application/show.go @@ -86,7 +86,7 @@ func (c *showApplicationCommand) Init(args []string) error { // SetFlags implements Command.SetFlags. func (c *showApplicationCommand) SetFlags(f *gnuflag.FlagSet) { c.ModelCommandBase.SetFlags(f) - c.out.AddFlags(f, "yaml", cmd.DefaultFormatters) + c.out.AddFlags(f, "yaml", cmd.DefaultFormatters.Formatters()) } // ApplicationsInfoAPI defines the API methods that show-application command uses. diff --git a/cmd/juju/cloud/list.go b/cmd/juju/cloud/list.go index 1e7ea02140d2..90399ac50c10 100644 --- a/cmd/juju/cloud/list.go +++ b/cmd/juju/cloud/list.go @@ -175,9 +175,16 @@ func (c *listCloudsCommand) getCloudList(ctxt *cmd.Context) (*cloudList, error) } func (c *listCloudsCommand) Run(ctxt *cmd.Context) error { + // TODO: is serial states that it's machine serialisable. We shouldn't + // prompt in those situations. In an ideal world we would move this into + // MaybePrompt, but the changes may have unintended consequences without + // proper understanding. + // Should fix this for Juju 3.0 + c.ReadOnly = ctxt.IsSerial() if err := c.MaybePrompt(ctxt, "list clouds from"); err != nil { return errors.Trace(err) } + details, err := c.getCloudList(ctxt) if err != nil { return errors.Trace(err) diff --git a/tests/suites/cli/clouds/public-clouds.yaml b/tests/suites/cli/clouds/public-clouds.yaml new file mode 100644 index 000000000000..279ad7d417a3 --- /dev/null +++ b/tests/suites/cli/clouds/public-clouds.yaml @@ -0,0 +1,7 @@ +clouds: + vmaas: + type: maas + auth-types: [oauth1] + endpoint: http://192.168.1.21/MAAS + regions: + default: {} \ No newline at end of file diff --git a/tests/suites/cli/display_clouds.sh b/tests/suites/cli/display_clouds.sh new file mode 100644 index 000000000000..9497fb0ef038 --- /dev/null +++ b/tests/suites/cli/display_clouds.sh @@ -0,0 +1,57 @@ +run_show_clouds() { + echo + + mkdir -p "${TEST_DIR}/juju" + echo "" >> "${TEST_DIR}/juju/public-clouds.yaml" + echo "" >> "${TEST_DIR}/juju/credentials.yaml" + + OUT=$(XDG_DATA_HOME="${TEST_DIR}" juju clouds --local --format=json 2>/dev/null | jq ".[] | select(.defined != \"built-in\")") + if [ -n "${OUT}" ]; then + echo "expected empty ${OUT}" + exit 1 + fi + + cp ./tests/suites/cli/clouds/public-clouds.yaml "${TEST_DIR}"/juju/public-clouds.yaml + OUT=$(XDG_DATA_HOME="${TEST_DIR}" juju clouds --local --format=json 2>/dev/null | jq ".[] | select(.defined != \"built-in\")") + if [ -n "${OUT}" ]; then + echo "expected empty ${OUT}" + exit 1 + fi + + EXPECTED=$(cat <<'EOF' +{ + "defined": "public", + "type": "maas", + "description": "Metal As A Service", + "auth-types": [ + "oauth1" + ], + "endpoint": "http://192.168.1.21/MAAS", + "regions": { + "default": {} + } +} +EOF + ) + + OUT=$(XDG_DATA_HOME="${TEST_DIR}" juju clouds --all --format=json 2>/dev/null | jq ".[] | select(.defined != \"built-in\")") + if [ "${OUT}" != "${EXPECTED}" ]; then + echo "expected ${EXPECTED}, got ${OUT}" + exit 1 + fi +} + +test_display_clouds() { + if [ "$(skip 'test_display_clouds')" ]; then + echo "==> TEST SKIPPED: display clouds" + return + fi + + ( + set_verbosity + + cd .. || exit + + run "run_show_clouds" + ) +} diff --git a/tests/suites/cli/use_local_charm.sh b/tests/suites/cli/local_charms.sh similarity index 100% rename from tests/suites/cli/use_local_charm.sh rename to tests/suites/cli/local_charms.sh diff --git a/tests/suites/cli/task.sh b/tests/suites/cli/task.sh index 512af0ba8328..7b2a2dc99cb8 100644 --- a/tests/suites/cli/task.sh +++ b/tests/suites/cli/task.sh @@ -9,11 +9,12 @@ test_cli() { echo "==> Checking for dependencies" check_dependencies juju - file="${TEST_DIR}/test-local-charms.txt" + file="${TEST_DIR}/test-cli.txt" - bootstrap "test-local-charms" "${file}" + bootstrap "test-cli" "${file}" + test_display_clouds test_local_charms - destroy_controller "test-local-charms" + destroy_controller "test-cli" } diff --git a/worker/uniter/runner/jujuc/action-get.go b/worker/uniter/runner/jujuc/action-get.go index 47c821753ccd..a6797d8df1cf 100644 --- a/worker/uniter/runner/jujuc/action-get.go +++ b/worker/uniter/runner/jujuc/action-get.go @@ -47,7 +47,7 @@ map as needed. // SetFlags handles known option flags; in this case, [--output={json|yaml}] // and --help. func (c *ActionGetCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) } // Init makes sure there are no additional unknown arguments to action-get. diff --git a/worker/uniter/runner/jujuc/config-get.go b/worker/uniter/runner/jujuc/config-get.go index 9f161d8ad5f3..f7d2ddff632a 100644 --- a/worker/uniter/runner/jujuc/config-get.go +++ b/worker/uniter/runner/jujuc/config-get.go @@ -40,7 +40,7 @@ reported as null. and --all are mutually exclusive. } func (c *ConfigGetCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) f.BoolVar(&c.All, "a", false, "print all keys") f.BoolVar(&c.All, "all", false, "") } diff --git a/worker/uniter/runner/jujuc/credential-get.go b/worker/uniter/runner/jujuc/credential-get.go index 48c9e8fc4453..2730edf8f7d7 100644 --- a/worker/uniter/runner/jujuc/credential-get.go +++ b/worker/uniter/runner/jujuc/credential-get.go @@ -38,7 +38,7 @@ credential-get returns the cloud specification used by the unit's model. // SetFlags is part of the cmd.Command interface. func (c *CredentialGetCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) } // Init is part of the cmd.Command interface. diff --git a/worker/uniter/runner/jujuc/is-leader.go b/worker/uniter/runner/jujuc/is-leader.go index 1a0c03ee386f..482091ccdff8 100644 --- a/worker/uniter/runner/jujuc/is-leader.go +++ b/worker/uniter/runner/jujuc/is-leader.go @@ -39,7 +39,7 @@ there is no such guarantee. // SetFlags is part of the cmd.Command interface. func (c *isLeaderCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) } // Run is part of the cmd.Command interface. diff --git a/worker/uniter/runner/jujuc/leader-get.go b/worker/uniter/runner/jujuc/leader-get.go index 31eb66904daf..570479b46b8b 100644 --- a/worker/uniter/runner/jujuc/leader-get.go +++ b/worker/uniter/runner/jujuc/leader-get.go @@ -42,7 +42,7 @@ is given, or if the key is "-", all keys and values will be printed. // SetFlags is part of the cmd.Command interface. func (c *leaderGetCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) } // Init is part of the cmd.Command interface. diff --git a/worker/uniter/runner/jujuc/network-get.go b/worker/uniter/runner/jujuc/network-get.go index a3c53f24222d..dc26efbc929f 100644 --- a/worker/uniter/runner/jujuc/network-get.go +++ b/worker/uniter/runner/jujuc/network-get.go @@ -75,7 +75,7 @@ If more than one flag is specified, a map of values is returned. // SetFlags is part of the cmd.Command interface. func (c *NetworkGetCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) f.BoolVar(&c.primaryAddress, "primary-address", false, "(deprecated) get the primary address for the binding") f.BoolVar(&c.bindAddress, "bind-address", false, "get the address for the binding on which the unit should listen") f.BoolVar(&c.ingressAddress, "ingress-address", false, "get the ingress address for the binding") diff --git a/worker/uniter/runner/jujuc/opened-ports.go b/worker/uniter/runner/jujuc/opened-ports.go index 7c3a91727619..4ae29c768d5c 100644 --- a/worker/uniter/runner/jujuc/opened-ports.go +++ b/worker/uniter/runner/jujuc/opened-ports.go @@ -32,7 +32,7 @@ func (c *OpenedPortsCommand) Info() *cmd.Info { } func (c *OpenedPortsCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) } func (c *OpenedPortsCommand) Init(args []string) error { diff --git a/worker/uniter/runner/jujuc/relation-get.go b/worker/uniter/runner/jujuc/relation-get.go index 87c53d4978bc..42c05934c87e 100644 --- a/worker/uniter/runner/jujuc/relation-get.go +++ b/worker/uniter/runner/jujuc/relation-get.go @@ -71,7 +71,7 @@ leader. // SetFlags is part of the cmd.Command interface. func (c *RelationGetCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) f.Var(c.relationIdProxy, "r", "Specify a relation by id") f.Var(c.relationIdProxy, "relation", "") diff --git a/worker/uniter/runner/jujuc/relation-ids.go b/worker/uniter/runner/jujuc/relation-ids.go index 6c1df6924f1c..d5e566fb8aa9 100644 --- a/worker/uniter/runner/jujuc/relation-ids.go +++ b/worker/uniter/runner/jujuc/relation-ids.go @@ -52,7 +52,7 @@ func (c *RelationIdsCommand) Info() *cmd.Info { } func (c *RelationIdsCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) } func (c *RelationIdsCommand) Init(args []string) error { diff --git a/worker/uniter/runner/jujuc/relation-list.go b/worker/uniter/runner/jujuc/relation-list.go index 8b6eeb9933a0..e539a362f8c6 100644 --- a/worker/uniter/runner/jujuc/relation-list.go +++ b/worker/uniter/runner/jujuc/relation-list.go @@ -48,7 +48,7 @@ func (c *RelationListCommand) Info() *cmd.Info { } func (c *RelationListCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) f.Var(c.relationIdProxy, "r", "specify a relation by id") f.Var(c.relationIdProxy, "relation", "") } diff --git a/worker/uniter/runner/jujuc/status-get.go b/worker/uniter/runner/jujuc/status-get.go index 5f2a2c8661b3..ff68efbad5a9 100644 --- a/worker/uniter/runner/jujuc/status-get.go +++ b/worker/uniter/runner/jujuc/status-get.go @@ -39,7 +39,7 @@ If the --include-data flag is passed, the associated data are printed also. } func (c *StatusGetCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) f.BoolVar(&c.includeData, "include-data", false, "print all status data") f.BoolVar(&c.applicationWide, "application", false, "print status for all units of this application if this unit is the leader") } diff --git a/worker/uniter/runner/jujuc/storage-get.go b/worker/uniter/runner/jujuc/storage-get.go index 39cc2c1db11b..a4b2b870aebe 100644 --- a/worker/uniter/runner/jujuc/storage-get.go +++ b/worker/uniter/runner/jujuc/storage-get.go @@ -45,7 +45,7 @@ When no is supplied, all keys values are printed. } func (c *StorageGetCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) f.Var(c.storageTagProxy, "s", "specify a storage instance by id") } diff --git a/worker/uniter/runner/jujuc/storage-list.go b/worker/uniter/runner/jujuc/storage-list.go index 9002b2629cef..7eaef0ca5931 100644 --- a/worker/uniter/runner/jujuc/storage-list.go +++ b/worker/uniter/runner/jujuc/storage-list.go @@ -44,7 +44,7 @@ instances for that named storage will be returned. } func (c *StorageListCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) } func (c *StorageListCommand) Init(args []string) (err error) { diff --git a/worker/uniter/runner/jujuc/unit-get.go b/worker/uniter/runner/jujuc/unit-get.go index de91889e8e2c..01691f303f42 100644 --- a/worker/uniter/runner/jujuc/unit-get.go +++ b/worker/uniter/runner/jujuc/unit-get.go @@ -35,7 +35,7 @@ func (c *UnitGetCommand) Info() *cmd.Info { } func (c *UnitGetCommand) SetFlags(f *gnuflag.FlagSet) { - c.out.AddFlags(f, "smart", cmd.DefaultFormatters) + c.out.AddFlags(f, "smart", cmd.DefaultFormatters.Formatters()) } func (c *UnitGetCommand) Init(args []string) error {