github.com/raychaser/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  }