github.com/dougm/docker@v1.5.0/engine/engine_test.go (about) 1 package engine 2 3 import ( 4 "bytes" 5 "strings" 6 "testing" 7 8 "github.com/docker/docker/pkg/ioutils" 9 ) 10 11 func TestRegister(t *testing.T) { 12 if err := Register("dummy1", nil); err != nil { 13 t.Fatal(err) 14 } 15 16 if err := Register("dummy1", nil); err == nil { 17 t.Fatalf("Expecting error, got none") 18 } 19 // Register is global so let's cleanup to avoid conflicts 20 defer unregister("dummy1") 21 22 eng := New() 23 24 //Should fail because global handlers are copied 25 //at the engine creation 26 if err := eng.Register("dummy1", nil); err == nil { 27 t.Fatalf("Expecting error, got none") 28 } 29 30 if err := eng.Register("dummy2", nil); err != nil { 31 t.Fatal(err) 32 } 33 34 if err := eng.Register("dummy2", nil); err == nil { 35 t.Fatalf("Expecting error, got none") 36 } 37 defer unregister("dummy2") 38 } 39 40 func TestJob(t *testing.T) { 41 eng := New() 42 job1 := eng.Job("dummy1", "--level=awesome") 43 44 if job1.handler != nil { 45 t.Fatalf("job1.handler should be empty") 46 } 47 48 h := func(j *Job) Status { 49 j.Printf("%s\n", j.Name) 50 return 42 51 } 52 53 eng.Register("dummy2", h) 54 defer unregister("dummy2") 55 job2 := eng.Job("dummy2", "--level=awesome") 56 57 if job2.handler == nil { 58 t.Fatalf("job2.handler shouldn't be nil") 59 } 60 61 if job2.handler(job2) != 42 { 62 t.Fatalf("handler dummy2 was not found in job2") 63 } 64 } 65 66 func TestEngineShutdown(t *testing.T) { 67 eng := New() 68 if eng.IsShutdown() { 69 t.Fatalf("Engine should not show as shutdown") 70 } 71 eng.Shutdown() 72 if !eng.IsShutdown() { 73 t.Fatalf("Engine should show as shutdown") 74 } 75 } 76 77 func TestEngineCommands(t *testing.T) { 78 eng := New() 79 handler := func(job *Job) Status { return StatusOK } 80 eng.Register("foo", handler) 81 eng.Register("bar", handler) 82 eng.Register("echo", handler) 83 eng.Register("die", handler) 84 var output bytes.Buffer 85 commands := eng.Job("commands") 86 commands.Stdout.Add(&output) 87 commands.Run() 88 expected := "bar\ncommands\ndie\necho\nfoo\n" 89 if result := output.String(); result != expected { 90 t.Fatalf("Unexpected output:\nExpected = %v\nResult = %v\n", expected, result) 91 } 92 } 93 94 func TestEngineString(t *testing.T) { 95 eng1 := New() 96 eng2 := New() 97 s1 := eng1.String() 98 s2 := eng2.String() 99 if eng1 == eng2 { 100 t.Fatalf("Different engines should have different names (%v == %v)", s1, s2) 101 } 102 } 103 104 func TestParseJob(t *testing.T) { 105 eng := New() 106 // Verify that the resulting job calls to the right place 107 var called bool 108 eng.Register("echo", func(job *Job) Status { 109 called = true 110 return StatusOK 111 }) 112 input := "echo DEBUG=1 hello world VERBOSITY=42" 113 job, err := eng.ParseJob(input) 114 if err != nil { 115 t.Fatal(err) 116 } 117 if job.Name != "echo" { 118 t.Fatalf("Invalid job name: %v", job.Name) 119 } 120 if strings.Join(job.Args, ":::") != "hello:::world" { 121 t.Fatalf("Invalid job args: %v", job.Args) 122 } 123 if job.Env().Get("DEBUG") != "1" { 124 t.Fatalf("Invalid job env: %v", job.Env) 125 } 126 if job.Env().Get("VERBOSITY") != "42" { 127 t.Fatalf("Invalid job env: %v", job.Env) 128 } 129 if len(job.Env().Map()) != 2 { 130 t.Fatalf("Invalid job env: %v", job.Env) 131 } 132 if err := job.Run(); err != nil { 133 t.Fatal(err) 134 } 135 if !called { 136 t.Fatalf("Job was not called") 137 } 138 } 139 140 func TestCatchallEmptyName(t *testing.T) { 141 eng := New() 142 var called bool 143 eng.RegisterCatchall(func(job *Job) Status { 144 called = true 145 return StatusOK 146 }) 147 err := eng.Job("").Run() 148 if err == nil { 149 t.Fatalf("Engine.Job(\"\").Run() should return an error") 150 } 151 if called { 152 t.Fatalf("Engine.Job(\"\").Run() should return an error") 153 } 154 } 155 156 // Ensure that a job within a job both using the same underlying standard 157 // output writer does not close the output of the outer job when the inner 158 // job's stdout is wrapped with a NopCloser. When not wrapped, it should 159 // close the outer job's output. 160 func TestNestedJobSharedOutput(t *testing.T) { 161 var ( 162 outerHandler Handler 163 innerHandler Handler 164 wrapOutput bool 165 ) 166 167 outerHandler = func(job *Job) Status { 168 job.Stdout.Write([]byte("outer1")) 169 170 innerJob := job.Eng.Job("innerJob") 171 172 if wrapOutput { 173 innerJob.Stdout.Add(ioutils.NopWriteCloser(job.Stdout)) 174 } else { 175 innerJob.Stdout.Add(job.Stdout) 176 } 177 178 if err := innerJob.Run(); err != nil { 179 t.Fatal(err) 180 } 181 182 // If wrapOutput was *false* this write will do nothing. 183 // FIXME (jlhawn): It should cause an error to write to 184 // closed output. 185 job.Stdout.Write([]byte(" outer2")) 186 187 return StatusOK 188 } 189 190 innerHandler = func(job *Job) Status { 191 job.Stdout.Write([]byte(" inner")) 192 193 return StatusOK 194 } 195 196 eng := New() 197 eng.Register("outerJob", outerHandler) 198 eng.Register("innerJob", innerHandler) 199 200 // wrapOutput starts *false* so the expected 201 // output of running the outer job will be: 202 // 203 // "outer1 inner" 204 // 205 outBuf := new(bytes.Buffer) 206 outerJob := eng.Job("outerJob") 207 outerJob.Stdout.Add(outBuf) 208 209 if err := outerJob.Run(); err != nil { 210 t.Fatal(err) 211 } 212 213 expectedOutput := "outer1 inner" 214 if outBuf.String() != expectedOutput { 215 t.Fatalf("expected job output to be %q, got %q", expectedOutput, outBuf.String()) 216 } 217 218 // Set wrapOutput to true so that the expected 219 // output of running the outer job will be: 220 // 221 // "outer1 inner outer2" 222 // 223 wrapOutput = true 224 outBuf.Reset() 225 outerJob = eng.Job("outerJob") 226 outerJob.Stdout.Add(outBuf) 227 228 if err := outerJob.Run(); err != nil { 229 t.Fatal(err) 230 } 231 232 expectedOutput = "outer1 inner outer2" 233 if outBuf.String() != expectedOutput { 234 t.Fatalf("expected job output to be %q, got %q", expectedOutput, outBuf.String()) 235 } 236 }