remote_test.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package engine
  2. import (
  3. "bufio"
  4. "bytes"
  5. "fmt"
  6. "github.com/dotcloud/docker/pkg/beam"
  7. "io"
  8. "strings"
  9. "testing"
  10. "time"
  11. )
  12. func TestHelloWorld(t *testing.T) {
  13. for i := 0; i < 10; i++ {
  14. testRemote(t,
  15. // Sender side
  16. func(eng *Engine) {
  17. job := eng.Job("echo", "hello", "world")
  18. out := &bytes.Buffer{}
  19. job.Stdout.Add(out)
  20. job.Run()
  21. if job.status != StatusOK {
  22. t.Fatalf("#%v", job.StatusCode())
  23. }
  24. lines := bufio.NewScanner(out)
  25. var i int
  26. for lines.Scan() {
  27. if lines.Text() != "hello world" {
  28. t.Fatalf("%#v", lines.Text())
  29. }
  30. i++
  31. }
  32. if i != 1000 {
  33. t.Fatalf("%#v", i)
  34. }
  35. },
  36. // Receiver side
  37. func(eng *Engine) {
  38. eng.Register("echo", func(job *Job) Status {
  39. // Simulate more output with a delay in the middle
  40. for i := 0; i < 500; i++ {
  41. fmt.Fprintf(job.Stdout, "%s\n", strings.Join(job.Args, " "))
  42. }
  43. time.Sleep(5 * time.Millisecond)
  44. for i := 0; i < 500; i++ {
  45. fmt.Fprintf(job.Stdout, "%s\n", strings.Join(job.Args, " "))
  46. }
  47. return StatusOK
  48. })
  49. },
  50. )
  51. }
  52. }
  53. func TestStdin(t *testing.T) {
  54. testRemote(t,
  55. func(eng *Engine) {
  56. job := eng.Job("mirror")
  57. job.Stdin.Add(strings.NewReader("hello world!\n"))
  58. out := &bytes.Buffer{}
  59. job.Stdout.Add(out)
  60. if err := job.Run(); err != nil {
  61. t.Fatal(err)
  62. }
  63. if out.String() != "hello world!\n" {
  64. t.Fatalf("%#v", out.String())
  65. }
  66. },
  67. func(eng *Engine) {
  68. eng.Register("mirror", func(job *Job) Status {
  69. if _, err := io.Copy(job.Stdout, job.Stdin); err != nil {
  70. t.Fatal(err)
  71. }
  72. return StatusOK
  73. })
  74. },
  75. )
  76. }
  77. func TestEnv(t *testing.T) {
  78. var (
  79. foo string
  80. answer int
  81. shadok_words []string
  82. )
  83. testRemote(t,
  84. func(eng *Engine) {
  85. job := eng.Job("sendenv")
  86. job.Env().Set("foo", "bar")
  87. job.Env().SetInt("answer", 42)
  88. job.Env().SetList("shadok_words", []string{"ga", "bu", "zo", "meu"})
  89. if err := job.Run(); err != nil {
  90. t.Fatal(err)
  91. }
  92. },
  93. func(eng *Engine) {
  94. eng.Register("sendenv", func(job *Job) Status {
  95. foo = job.Env().Get("foo")
  96. answer = job.Env().GetInt("answer")
  97. shadok_words = job.Env().GetList("shadok_words")
  98. return StatusOK
  99. })
  100. },
  101. )
  102. // Check for results here rather than inside the job handler,
  103. // otherwise the tests may incorrectly pass if the handler is not
  104. // called.
  105. if foo != "bar" {
  106. t.Fatalf("%#v", foo)
  107. }
  108. if answer != 42 {
  109. t.Fatalf("%#v", answer)
  110. }
  111. if strings.Join(shadok_words, ", ") != "ga, bu, zo, meu" {
  112. t.Fatalf("%#v", shadok_words)
  113. }
  114. }
  115. // Helpers
  116. func testRemote(t *testing.T, senderSide, receiverSide func(*Engine)) {
  117. sndConn, rcvConn, err := beam.USocketPair()
  118. if err != nil {
  119. t.Fatal(err)
  120. }
  121. defer sndConn.Close()
  122. defer rcvConn.Close()
  123. sender := NewSender(sndConn)
  124. receiver := NewReceiver(rcvConn)
  125. // Setup the sender side
  126. eng := New()
  127. sender.Install(eng)
  128. // Setup the receiver side
  129. receiverSide(receiver.Engine)
  130. go receiver.Run()
  131. timeout(t, func() {
  132. senderSide(eng)
  133. })
  134. }
  135. func timeout(t *testing.T, f func()) {
  136. onTimeout := time.After(100 * time.Millisecond)
  137. onDone := make(chan bool)
  138. go func() {
  139. f()
  140. close(onDone)
  141. }()
  142. select {
  143. case <-onTimeout:
  144. t.Fatalf("timeout")
  145. case <-onDone:
  146. }
  147. }