engine_test.go 5.2 KB

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