github.com/mattyr/nomad@v0.3.3-0.20160919021406-3485a065154a/api/nodes_test.go (about) 1 package api 2 3 import ( 4 "fmt" 5 "reflect" 6 "sort" 7 "strings" 8 "testing" 9 "time" 10 11 "github.com/hashicorp/nomad/testutil" 12 ) 13 14 func TestNodes_List(t *testing.T) { 15 c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) { 16 c.DevMode = true 17 }) 18 defer s.Stop() 19 nodes := c.Nodes() 20 21 var qm *QueryMeta 22 var out []*NodeListStub 23 var err error 24 25 testutil.WaitForResult(func() (bool, error) { 26 out, qm, err = nodes.List(nil) 27 if err != nil { 28 return false, err 29 } 30 if n := len(out); n != 1 { 31 return false, fmt.Errorf("expected 1 node, got: %d", n) 32 } 33 return true, nil 34 }, func(err error) { 35 t.Fatalf("err: %s", err) 36 }) 37 38 // Check that we got valid QueryMeta. 39 assertQueryMeta(t, qm) 40 } 41 42 func TestNodes_PrefixList(t *testing.T) { 43 c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) { 44 c.DevMode = true 45 }) 46 defer s.Stop() 47 nodes := c.Nodes() 48 49 var qm *QueryMeta 50 var out []*NodeListStub 51 var err error 52 53 // Get the node ID 54 var nodeID string 55 testutil.WaitForResult(func() (bool, error) { 56 out, _, err := nodes.List(nil) 57 if err != nil { 58 return false, err 59 } 60 if n := len(out); n != 1 { 61 return false, fmt.Errorf("expected 1 node, got: %d", n) 62 } 63 nodeID = out[0].ID 64 return true, nil 65 }, func(err error) { 66 t.Fatalf("err: %s", err) 67 }) 68 69 // Find node based on four character prefix 70 out, qm, err = nodes.PrefixList(nodeID[:4]) 71 if err != nil { 72 t.Fatalf("err: %s", err) 73 } 74 if n := len(out); n != 1 { 75 t.Fatalf("expected 1 node, got: %d ", n) 76 } 77 78 // Check that we got valid QueryMeta. 79 assertQueryMeta(t, qm) 80 } 81 82 func TestNodes_Info(t *testing.T) { 83 startTime := time.Now().Unix() 84 c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) { 85 c.DevMode = true 86 }) 87 defer s.Stop() 88 nodes := c.Nodes() 89 90 // Retrieving a non-existent node returns error 91 _, _, err := nodes.Info("12345678-abcd-efab-cdef-123456789abc", nil) 92 if err == nil || !strings.Contains(err.Error(), "not found") { 93 t.Fatalf("expected not found error, got: %#v", err) 94 } 95 96 // Get the node ID 97 var nodeID, dc string 98 testutil.WaitForResult(func() (bool, error) { 99 out, _, err := nodes.List(nil) 100 if err != nil { 101 return false, err 102 } 103 if n := len(out); n != 1 { 104 return false, fmt.Errorf("expected 1 node, got: %d", n) 105 } 106 nodeID = out[0].ID 107 dc = out[0].Datacenter 108 return true, nil 109 }, func(err error) { 110 t.Fatalf("err: %s", err) 111 }) 112 113 // Querying for existing nodes returns properly 114 result, qm, err := nodes.Info(nodeID, nil) 115 if err != nil { 116 t.Fatalf("err: %s", err) 117 } 118 assertQueryMeta(t, qm) 119 120 // Check that the result is what we expect 121 if result.ID != nodeID || result.Datacenter != dc { 122 t.Fatalf("expected %s (%s), got: %s (%s)", 123 nodeID, dc, 124 result.ID, result.Datacenter) 125 } 126 127 // Check that the StatusUpdatedAt field is being populated correctly 128 if result.StatusUpdatedAt < startTime { 129 t.Fatalf("start time: %v, status updated: %v", startTime, result.StatusUpdatedAt) 130 } 131 } 132 133 func TestNodes_ToggleDrain(t *testing.T) { 134 c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) { 135 c.DevMode = true 136 }) 137 defer s.Stop() 138 nodes := c.Nodes() 139 140 // Wait for node registration and get the ID 141 var nodeID string 142 testutil.WaitForResult(func() (bool, error) { 143 out, _, err := nodes.List(nil) 144 if err != nil { 145 return false, err 146 } 147 if n := len(out); n != 1 { 148 return false, fmt.Errorf("expected 1 node, got: %d", n) 149 } 150 nodeID = out[0].ID 151 return true, nil 152 }, func(err error) { 153 t.Fatalf("err: %s", err) 154 }) 155 156 // Check for drain mode 157 out, _, err := nodes.Info(nodeID, nil) 158 if err != nil { 159 t.Fatalf("err: %s", err) 160 } 161 if out.Drain { 162 t.Fatalf("drain mode should be off") 163 } 164 165 // Toggle it on 166 wm, err := nodes.ToggleDrain(nodeID, true, nil) 167 if err != nil { 168 t.Fatalf("err: %s", err) 169 } 170 assertWriteMeta(t, wm) 171 172 // Check again 173 out, _, err = nodes.Info(nodeID, nil) 174 if err != nil { 175 t.Fatalf("err: %s", err) 176 } 177 if !out.Drain { 178 t.Fatalf("drain mode should be on") 179 } 180 181 // Toggle off again 182 wm, err = nodes.ToggleDrain(nodeID, false, nil) 183 if err != nil { 184 t.Fatalf("err: %s", err) 185 } 186 assertWriteMeta(t, wm) 187 188 // Check again 189 out, _, err = nodes.Info(nodeID, nil) 190 if err != nil { 191 t.Fatalf("err: %s", err) 192 } 193 if out.Drain { 194 t.Fatalf("drain mode should be off") 195 } 196 } 197 198 func TestNodes_Allocations(t *testing.T) { 199 c, s := makeClient(t, nil, nil) 200 defer s.Stop() 201 nodes := c.Nodes() 202 203 // Looking up by a non-existent node returns nothing. We 204 // don't check the index here because it's possible the node 205 // has already registered, in which case we will get a non- 206 // zero result anyways. 207 allocs, _, err := nodes.Allocations("nope", nil) 208 if err != nil { 209 t.Fatalf("err: %s", err) 210 } 211 if n := len(allocs); n != 0 { 212 t.Fatalf("expected 0 allocs, got: %d", n) 213 } 214 } 215 216 func TestNodes_ForceEvaluate(t *testing.T) { 217 c, s := makeClient(t, nil, func(c *testutil.TestServerConfig) { 218 c.DevMode = true 219 }) 220 defer s.Stop() 221 nodes := c.Nodes() 222 223 // Force-eval on a non-existent node fails 224 _, _, err := nodes.ForceEvaluate("12345678-abcd-efab-cdef-123456789abc", nil) 225 if err == nil || !strings.Contains(err.Error(), "not found") { 226 t.Fatalf("expected not found error, got: %#v", err) 227 } 228 229 // Wait for node registration and get the ID 230 var nodeID string 231 testutil.WaitForResult(func() (bool, error) { 232 out, _, err := nodes.List(nil) 233 if err != nil { 234 return false, err 235 } 236 if n := len(out); n != 1 { 237 return false, fmt.Errorf("expected 1 node, got: %d", n) 238 } 239 nodeID = out[0].ID 240 return true, nil 241 }, func(err error) { 242 t.Fatalf("err: %s", err) 243 }) 244 245 // Try force-eval again. We don't check the WriteMeta because 246 // there are no allocations to process, so we would get an index 247 // of zero. Same goes for the eval ID. 248 _, _, err = nodes.ForceEvaluate(nodeID, nil) 249 if err != nil { 250 t.Fatalf("err: %s", err) 251 } 252 } 253 254 func TestNodes_Sort(t *testing.T) { 255 nodes := []*NodeListStub{ 256 &NodeListStub{CreateIndex: 2}, 257 &NodeListStub{CreateIndex: 1}, 258 &NodeListStub{CreateIndex: 5}, 259 } 260 sort.Sort(NodeIndexSort(nodes)) 261 262 expect := []*NodeListStub{ 263 &NodeListStub{CreateIndex: 5}, 264 &NodeListStub{CreateIndex: 2}, 265 &NodeListStub{CreateIndex: 1}, 266 } 267 if !reflect.DeepEqual(nodes, expect) { 268 t.Fatalf("\n\n%#v\n\n%#v", nodes, expect) 269 } 270 }