github.com/mattyr/nomad@v0.3.3-0.20160919021406-3485a065154a/api/api_test.go (about) 1 package api 2 3 import ( 4 "encoding/json" 5 "net/http" 6 "net/http/httptest" 7 "os" 8 "strings" 9 "testing" 10 "time" 11 12 "github.com/hashicorp/nomad/testutil" 13 ) 14 15 type configCallback func(c *Config) 16 17 // seen is used to track which tests we have already marked as parallel 18 var seen map[*testing.T]struct{} 19 20 func init() { 21 seen = make(map[*testing.T]struct{}) 22 } 23 24 func makeClient(t *testing.T, cb1 configCallback, 25 cb2 testutil.ServerConfigCallback) (*Client, *testutil.TestServer) { 26 // Make client config 27 conf := DefaultConfig() 28 if cb1 != nil { 29 cb1(conf) 30 } 31 32 // Create server 33 server := testutil.NewTestServer(t, cb2) 34 conf.Address = "http://" + server.HTTPAddr 35 36 // Create client 37 client, err := NewClient(conf) 38 if err != nil { 39 t.Fatalf("err: %v", err) 40 } 41 42 return client, server 43 } 44 45 func TestRequestTime(t *testing.T) { 46 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 47 time.Sleep(100 * time.Millisecond) 48 d, err := json.Marshal(struct{ Done bool }{true}) 49 if err != nil { 50 http.Error(w, err.Error(), http.StatusInternalServerError) 51 return 52 } 53 w.Write(d) 54 })) 55 defer srv.Close() 56 57 conf := DefaultConfig() 58 conf.Address = srv.URL 59 60 client, err := NewClient(conf) 61 if err != nil { 62 t.Fatalf("err: %v", err) 63 } 64 65 var out interface{} 66 67 qm, err := client.query("/", &out, nil) 68 if err != nil { 69 t.Fatalf("query err: %v", err) 70 } 71 if qm.RequestTime == 0 { 72 t.Errorf("bad request time: %d", qm.RequestTime) 73 } 74 75 wm, err := client.write("/", struct{ S string }{"input"}, &out, nil) 76 if err != nil { 77 t.Fatalf("write err: %v", err) 78 } 79 if wm.RequestTime == 0 { 80 t.Errorf("bad request time: %d", wm.RequestTime) 81 } 82 83 wm, err = client.delete("/", &out, nil) 84 if err != nil { 85 t.Fatalf("delete err: %v", err) 86 } 87 if wm.RequestTime == 0 { 88 t.Errorf("bad request time: %d", wm.RequestTime) 89 } 90 } 91 92 func TestDefaultConfig_env(t *testing.T) { 93 url := "http://1.2.3.4:5678" 94 auth := []string{"nomaduser", "12345"} 95 96 os.Setenv("NOMAD_ADDR", url) 97 defer os.Setenv("NOMAD_ADDR", "") 98 99 os.Setenv("NOMAD_HTTP_AUTH", strings.Join(auth, ":")) 100 defer os.Setenv("NOMAD_HTTP_AUTH", "") 101 102 config := DefaultConfig() 103 104 if config.Address != url { 105 t.Errorf("expected %q to be %q", config.Address, url) 106 } 107 108 if config.HttpAuth.Username != auth[0] { 109 t.Errorf("expected %q to be %q", config.HttpAuth.Username, auth[0]) 110 } 111 112 if config.HttpAuth.Password != auth[1] { 113 t.Errorf("expected %q to be %q", config.HttpAuth.Password, auth[1]) 114 } 115 } 116 117 func TestSetQueryOptions(t *testing.T) { 118 c, s := makeClient(t, nil, nil) 119 defer s.Stop() 120 121 r := c.newRequest("GET", "/v1/jobs") 122 q := &QueryOptions{ 123 Region: "foo", 124 AllowStale: true, 125 WaitIndex: 1000, 126 WaitTime: 100 * time.Second, 127 } 128 r.setQueryOptions(q) 129 130 if r.params.Get("region") != "foo" { 131 t.Fatalf("bad: %v", r.params) 132 } 133 if _, ok := r.params["stale"]; !ok { 134 t.Fatalf("bad: %v", r.params) 135 } 136 if r.params.Get("index") != "1000" { 137 t.Fatalf("bad: %v", r.params) 138 } 139 if r.params.Get("wait") != "100000ms" { 140 t.Fatalf("bad: %v", r.params) 141 } 142 } 143 144 func TestSetWriteOptions(t *testing.T) { 145 c, s := makeClient(t, nil, nil) 146 defer s.Stop() 147 148 r := c.newRequest("GET", "/v1/jobs") 149 q := &WriteOptions{ 150 Region: "foo", 151 } 152 r.setWriteOptions(q) 153 154 if r.params.Get("region") != "foo" { 155 t.Fatalf("bad: %v", r.params) 156 } 157 } 158 159 func TestRequestToHTTP(t *testing.T) { 160 c, s := makeClient(t, nil, nil) 161 defer s.Stop() 162 163 r := c.newRequest("DELETE", "/v1/jobs/foo") 164 q := &QueryOptions{ 165 Region: "foo", 166 } 167 r.setQueryOptions(q) 168 req, err := r.toHTTP() 169 if err != nil { 170 t.Fatalf("err: %v", err) 171 } 172 173 if req.Method != "DELETE" { 174 t.Fatalf("bad: %v", req) 175 } 176 if req.URL.RequestURI() != "/v1/jobs/foo?region=foo" { 177 t.Fatalf("bad: %v", req) 178 } 179 } 180 181 func TestParseQueryMeta(t *testing.T) { 182 resp := &http.Response{ 183 Header: make(map[string][]string), 184 } 185 resp.Header.Set("X-Nomad-Index", "12345") 186 resp.Header.Set("X-Nomad-LastContact", "80") 187 resp.Header.Set("X-Nomad-KnownLeader", "true") 188 189 qm := &QueryMeta{} 190 if err := parseQueryMeta(resp, qm); err != nil { 191 t.Fatalf("err: %v", err) 192 } 193 194 if qm.LastIndex != 12345 { 195 t.Fatalf("Bad: %v", qm) 196 } 197 if qm.LastContact != 80*time.Millisecond { 198 t.Fatalf("Bad: %v", qm) 199 } 200 if !qm.KnownLeader { 201 t.Fatalf("Bad: %v", qm) 202 } 203 } 204 205 func TestParseWriteMeta(t *testing.T) { 206 resp := &http.Response{ 207 Header: make(map[string][]string), 208 } 209 resp.Header.Set("X-Nomad-Index", "12345") 210 211 wm := &WriteMeta{} 212 if err := parseWriteMeta(resp, wm); err != nil { 213 t.Fatalf("err: %v", err) 214 } 215 216 if wm.LastIndex != 12345 { 217 t.Fatalf("Bad: %v", wm) 218 } 219 } 220 221 func TestQueryString(t *testing.T) { 222 c, s := makeClient(t, nil, nil) 223 defer s.Stop() 224 225 r := c.newRequest("PUT", "/v1/abc?foo=bar&baz=zip") 226 q := &WriteOptions{Region: "foo"} 227 r.setWriteOptions(q) 228 229 req, err := r.toHTTP() 230 if err != nil { 231 t.Fatalf("err: %s", err) 232 } 233 234 if uri := req.URL.RequestURI(); uri != "/v1/abc?baz=zip&foo=bar®ion=foo" { 235 t.Fatalf("bad uri: %q", uri) 236 } 237 }