github.com/diptanu/nomad@v0.5.7-0.20170516172507-d72e86cbe3d9/command/helpers_test.go (about)

     1  package command
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"os"
     9  	"reflect"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/hashicorp/nomad/api"
    15  	"github.com/hashicorp/nomad/helper"
    16  	"github.com/hashicorp/nomad/helper/flatmap"
    17  	"github.com/kr/pretty"
    18  	"github.com/mitchellh/cli"
    19  )
    20  
    21  func TestHelpers_FormatKV(t *testing.T) {
    22  	in := []string{"alpha|beta", "charlie|delta", "echo|"}
    23  	out := formatKV(in)
    24  
    25  	expect := "alpha   = beta\n"
    26  	expect += "charlie = delta\n"
    27  	expect += "echo    = <none>"
    28  
    29  	if out != expect {
    30  		t.Fatalf("expect: %s, got: %s", expect, out)
    31  	}
    32  }
    33  
    34  func TestHelpers_FormatList(t *testing.T) {
    35  	in := []string{"alpha|beta||delta"}
    36  	out := formatList(in)
    37  
    38  	expect := "alpha  beta  <none>  delta"
    39  
    40  	if out != expect {
    41  		t.Fatalf("expect: %s, got: %s", expect, out)
    42  	}
    43  }
    44  
    45  func TestHelpers_NodeID(t *testing.T) {
    46  	srv, _, _ := testServer(t, nil)
    47  	defer srv.Stop()
    48  
    49  	meta := Meta{Ui: new(cli.MockUi)}
    50  	client, err := meta.Client()
    51  	if err != nil {
    52  		t.FailNow()
    53  	}
    54  
    55  	// This is because there is no client
    56  	if _, err := getLocalNodeID(client); err == nil {
    57  		t.Fatalf("getLocalNodeID() should fail")
    58  	}
    59  }
    60  
    61  func TestHelpers_LineLimitReader_NoTimeLimit(t *testing.T) {
    62  	helloString := `hello
    63  world
    64  this
    65  is
    66  a
    67  test`
    68  
    69  	noLines := "jskdfhjasdhfjkajkldsfdlsjkahfkjdsafa"
    70  
    71  	cases := []struct {
    72  		Input       string
    73  		Output      string
    74  		Lines       int
    75  		SearchLimit int
    76  	}{
    77  		{
    78  			Input:       helloString,
    79  			Output:      helloString,
    80  			Lines:       6,
    81  			SearchLimit: 1000,
    82  		},
    83  		{
    84  			Input: helloString,
    85  			Output: `world
    86  this
    87  is
    88  a
    89  test`,
    90  			Lines:       5,
    91  			SearchLimit: 1000,
    92  		},
    93  		{
    94  			Input:       helloString,
    95  			Output:      `test`,
    96  			Lines:       1,
    97  			SearchLimit: 1000,
    98  		},
    99  		{
   100  			Input:       helloString,
   101  			Output:      "",
   102  			Lines:       0,
   103  			SearchLimit: 1000,
   104  		},
   105  		{
   106  			Input:       helloString,
   107  			Output:      helloString,
   108  			Lines:       6,
   109  			SearchLimit: 1, // Exceed the limit
   110  		},
   111  		{
   112  			Input:       noLines,
   113  			Output:      noLines,
   114  			Lines:       10,
   115  			SearchLimit: 1000,
   116  		},
   117  		{
   118  			Input:       noLines,
   119  			Output:      noLines,
   120  			Lines:       10,
   121  			SearchLimit: 2,
   122  		},
   123  	}
   124  
   125  	for i, c := range cases {
   126  		in := ioutil.NopCloser(strings.NewReader(c.Input))
   127  		limit := NewLineLimitReader(in, c.Lines, c.SearchLimit, 0)
   128  		outBytes, err := ioutil.ReadAll(limit)
   129  		if err != nil {
   130  			t.Fatalf("case %d failed: %v", i, err)
   131  		}
   132  
   133  		out := string(outBytes)
   134  		if out != c.Output {
   135  			t.Fatalf("case %d: got %q; want %q", i, out, c.Output)
   136  		}
   137  	}
   138  }
   139  
   140  type testReadCloser struct {
   141  	data chan []byte
   142  }
   143  
   144  func (t *testReadCloser) Read(p []byte) (n int, err error) {
   145  	select {
   146  	case b, ok := <-t.data:
   147  		if !ok {
   148  			return 0, io.EOF
   149  		}
   150  
   151  		return copy(p, b), nil
   152  	case <-time.After(10 * time.Millisecond):
   153  		return 0, nil
   154  	}
   155  }
   156  
   157  func (t *testReadCloser) Close() error {
   158  	close(t.data)
   159  	return nil
   160  }
   161  
   162  func TestHelpers_LineLimitReader_TimeLimit(t *testing.T) {
   163  	// Create the test reader
   164  	in := &testReadCloser{data: make(chan []byte)}
   165  
   166  	// Set up the reader such that it won't hit the line/buffer limit and could
   167  	// only terminate if it hits the time limit
   168  	limit := NewLineLimitReader(in, 1000, 1000, 100*time.Millisecond)
   169  
   170  	expected := []byte("hello world")
   171  
   172  	resultCh := make(chan struct{})
   173  	go func() {
   174  		outBytes, err := ioutil.ReadAll(limit)
   175  		if err != nil {
   176  			t.Fatalf("ReadAll failed: %v", err)
   177  		}
   178  
   179  		if reflect.DeepEqual(outBytes, expected) {
   180  			close(resultCh)
   181  			return
   182  		}
   183  	}()
   184  
   185  	// Send the data
   186  	in.data <- expected
   187  	in.Close()
   188  
   189  	select {
   190  	case <-resultCh:
   191  	case <-time.After(1 * time.Second):
   192  		t.Fatalf("did not exit by time limit")
   193  	}
   194  }
   195  
   196  const (
   197  	job = `job "job1" {
   198          type = "service"
   199          datacenters = [ "dc1" ]
   200          group "group1" {
   201                  count = 1
   202                  task "task1" {
   203                          driver = "exec"
   204                          resources = {}
   205                  }
   206                  restart{
   207                          attempts = 10
   208                          mode = "delay"
   209  						interval = "15s"
   210                  }
   211          }
   212  }`
   213  )
   214  
   215  var (
   216  	expectedApiJob = &api.Job{
   217  		ID:          helper.StringToPtr("job1"),
   218  		Name:        helper.StringToPtr("job1"),
   219  		Type:        helper.StringToPtr("service"),
   220  		Datacenters: []string{"dc1"},
   221  		TaskGroups: []*api.TaskGroup{
   222  			{
   223  				Name:  helper.StringToPtr("group1"),
   224  				Count: helper.IntToPtr(1),
   225  				RestartPolicy: &api.RestartPolicy{
   226  					Attempts: helper.IntToPtr(10),
   227  					Interval: helper.TimeToPtr(15 * time.Second),
   228  					Mode:     helper.StringToPtr("delay"),
   229  				},
   230  
   231  				Tasks: []*api.Task{
   232  					{
   233  						Driver:    "exec",
   234  						Name:      "task1",
   235  						Resources: &api.Resources{},
   236  					},
   237  				},
   238  			},
   239  		},
   240  	}
   241  )
   242  
   243  // Test APIJob with local jobfile
   244  func TestJobGetter_LocalFile(t *testing.T) {
   245  	fh, err := ioutil.TempFile("", "nomad")
   246  	if err != nil {
   247  		t.Fatalf("err: %s", err)
   248  	}
   249  	defer os.Remove(fh.Name())
   250  	_, err = fh.WriteString(job)
   251  	if err != nil {
   252  		t.Fatalf("err: %s", err)
   253  	}
   254  
   255  	j := &JobGetter{}
   256  	aj, err := j.ApiJob(fh.Name())
   257  	if err != nil {
   258  		t.Fatalf("err: %s", err)
   259  	}
   260  
   261  	if !reflect.DeepEqual(expectedApiJob, aj) {
   262  		eflat := flatmap.Flatten(expectedApiJob, nil, false)
   263  		aflat := flatmap.Flatten(aj, nil, false)
   264  		t.Fatalf("got:\n%v\nwant:\n%v", aflat, eflat)
   265  	}
   266  }
   267  
   268  // Test StructJob with jobfile from HTTP Server
   269  func TestJobGetter_HTTPServer(t *testing.T) {
   270  	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
   271  		fmt.Fprintf(w, job)
   272  	})
   273  	go http.ListenAndServe("127.0.0.1:12345", nil)
   274  
   275  	// Wait until HTTP Server starts certainly
   276  	time.Sleep(100 * time.Millisecond)
   277  
   278  	j := &JobGetter{}
   279  	aj, err := j.ApiJob("http://127.0.0.1:12345/")
   280  	if err != nil {
   281  		t.Fatalf("err: %s", err)
   282  	}
   283  	if !reflect.DeepEqual(expectedApiJob, aj) {
   284  		for _, d := range pretty.Diff(expectedApiJob, aj) {
   285  			t.Logf(d)
   286  		}
   287  		t.Fatalf("Unexpected file")
   288  	}
   289  }