open-nomad/command/node_pool_apply_test.go

207 lines
4.9 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package command
import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"github.com/hashicorp/nomad/ci"
"github.com/mitchellh/cli"
"github.com/shoenig/test"
"github.com/shoenig/test/must"
)
func TestNodePoolApplyCommand_Implements(t *testing.T) {
ci.Parallel(t)
var _ cli.Command = &NodePoolApplyCommand{}
}
func TestNodePoolApplyCommand_Run(t *testing.T) {
ci.Parallel(t)
// Start test server.
srv, client, url := testServer(t, true, nil)
defer srv.Shutdown()
waitForNodes(t, client)
// Initialize UI and command.
ui := cli.NewMockUi()
cmd := &NodePoolApplyCommand{Meta: Meta{Ui: ui}}
// Create node pool with HCL file.
hclTestFile := `
node_pool "dev" {
description = "dev node pool"
}`
file, err := os.CreateTemp(t.TempDir(), "node-pool-test-*.hcl")
must.NoError(t, err)
_, err = file.WriteString(hclTestFile)
must.NoError(t, err)
// Run command.
args := []string{"-address", url, file.Name()}
code := cmd.Run(args)
must.Eq(t, 0, code)
// Verify node pool was created.
got, err := srv.Agent.Server().State().NodePoolByName(nil, "dev")
must.NoError(t, err)
must.NotNil(t, got)
// Update node pool.
file.Truncate(0)
file.Seek(0, 0)
hclTestFile = `
node_pool "dev" {
description = "dev node pool"
meta {
test = "true"
}
}`
_, err = file.WriteString(hclTestFile)
must.NoError(t, err)
// Run command.
code = cmd.Run(args)
must.Eq(t, 0, code)
// Verify node pool was updated.
got, err = srv.Agent.Server().State().NodePoolByName(nil, "dev")
must.NoError(t, err)
must.NotNil(t, got)
must.NotNil(t, got.Meta)
must.Eq(t, "true", got.Meta["test"])
// Create node pool with JSON file.
jsonTestFile := `
{
"Name": "prod",
"Description": "prod node pool"
}`
file, err = os.CreateTemp(t.TempDir(), "node-pool-test-*.json")
must.NoError(t, err)
_, err = file.WriteString(jsonTestFile)
must.NoError(t, err)
// Run command.
args = []string{"-address", url, "-json", file.Name()}
code = cmd.Run(args)
must.Eq(t, 0, code)
// Verify node pool was created.
got, err = srv.Agent.Server().State().NodePoolByName(nil, "prod")
must.NoError(t, err)
must.NotNil(t, got)
}
func TestNodePoolApplyCommand_Run_fail(t *testing.T) {
ci.Parallel(t)
// Start test server.
srv, client, url := testServer(t, true, nil)
defer srv.Shutdown()
waitForNodes(t, client)
testCases := []struct {
name string
args []string
input string
expectedOutput string
expectedCode int
}{
{
name: "missing file",
args: []string{},
expectedOutput: "This command takes one argument",
expectedCode: 1,
},
{
name: "file doesn't exist",
args: []string{"doesn-exist.hcl"},
expectedOutput: "no such file",
expectedCode: 1,
},
{
name: "invalid json",
args: []string{"-json", "invalid.json"},
input: "not json",
expectedOutput: "Failed to parse input",
expectedCode: 1,
},
{
name: "invalid hcl",
args: []string{"invalid.hcl"},
input: "not HCL",
expectedOutput: "Failed to parse input",
expectedCode: 1,
},
{
name: "valid json without json flag",
args: []string{"valid.json"},
input: `{"Name": "dev"}`,
expectedOutput: "Failed to parse input",
expectedCode: 1,
},
{
name: "valid hcl with json flag",
args: []string{"-json", "valid.hcl"},
input: `node_pool "dev" {}`,
expectedOutput: "Failed to parse input",
expectedCode: 1,
},
{
name: "invalid node pool hcl",
args: []string{"invalid.hcl"},
input: `not_a_node_pool "dev" {}`,
expectedOutput: "Failed to parse input",
expectedCode: 1,
},
{
name: "invalid node pool",
args: []string{"-address", url, "invalid_node_pool.hcl"},
input: `node_pool "invalid name" {}`,
expectedOutput: "Error applying node pool",
expectedCode: 1,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Initialize UI and command.
ui := cli.NewMockUi()
cmd := &NodePoolApplyCommand{Meta: Meta{Ui: ui}}
// Write input to file.
if tc.input != "" {
// Split the filename and extension from the last argument to
// add a "*" between them so os.CreateTemp retains the file
// extension.
filename := tc.args[len(tc.args)-1]
ext := filepath.Ext(filename)
name, _ := strings.CutSuffix(filename, ext)
file, err := os.CreateTemp(t.TempDir(), fmt.Sprintf("%s-*%s", name, ext))
must.NoError(t, err)
_, err = file.WriteString(tc.input)
must.NoError(t, err)
// Update last arg with full test file path.
tc.args[len(tc.args)-1] = file.Name()
}
got := cmd.Run(tc.args)
test.Eq(t, tc.expectedCode, got)
test.StrContains(t, ui.ErrorWriter.String(), tc.expectedOutput)
})
}
}