// Copyright (c) HashiCorp, Inc. // SPDX-License-Identifier: MPL-2.0 package command import ( "strings" "testing" "github.com/hashicorp/nomad/api" "github.com/hashicorp/nomad/ci" "github.com/mitchellh/cli" "github.com/shoenig/test" "github.com/shoenig/test/must" ) func TestNodePoolInfoCommand_Implements(t *testing.T) { ci.Parallel(t) var _ cli.Command = &NodePoolInfoCommand{} } func TestNodePoolInfoCommand_Run(t *testing.T) { ci.Parallel(t) // Start test server. srv, client, url := testServer(t, true, nil) defer srv.Shutdown() waitForNodes(t, client) // Register test node pools. dev1 := &api.NodePool{ Name: "dev-1", Description: "Test pool", Meta: map[string]string{ "env": "test", }, SchedulerConfiguration: &api.NodePoolSchedulerConfiguration{ SchedulerAlgorithm: api.SchedulerAlgorithmSpread, }, } _, err := client.NodePools().Register(dev1, nil) must.NoError(t, err) dev1Output := ` Name = dev-1 Description = Test pool Metadata env = test Scheduler Configuration Scheduler Algorithm = spread` dev1JsonOutput := ` { "Description": "Test pool", "Meta": { "env": "test" }, "Name": "dev-1", "SchedulerConfiguration": { "SchedulerAlgorithm": "spread" } }` // These two node pools are used to test exact prefix match. prod1 := &api.NodePool{Name: "prod-1"} _, err = client.NodePools().Register(prod1, nil) must.NoError(t, err) prod12 := &api.NodePool{Name: "prod-12"} _, err = client.NodePools().Register(prod12, nil) must.NoError(t, err) testCases := []struct { name string args []string expectedOut string expectedErr string expectedCode int }{ { name: "basic info", args: []string{"dev-1"}, expectedOut: dev1Output, expectedCode: 0, }, { name: "basic info by prefix", args: []string{"dev"}, expectedOut: dev1Output, expectedCode: 0, }, { name: "exact prefix match", args: []string{"prod-1"}, expectedOut: ` Name = prod-1 Description = Metadata No metadata Scheduler Configuration No scheduler configuration`, expectedCode: 0, }, { name: "json", args: []string{"-json", "dev"}, expectedOut: dev1JsonOutput, expectedCode: 0, }, { name: "template", args: []string{ "-t", "{{.Name}} -> {{.Meta.env}}", "dev-1", }, expectedOut: "dev-1 -> test", expectedCode: 0, }, { name: "fail because of missing node pool arg", args: []string{}, expectedErr: "This command takes one argument", expectedCode: 1, }, { name: "fail because no match", args: []string{"invalid"}, expectedErr: `No node pool with prefix "invalid" found`, expectedCode: 1, }, { name: "fail because of multiple matches", args: []string{"de"}, // Matches default and dev-1. expectedErr: "Prefix matched multiple node pools", expectedCode: 1, }, { name: "fail because of invalid template", args: []string{ "-t", "{{.NotValid}}", "dev-1", }, expectedErr: "Error formatting the data", expectedCode: 1, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { // Initialize UI and command. ui := cli.NewMockUi() cmd := &NodePoolInfoCommand{Meta: Meta{Ui: ui}} // Run command. args := []string{"-address", url} args = append(args, tc.args...) code := cmd.Run(args) gotStdout := ui.OutputWriter.String() gotStdout = jsonOutputRaftIndexes.ReplaceAllString(gotStdout, "") test.Eq(t, tc.expectedCode, code) test.StrContains(t, gotStdout, strings.TrimSpace(tc.expectedOut)) test.StrContains(t, ui.ErrorWriter.String(), strings.TrimSpace(tc.expectedErr)) }) } }