github.com/ryanslade/nomad@v0.2.4-0.20160128061903-fc95782f2089/api/api_test.go (about)

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