github.com/hernad/nomad@v1.6.112/command/alloc_checks_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package command
     5  
     6  import (
     7  	"encoding/json"
     8  	"testing"
     9  
    10  	"github.com/hernad/nomad/api"
    11  	"github.com/hernad/nomad/ci"
    12  	"github.com/hernad/nomad/nomad/mock"
    13  	"github.com/hernad/nomad/nomad/structs"
    14  	"github.com/mitchellh/cli"
    15  	"github.com/posener/complete"
    16  	"github.com/shoenig/test/must"
    17  )
    18  
    19  func TestAllocChecksCommand_Implements(t *testing.T) {
    20  	ci.Parallel(t)
    21  	var _ cli.Command = (*AllocChecksCommand)(nil)
    22  }
    23  
    24  func TestAllocChecksCommand_Fails(t *testing.T) {
    25  	ci.Parallel(t)
    26  	srv, _, url := testServer(t, false, nil)
    27  	defer srv.Shutdown()
    28  
    29  	ui := cli.NewMockUi()
    30  	cmd := &AllocChecksCommand{Meta: Meta{Ui: ui}}
    31  
    32  	// fails on misuse t.Run("fails on misuse", func(t *testing.T) {
    33  	code := cmd.Run([]string{"some", "bad", "args"})
    34  	must.One(t, code)
    35  	out := ui.ErrorWriter.String()
    36  	must.StrContains(t, out, commandErrorText(cmd))
    37  
    38  	ui.ErrorWriter.Reset()
    39  
    40  	// fails on connection failure
    41  	code = cmd.Run([]string{"-address=nope", "foobar"})
    42  	must.One(t, code)
    43  	out = ui.ErrorWriter.String()
    44  	must.StrContains(t, out, "Error querying allocation")
    45  
    46  	ui.ErrorWriter.Reset()
    47  
    48  	// fails on missing allocation
    49  	code = cmd.Run([]string{"-address=" + url, "26470238-5CF2-438F-8772-DC67CFB0705C"})
    50  	must.One(t, code)
    51  	out = ui.ErrorWriter.String()
    52  	must.StrContains(t, out, "No allocation(s) with prefix or id")
    53  
    54  	ui.ErrorWriter.Reset()
    55  
    56  	// fails on prefix with too few characters
    57  	code = cmd.Run([]string{"-address=" + url, "2"})
    58  	must.One(t, code)
    59  	out = ui.ErrorWriter.String()
    60  	must.StrContains(t, out, "must contain at least two characters.")
    61  
    62  	ui.ErrorWriter.Reset()
    63  }
    64  
    65  func TestAllocChecksCommand_AutocompleteArgs(t *testing.T) {
    66  	ci.Parallel(t)
    67  
    68  	srv, _, url := testServer(t, true, nil)
    69  	defer srv.Shutdown()
    70  
    71  	ui := cli.NewMockUi()
    72  	cmd := &AllocChecksCommand{Meta: Meta{Ui: ui, flagAddress: url}}
    73  
    74  	// Create a fake alloc
    75  	state := srv.Agent.Server().State()
    76  	a := mock.Alloc()
    77  	must.NoError(t, state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a}))
    78  
    79  	prefix := a.ID[:5]
    80  	args := complete.Args{Last: prefix}
    81  	predictor := cmd.AutocompleteArgs()
    82  
    83  	res := predictor.Predict(args)
    84  	must.Len(t, 1, res)
    85  	must.Eq(t, a.ID, res[0])
    86  }
    87  
    88  func TestAllocChecksCommand_Run(t *testing.T) {
    89  	ci.Parallel(t)
    90  	srv, client, url := testServer(t, true, nil)
    91  
    92  	defer srv.Shutdown()
    93  
    94  	// wait for nodes
    95  	waitForNodes(t, client)
    96  
    97  	jobID := "job1_checks"
    98  	job1 := testNomadServiceJob(jobID)
    99  
   100  	resp, _, err := client.Jobs().Register(job1, nil)
   101  	must.NoError(t, err)
   102  
   103  	// wait for registration success
   104  	ui := cli.NewMockUi()
   105  	code := waitForSuccess(ui, client, fullId, t, resp.EvalID)
   106  	must.Zero(t, code)
   107  
   108  	// Get an alloc id
   109  	allocID := getAllocFromJob(t, client, jobID)
   110  
   111  	// do not wait for alloc running - it will stay pending because the
   112  	// health-check will never pass
   113  
   114  	// Run command
   115  	cmd := &AllocChecksCommand{Meta: Meta{Ui: ui, flagAddress: url}}
   116  	code = cmd.Run([]string{"-address=" + url, allocID})
   117  	must.Zero(t, code)
   118  
   119  	// check output
   120  	out := ui.OutputWriter.String()
   121  	must.StrContains(t, out, `Name       =  check1`)
   122  	must.StrContains(t, out, `Group      =  job1_checks.group1[0]`)
   123  	must.StrContains(t, out, `Task       =  (group)`)
   124  	must.StrContains(t, out, `Service    =  service1`)
   125  	must.StrContains(t, out, `Mode       =  healthiness`)
   126  
   127  	ui.OutputWriter.Reset()
   128  
   129  	// List json
   130  	cmd = &AllocChecksCommand{Meta: Meta{Ui: ui, flagAddress: url}}
   131  	must.Zero(t, cmd.Run([]string{"-address=" + url, "-json", allocID}))
   132  
   133  	outJson := api.AllocCheckStatuses{}
   134  	err = json.Unmarshal(ui.OutputWriter.Bytes(), &outJson)
   135  	must.NoError(t, err)
   136  
   137  	ui.OutputWriter.Reset()
   138  
   139  	// Go template to format the output
   140  	code = cmd.Run([]string{"-address=" + url, "-t", "{{range .}}{{ .Status }}{{end}}", allocID})
   141  	must.Zero(t, code)
   142  
   143  	out = ui.OutputWriter.String()
   144  	must.StrContains(t, out, "failure")
   145  
   146  	ui.OutputWriter.Reset()
   147  	ui.ErrorWriter.Reset()
   148  }