123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- package engine
- import (
- "bytes"
- "strings"
- "testing"
- "github.com/docker/docker/pkg/ioutils"
- )
- func TestRegister(t *testing.T) {
- if err := Register("dummy1", nil); err != nil {
- t.Fatal(err)
- }
- if err := Register("dummy1", nil); err == nil {
- t.Fatalf("Expecting error, got none")
- }
- // Register is global so let's cleanup to avoid conflicts
- defer unregister("dummy1")
- eng := New()
- //Should fail because global handlers are copied
- //at the engine creation
- if err := eng.Register("dummy1", nil); err == nil {
- t.Fatalf("Expecting error, got none")
- }
- if err := eng.Register("dummy2", nil); err != nil {
- t.Fatal(err)
- }
- if err := eng.Register("dummy2", nil); err == nil {
- t.Fatalf("Expecting error, got none")
- }
- defer unregister("dummy2")
- }
- func TestJob(t *testing.T) {
- eng := New()
- job1 := eng.Job("dummy1", "--level=awesome")
- if job1.handler != nil {
- t.Fatalf("job1.handler should be empty")
- }
- h := func(j *Job) error {
- j.Printf("%s\n", j.Name)
- return nil
- }
- eng.Register("dummy2", h)
- defer unregister("dummy2")
- job2 := eng.Job("dummy2", "--level=awesome")
- if job2.handler == nil {
- t.Fatalf("job2.handler shouldn't be nil")
- }
- if job2.handler(job2) != nil {
- t.Fatalf("handler dummy2 was not found in job2")
- }
- }
- func TestEngineShutdown(t *testing.T) {
- eng := New()
- if eng.IsShutdown() {
- t.Fatalf("Engine should not show as shutdown")
- }
- eng.Shutdown()
- if !eng.IsShutdown() {
- t.Fatalf("Engine should show as shutdown")
- }
- }
- func TestEngineCommands(t *testing.T) {
- eng := New()
- handler := func(job *Job) error { return nil }
- eng.Register("foo", handler)
- eng.Register("bar", handler)
- eng.Register("echo", handler)
- eng.Register("die", handler)
- var output bytes.Buffer
- commands := eng.Job("commands")
- commands.Stdout.Add(&output)
- commands.Run()
- expected := "bar\ncommands\ndie\necho\nfoo\n"
- if result := output.String(); result != expected {
- t.Fatalf("Unexpected output:\nExpected = %v\nResult = %v\n", expected, result)
- }
- }
- func TestEngineString(t *testing.T) {
- eng1 := New()
- eng2 := New()
- s1 := eng1.String()
- s2 := eng2.String()
- if eng1 == eng2 {
- t.Fatalf("Different engines should have different names (%v == %v)", s1, s2)
- }
- }
- func TestParseJob(t *testing.T) {
- eng := New()
- // Verify that the resulting job calls to the right place
- var called bool
- eng.Register("echo", func(job *Job) error {
- called = true
- return nil
- })
- input := "echo DEBUG=1 hello world VERBOSITY=42"
- job, err := eng.ParseJob(input)
- if err != nil {
- t.Fatal(err)
- }
- if job.Name != "echo" {
- t.Fatalf("Invalid job name: %v", job.Name)
- }
- if strings.Join(job.Args, ":::") != "hello:::world" {
- t.Fatalf("Invalid job args: %v", job.Args)
- }
- if job.Env().Get("DEBUG") != "1" {
- t.Fatalf("Invalid job env: %v", job.Env)
- }
- if job.Env().Get("VERBOSITY") != "42" {
- t.Fatalf("Invalid job env: %v", job.Env)
- }
- if len(job.Env().Map()) != 2 {
- t.Fatalf("Invalid job env: %v", job.Env)
- }
- if err := job.Run(); err != nil {
- t.Fatal(err)
- }
- if !called {
- t.Fatalf("Job was not called")
- }
- }
- func TestCatchallEmptyName(t *testing.T) {
- eng := New()
- var called bool
- eng.RegisterCatchall(func(job *Job) error {
- called = true
- return nil
- })
- err := eng.Job("").Run()
- if err == nil {
- t.Fatalf("Engine.Job(\"\").Run() should return an error")
- }
- if called {
- t.Fatalf("Engine.Job(\"\").Run() should return an error")
- }
- }
- // Ensure that a job within a job both using the same underlying standard
- // output writer does not close the output of the outer job when the inner
- // job's stdout is wrapped with a NopCloser. When not wrapped, it should
- // close the outer job's output.
- func TestNestedJobSharedOutput(t *testing.T) {
- var (
- outerHandler Handler
- innerHandler Handler
- wrapOutput bool
- )
- outerHandler = func(job *Job) error {
- job.Stdout.Write([]byte("outer1"))
- innerJob := job.Eng.Job("innerJob")
- if wrapOutput {
- innerJob.Stdout.Add(ioutils.NopWriteCloser(job.Stdout))
- } else {
- innerJob.Stdout.Add(job.Stdout)
- }
- if err := innerJob.Run(); err != nil {
- t.Fatal(err)
- }
- // If wrapOutput was *false* this write will do nothing.
- // FIXME (jlhawn): It should cause an error to write to
- // closed output.
- job.Stdout.Write([]byte(" outer2"))
- return nil
- }
- innerHandler = func(job *Job) error {
- job.Stdout.Write([]byte(" inner"))
- return nil
- }
- eng := New()
- eng.Register("outerJob", outerHandler)
- eng.Register("innerJob", innerHandler)
- // wrapOutput starts *false* so the expected
- // output of running the outer job will be:
- //
- // "outer1 inner"
- //
- outBuf := new(bytes.Buffer)
- outerJob := eng.Job("outerJob")
- outerJob.Stdout.Add(outBuf)
- if err := outerJob.Run(); err != nil {
- t.Fatal(err)
- }
- expectedOutput := "outer1 inner"
- if outBuf.String() != expectedOutput {
- t.Fatalf("expected job output to be %q, got %q", expectedOutput, outBuf.String())
- }
- // Set wrapOutput to true so that the expected
- // output of running the outer job will be:
- //
- // "outer1 inner outer2"
- //
- wrapOutput = true
- outBuf.Reset()
- outerJob = eng.Job("outerJob")
- outerJob.Stdout.Add(outBuf)
- if err := outerJob.Run(); err != nil {
- t.Fatal(err)
- }
- expectedOutput = "outer1 inner outer2"
- if outBuf.String() != expectedOutput {
- t.Fatalf("expected job output to be %q, got %q", expectedOutput, outBuf.String())
- }
- }
|