common_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. package integration
  2. import (
  3. "fmt"
  4. "os"
  5. "os/exec"
  6. "runtime"
  7. "strings"
  8. "testing"
  9. "time"
  10. "github.com/gbazil/telnet"
  11. . "gopkg.in/check.v1"
  12. )
  13. func Test(t *testing.T) { TestingT(t) }
  14. func init() {
  15. Suite(&QemuSuite{
  16. runCommand: "../scripts/run",
  17. sshCommand: "../scripts/ssh",
  18. qemuCmd: nil,
  19. })
  20. }
  21. var (
  22. BusyboxImage = map[string]string{
  23. "amd64": "busybox",
  24. "arm": "armhf/busybox",
  25. "arm64": "aarch64/busybox",
  26. }[runtime.GOARCH]
  27. NginxImage = map[string]string{
  28. "amd64": "nginx",
  29. "arm": "armhfbuild/nginx",
  30. "arm64": "armhfbuild/nginx",
  31. }[runtime.GOARCH]
  32. Version = os.Getenv("VERSION")
  33. Suffix = os.Getenv("SUFFIX")
  34. )
  35. type QemuSuite struct {
  36. runCommand string
  37. sshCommand string
  38. qemuCmd *exec.Cmd
  39. netConsole telnet.Telnet
  40. }
  41. func (s *QemuSuite) TearDownTest(c *C) {
  42. if s.qemuCmd != nil {
  43. s.Stop(c)
  44. }
  45. time.Sleep(time.Second)
  46. }
  47. // RunQemuWith requires user to specify all the `scripts/run` arguments
  48. func (s *QemuSuite) RunQemuWith(c *C, additionalArgs ...string) error {
  49. err := s.runQemu(c, additionalArgs...)
  50. c.Assert(err, IsNil)
  51. err = s.WaitForSSH()
  52. c.Assert(err, IsNil)
  53. return err
  54. }
  55. func (s *QemuSuite) RunQemu(c *C, additionalArgs ...string) error {
  56. runArgs := []string{
  57. "--qemu",
  58. "--no-rebuild",
  59. "--no-rm-usr",
  60. "--fresh",
  61. }
  62. runArgs = append(runArgs, additionalArgs...)
  63. err := s.RunQemuWith(c, runArgs...)
  64. c.Assert(err, IsNil)
  65. return err
  66. }
  67. func (s *QemuSuite) RunQemuInstalled(c *C, additionalArgs ...string) error {
  68. runArgs := []string{
  69. "--fresh",
  70. }
  71. runArgs = append(runArgs, additionalArgs...)
  72. err := s.RunQemu(c, runArgs...)
  73. c.Assert(err, IsNil)
  74. return err
  75. }
  76. // RunQemuWithNetConsole requires user to specify all the `scripts/run` arguments
  77. func (s *QemuSuite) RunQemuWithNetConsole(c *C, additionalArgs ...string) error {
  78. runArgs := []string{
  79. "--netconsole",
  80. }
  81. runArgs = append(runArgs, additionalArgs...)
  82. err := s.runQemu(c, runArgs...)
  83. c.Assert(err, IsNil)
  84. time.Sleep(500 * time.Millisecond)
  85. // start telnet, and wait for prompt
  86. for i := 0; i < 20; i++ {
  87. s.netConsole, err = telnet.DialTimeout("127.0.0.1:4444", 5*time.Second)
  88. if err == nil {
  89. fmt.Printf("t%d SUCCEEDED\n", i)
  90. break
  91. }
  92. fmt.Printf("t%d", i)
  93. time.Sleep(500 * time.Millisecond)
  94. }
  95. c.Assert(err, IsNil)
  96. for i := 0; i < 20; i++ {
  97. time.Sleep(1 * time.Second)
  98. res := s.NetCall("uname")
  99. if strings.Contains(res, "Linux") {
  100. fmt.Printf("W%d SUCCEEDED(%s)\n", i, res)
  101. break
  102. }
  103. }
  104. s.NetCall("ip a")
  105. s.NetCall("cat /proc/cmdline")
  106. return err
  107. }
  108. func (s *QemuSuite) NetCall(cmd string) string {
  109. s.netConsole.Write(cmd + "\n")
  110. r, err := s.netConsole.Read("\n")
  111. fmt.Printf("cmd> %s", r)
  112. result := ""
  113. r = ""
  114. for err == nil {
  115. r, err = s.netConsole.Read("\n")
  116. fmt.Printf("\t%s", r)
  117. result = result + r
  118. }
  119. fmt.Printf("\n")
  120. // Note, if the result contains something like "+ cmd\n", you may have set -xe on
  121. return result
  122. }
  123. func (s *QemuSuite) NetCheckCall(c *C, additionalArgs ...string) {
  124. out := s.NetCall(strings.Join(additionalArgs, " "))
  125. c.Assert(out, Not(Equals), "")
  126. }
  127. func (s *QemuSuite) NetCheckOutput(c *C, result string, check Checker, additionalArgs ...string) string {
  128. out := s.NetCall(strings.Join(additionalArgs, " "))
  129. out = strings.Replace(out, "\r", "", -1)
  130. c.Assert(out, check, result)
  131. return out
  132. }
  133. func (s *QemuSuite) runQemu(c *C, args ...string) error {
  134. c.Assert(s.qemuCmd, IsNil) // can't run 2 qemu's at once (yet)
  135. time.Sleep(time.Second)
  136. s.qemuCmd = exec.Command(s.runCommand, args...)
  137. if os.Getenv("DEBUG") != "" {
  138. s.qemuCmd.Stdout = os.Stdout
  139. s.qemuCmd.Stderr = os.Stderr
  140. }
  141. if err := s.qemuCmd.Start(); err != nil {
  142. return err
  143. }
  144. fmt.Printf("--- %s: starting qemu %s, %v\n", c.TestName(), s.runCommand, args)
  145. return nil
  146. }
  147. func (s *QemuSuite) WaitForSSH() error {
  148. sshArgs := []string{
  149. "--qemu",
  150. "true",
  151. }
  152. var err error
  153. for i := 0; i < 100; i++ {
  154. cmd := exec.Command(s.sshCommand, sshArgs...)
  155. if err = cmd.Run(); err == nil {
  156. break
  157. }
  158. fmt.Printf("s%d", i)
  159. time.Sleep(time.Second)
  160. }
  161. if err != nil {
  162. return fmt.Errorf("Failed to connect to SSH: %v", err)
  163. }
  164. sshArgs = []string{
  165. "--qemu",
  166. "docker",
  167. "version",
  168. ">/dev/null",
  169. "2>&1",
  170. }
  171. for i := 0; i < 20; i++ {
  172. cmd := exec.Command(s.sshCommand, sshArgs...)
  173. if err = cmd.Run(); err == nil {
  174. return nil
  175. }
  176. fmt.Printf("d%d", i)
  177. time.Sleep(500 * time.Millisecond)
  178. }
  179. return fmt.Errorf("Failed to check Docker version: %v", err)
  180. }
  181. func (s *QemuSuite) MakeCall(additionalArgs ...string) (string, error) {
  182. sshArgs := []string{
  183. "--qemu",
  184. }
  185. sshArgs = append(sshArgs, additionalArgs...)
  186. cmd := exec.Command(s.sshCommand, sshArgs...)
  187. cmd.Stderr = os.Stderr
  188. out, err := cmd.Output()
  189. str := string(out)
  190. fmt.Println(str)
  191. return str, err
  192. }
  193. func (s *QemuSuite) CheckCall(c *C, additionalArgs ...string) {
  194. _, err := s.MakeCall(additionalArgs...)
  195. c.Assert(err, IsNil)
  196. }
  197. func (s *QemuSuite) CheckOutput(c *C, result string, check Checker, additionalArgs ...string) string {
  198. out, err := s.MakeCall(additionalArgs...)
  199. c.Assert(err, IsNil)
  200. c.Assert(out, check, result)
  201. return out
  202. }
  203. func (s *QemuSuite) CheckOutputContains(c *C, result string, additionalArgs ...string) string {
  204. out, err := s.MakeCall(additionalArgs...)
  205. c.Assert(err, IsNil)
  206. c.Assert(strings.Contains(out, result), Equals, true)
  207. return out
  208. }
  209. func (s *QemuSuite) Stop(c *C) {
  210. fmt.Printf("%s: stopping qemu\n", c.TestName())
  211. //s.MakeCall("sudo poweroff")
  212. time.Sleep(1000 * time.Millisecond)
  213. //c.Assert(s.WaitForSSH(), IsNil)
  214. fmt.Printf("%s: stopping qemu 2\n", c.TestName())
  215. c.Assert(s.qemuCmd.Process.Kill(), IsNil)
  216. fmt.Printf("%s: stopping qemu 3\n", c.TestName())
  217. s.qemuCmd.Process.Wait()
  218. time.Sleep(time.Second)
  219. s.qemuCmd = nil
  220. fmt.Printf("--- %s: qemu stopped", c.TestName())
  221. }
  222. func (s *QemuSuite) Reboot(c *C) {
  223. fmt.Printf("--- %s: qemu reboot", c.TestName())
  224. s.MakeCall("sudo reboot")
  225. time.Sleep(3000 * time.Millisecond)
  226. c.Assert(s.WaitForSSH(), IsNil)
  227. }
  228. func (s *QemuSuite) LoadInstallerImage(c *C) {
  229. cmd := exec.Command("sh", "-c", fmt.Sprintf("docker save rancher/os:%s%s | ../scripts/ssh --qemu sudo system-docker load", Version, Suffix))
  230. cmd.Stdout = os.Stdout
  231. cmd.Stderr = os.Stderr
  232. c.Assert(cmd.Run(), IsNil)
  233. }
  234. func (s *QemuSuite) PullAndLoadImage(c *C, image string) {
  235. cmd := exec.Command("sh", "-c", fmt.Sprintf("docker pull %s", image))
  236. cmd.Stdout = os.Stdout
  237. cmd.Stderr = os.Stderr
  238. c.Assert(cmd.Run(), IsNil)
  239. cmd = exec.Command("sh", "-c", fmt.Sprintf("docker save %s | ../scripts/ssh --qemu sudo system-docker load", image))
  240. cmd.Stdout = os.Stdout
  241. cmd.Stderr = os.Stderr
  242. c.Assert(cmd.Run(), IsNil)
  243. }