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 }