common_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285
  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. time.Sleep(time.Second)
  135. s.qemuCmd = exec.Command(s.runCommand, args...)
  136. if os.Getenv("DEBUG") != "" {
  137. s.qemuCmd.Stdout = os.Stdout
  138. s.qemuCmd.Stderr = os.Stderr
  139. }
  140. if err := s.qemuCmd.Start(); err != nil {
  141. return err
  142. }
  143. fmt.Printf("--- %s: starting qemu %s, %v\n", c.TestName(), s.runCommand, args)
  144. return nil
  145. }
  146. func (s *QemuSuite) WaitForSSH() error {
  147. sshArgs := []string{
  148. "--qemu",
  149. "true",
  150. }
  151. var err error
  152. for i := 0; i < 100; i++ {
  153. cmd := exec.Command(s.sshCommand, sshArgs...)
  154. if err = cmd.Run(); err == nil {
  155. break
  156. }
  157. fmt.Printf("s%d", i)
  158. time.Sleep(time.Second)
  159. }
  160. if err != nil {
  161. return fmt.Errorf("Failed to connect to SSH: %v", err)
  162. }
  163. sshArgs = []string{
  164. "--qemu",
  165. "docker",
  166. "version",
  167. ">/dev/null",
  168. "2>&1",
  169. }
  170. for i := 0; i < 20; i++ {
  171. cmd := exec.Command(s.sshCommand, sshArgs...)
  172. if err = cmd.Run(); err == nil {
  173. return nil
  174. }
  175. fmt.Printf("d%d", i)
  176. time.Sleep(500 * time.Millisecond)
  177. }
  178. return fmt.Errorf("Failed to check Docker version: %v", err)
  179. }
  180. func (s *QemuSuite) MakeCall(additionalArgs ...string) (string, error) {
  181. sshArgs := []string{
  182. "--qemu",
  183. }
  184. sshArgs = append(sshArgs, additionalArgs...)
  185. cmd := exec.Command(s.sshCommand, sshArgs...)
  186. cmd.Stderr = os.Stderr
  187. out, err := cmd.Output()
  188. str := string(out)
  189. fmt.Println(str)
  190. return str, err
  191. }
  192. func (s *QemuSuite) CheckCall(c *C, additionalArgs ...string) {
  193. _, err := s.MakeCall(additionalArgs...)
  194. c.Assert(err, IsNil)
  195. }
  196. func (s *QemuSuite) CheckOutput(c *C, result string, check Checker, additionalArgs ...string) string {
  197. out, err := s.MakeCall(additionalArgs...)
  198. c.Assert(err, IsNil)
  199. c.Assert(out, check, result)
  200. return out
  201. }
  202. func (s *QemuSuite) CheckOutputContains(c *C, result string, additionalArgs ...string) string {
  203. out, err := s.MakeCall(additionalArgs...)
  204. c.Assert(err, IsNil)
  205. c.Assert(strings.Contains(out, result), Equals, true)
  206. return out
  207. }
  208. func (s *QemuSuite) Stop(c *C) {
  209. fmt.Printf("%s: stopping qemu\n", c.TestName())
  210. //s.MakeCall("sudo poweroff")
  211. time.Sleep(1000 * time.Millisecond)
  212. //c.Assert(s.WaitForSSH(), IsNil)
  213. fmt.Printf("%s: stopping qemu 2\n", c.TestName())
  214. c.Assert(s.qemuCmd.Process.Kill(), IsNil)
  215. fmt.Printf("%s: stopping qemu 3\n", c.TestName())
  216. s.qemuCmd.Process.Wait()
  217. //time.Sleep(time.Millisecond * 1000)
  218. s.qemuCmd = nil
  219. fmt.Printf("--- %s: qemu stopped", c.TestName())
  220. }
  221. func (s *QemuSuite) Reboot(c *C) {
  222. fmt.Printf("--- %s: qemu reboot", c.TestName())
  223. s.MakeCall("sudo reboot")
  224. time.Sleep(3000 * time.Millisecond)
  225. c.Assert(s.WaitForSSH(), IsNil)
  226. }
  227. func (s *QemuSuite) LoadInstallerImage(c *C) {
  228. cmd := exec.Command("sh", "-c", fmt.Sprintf("docker save rancher/os:%s%s | ../scripts/ssh --qemu sudo system-docker load", Version, Suffix))
  229. cmd.Stdout = os.Stdout
  230. cmd.Stderr = os.Stderr
  231. c.Assert(cmd.Run(), IsNil)
  232. }
  233. func (s *QemuSuite) PullAndLoadImage(c *C, image string) {
  234. cmd := exec.Command("sh", "-c", fmt.Sprintf("docker pull %s", image))
  235. cmd.Stdout = os.Stdout
  236. cmd.Stderr = os.Stderr
  237. c.Assert(cmd.Run(), IsNil)
  238. cmd = exec.Command("sh", "-c", fmt.Sprintf("docker save %s | ../scripts/ssh --qemu sudo system-docker load", image))
  239. cmd.Stdout = os.Stdout
  240. cmd.Stderr = os.Stderr
  241. c.Assert(cmd.Run(), IsNil)
  242. }