common_test.go 6.5 KB

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