github.com/hernad/nomad@v1.6.112/command/server_members_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 "fmt" 9 "strings" 10 "testing" 11 12 "github.com/hernad/nomad/api" 13 "github.com/hernad/nomad/ci" 14 "github.com/hernad/nomad/command/agent" 15 "github.com/mitchellh/cli" 16 "github.com/shoenig/test/must" 17 ) 18 19 func TestServerMembersCommand_Implements(t *testing.T) { 20 ci.Parallel(t) 21 var _ cli.Command = &ServerMembersCommand{} 22 } 23 24 func TestServerMembersCommand_Run(t *testing.T) { 25 ci.Parallel(t) 26 srv, client, url := testServer(t, false, nil) 27 defer srv.Shutdown() 28 29 ui := cli.NewMockUi() 30 cmd := &ServerMembersCommand{Meta: Meta{Ui: ui}} 31 32 // Get our own node name 33 name, err := client.Agent().NodeName() 34 must.NoError(t, err) 35 36 // Query the members 37 code := cmd.Run([]string{"-address=" + url}) 38 39 if out := ui.OutputWriter.String(); !strings.Contains(out, name) { 40 t.Fatalf("expected %q in output, got: %s", name, out) 41 } 42 ui.OutputWriter.Reset() 43 44 // Query members with verbose output 45 code = cmd.Run([]string{"-address=" + url, "-verbose"}) 46 must.Zero(t, code) 47 48 // Still support previous detailed flag 49 code = cmd.Run([]string{"-address=" + url, "-detailed"}) 50 must.Zero(t, code) 51 52 must.StrContains(t, ui.OutputWriter.String(), "Tags") 53 54 ui.OutputWriter.Reset() 55 56 // List json 57 code = cmd.Run([]string{"-address=" + url, "-json"}) 58 must.Zero(t, code) 59 60 outJson := []api.AgentMember{} 61 err = json.Unmarshal(ui.OutputWriter.Bytes(), &outJson) 62 must.NoError(t, err) 63 64 ui.OutputWriter.Reset() 65 66 // Go template to format the output 67 code = cmd.Run([]string{"-address=" + url, "-t", "{{range .}}{{ .Status }}{{end}}"}) 68 must.Zero(t, code) 69 70 out := ui.OutputWriter.String() 71 must.StrContains(t, out, "alive") 72 73 ui.ErrorWriter.Reset() 74 } 75 76 func TestMembersCommand_Fails(t *testing.T) { 77 ci.Parallel(t) 78 ui := cli.NewMockUi() 79 cmd := &ServerMembersCommand{Meta: Meta{Ui: ui}} 80 81 // Fails on misuse 82 code := cmd.Run([]string{"some", "bad", "args"}) 83 must.One(t, code) 84 85 must.StrContains(t, ui.ErrorWriter.String(), commandErrorText(cmd)) 86 ui.ErrorWriter.Reset() 87 88 // Fails on connection failure 89 code = cmd.Run([]string{"-address=nope"}) 90 must.One(t, code) 91 92 must.StrContains(t, ui.ErrorWriter.String(), "Error querying servers") 93 } 94 95 // Tests that a single server region that left should still 96 // not return an error and list other members in other regions 97 func TestServerMembersCommand_MultiRegion_Leave(t *testing.T) { 98 ci.Parallel(t) 99 100 config1 := func(c *agent.Config) { 101 c.Region = "r1" 102 c.Datacenter = "d1" 103 } 104 105 srv1, client1, url := testServer(t, false, config1) 106 defer srv1.Shutdown() 107 108 config2 := func(c *agent.Config) { 109 c.Region = "r2" 110 c.Datacenter = "d2" 111 } 112 113 srv2, _, _ := testServer(t, false, config2) 114 defer srv2.Shutdown() 115 116 // Join with srv1 117 addr := fmt.Sprintf("127.0.0.1:%d", 118 srv1.Agent.Server().GetConfig().SerfConfig.MemberlistConfig.BindPort) 119 120 _, err := srv2.Agent.Server().Join([]string{addr}) 121 must.NoError(t, err) 122 123 ui := cli.NewMockUi() 124 cmd := &ServerMembersCommand{Meta: Meta{Ui: ui}} 125 126 // Get our own node name 127 name, err := client1.Agent().NodeName() 128 must.NoError(t, err) 129 130 // Query the members 131 code := cmd.Run([]string{"-address=" + url}) 132 must.Zero(t, code) 133 134 must.StrContains(t, ui.OutputWriter.String(), name) 135 ui.OutputWriter.Reset() 136 137 // Make one of the servers leave 138 srv2.Agent.Leave() 139 140 // Query again, should still contain expected output 141 code = cmd.Run([]string{"-address=" + url}) 142 must.Zero(t, code) 143 144 must.StrContains(t, ui.OutputWriter.String(), name) 145 }