/commands/commands_test.go

https://gitlab.com/github-cloud-corporation/machine · Go · 243 lines · 198 code · 39 blank · 6 comment · 10 complexity · 5eaae9a9298a13b62461e8ff01d07187 MD5 · raw file

  1. package commands
  2. import (
  3. "errors"
  4. "flag"
  5. "testing"
  6. "github.com/codegangsta/cli"
  7. "github.com/docker/machine/commands/commandstest"
  8. "github.com/docker/machine/drivers/fakedriver"
  9. "github.com/docker/machine/libmachine"
  10. "github.com/docker/machine/libmachine/crashreport"
  11. "github.com/docker/machine/libmachine/host"
  12. "github.com/docker/machine/libmachine/hosttest"
  13. "github.com/docker/machine/libmachine/mcnerror"
  14. "github.com/docker/machine/libmachine/provision"
  15. "github.com/docker/machine/libmachine/state"
  16. "github.com/stretchr/testify/assert"
  17. )
  18. func TestRunActionForeachMachine(t *testing.T) {
  19. defer provision.SetDetector(&provision.StandardDetector{})
  20. provision.SetDetector(&provision.FakeDetector{
  21. Provisioner: provision.NewNetstatProvisioner(),
  22. })
  23. // Assume a bunch of machines in randomly started or
  24. // stopped states.
  25. machines := []*host.Host{
  26. {
  27. Name: "foo",
  28. DriverName: "fakedriver",
  29. Driver: &fakedriver.Driver{
  30. MockState: state.Running,
  31. },
  32. },
  33. {
  34. Name: "bar",
  35. DriverName: "fakedriver",
  36. Driver: &fakedriver.Driver{
  37. MockState: state.Stopped,
  38. },
  39. },
  40. {
  41. Name: "baz",
  42. // Ssh, don't tell anyone but this
  43. // driver only _thinks_ it's named
  44. // virtualbox... (to test serial actions)
  45. // It's actually FakeDriver!
  46. DriverName: "virtualbox",
  47. Driver: &fakedriver.Driver{
  48. MockState: state.Stopped,
  49. },
  50. },
  51. {
  52. Name: "spam",
  53. DriverName: "virtualbox",
  54. Driver: &fakedriver.Driver{
  55. MockState: state.Running,
  56. },
  57. },
  58. {
  59. Name: "eggs",
  60. DriverName: "fakedriver",
  61. Driver: &fakedriver.Driver{
  62. MockState: state.Stopped,
  63. },
  64. },
  65. {
  66. Name: "ham",
  67. DriverName: "fakedriver",
  68. Driver: &fakedriver.Driver{
  69. MockState: state.Running,
  70. },
  71. },
  72. }
  73. runActionForeachMachine("start", machines)
  74. for _, machine := range machines {
  75. machineState, _ := machine.Driver.GetState()
  76. assert.Equal(t, state.Running, machineState)
  77. }
  78. runActionForeachMachine("stop", machines)
  79. for _, machine := range machines {
  80. machineState, _ := machine.Driver.GetState()
  81. assert.Equal(t, state.Stopped, machineState)
  82. }
  83. }
  84. func TestPrintIPEmptyGivenLocalEngine(t *testing.T) {
  85. stdoutGetter := commandstest.NewStdoutGetter()
  86. defer stdoutGetter.Stop()
  87. host, _ := hosttest.GetDefaultTestHost()
  88. err := printIP(host)()
  89. assert.NoError(t, err)
  90. assert.Equal(t, "\n", stdoutGetter.Output())
  91. }
  92. func TestPrintIPPrintsGivenRemoteEngine(t *testing.T) {
  93. stdoutGetter := commandstest.NewStdoutGetter()
  94. defer stdoutGetter.Stop()
  95. host, _ := hosttest.GetDefaultTestHost()
  96. host.Driver = &fakedriver.Driver{
  97. MockState: state.Running,
  98. MockIP: "1.2.3.4",
  99. }
  100. err := printIP(host)()
  101. assert.NoError(t, err)
  102. assert.Equal(t, "1.2.3.4\n", stdoutGetter.Output())
  103. }
  104. func TestConsolidateError(t *testing.T) {
  105. cases := []struct {
  106. inputErrs []error
  107. expectedErr error
  108. }{
  109. {
  110. inputErrs: []error{
  111. errors.New("Couldn't remove host 'bar'"),
  112. },
  113. expectedErr: errors.New("Couldn't remove host 'bar'"),
  114. },
  115. {
  116. inputErrs: []error{
  117. errors.New("Couldn't remove host 'bar'"),
  118. errors.New("Couldn't remove host 'foo'"),
  119. },
  120. expectedErr: errors.New("Couldn't remove host 'bar'\nCouldn't remove host 'foo'"),
  121. },
  122. }
  123. for _, c := range cases {
  124. assert.Equal(t, c.expectedErr, consolidateErrs(c.inputErrs))
  125. }
  126. }
  127. type MockCrashReporter struct {
  128. sent bool
  129. }
  130. func (m *MockCrashReporter) Send(err crashreport.CrashError) error {
  131. m.sent = true
  132. return nil
  133. }
  134. func TestSendCrashReport(t *testing.T) {
  135. defer func(fnOsExit func(code int)) { osExit = fnOsExit }(osExit)
  136. osExit = func(code int) {}
  137. defer func(factory func(baseDir string, apiKey string) crashreport.CrashReporter) {
  138. crashreport.NewCrashReporter = factory
  139. }(crashreport.NewCrashReporter)
  140. tests := []struct {
  141. description string
  142. err error
  143. sent bool
  144. }{
  145. {
  146. description: "Should send crash error",
  147. err: crashreport.CrashError{
  148. Cause: errors.New("BUG"),
  149. Command: "command",
  150. Context: "context",
  151. DriverName: "virtualbox",
  152. },
  153. sent: true,
  154. },
  155. {
  156. description: "Should not send standard error",
  157. err: errors.New("BUG"),
  158. sent: false,
  159. },
  160. }
  161. for _, test := range tests {
  162. mockCrashReporter := &MockCrashReporter{}
  163. crashreport.NewCrashReporter = func(baseDir string, apiKey string) crashreport.CrashReporter {
  164. return mockCrashReporter
  165. }
  166. command := func(commandLine CommandLine, api libmachine.API) error {
  167. return test.err
  168. }
  169. context := cli.NewContext(cli.NewApp(), &flag.FlagSet{}, nil)
  170. runCommand(command)(context)
  171. assert.Equal(t, test.sent, mockCrashReporter.sent, test.description)
  172. }
  173. }
  174. func TestReturnExitCode1onError(t *testing.T) {
  175. command := func(commandLine CommandLine, api libmachine.API) error {
  176. return errors.New("foo is not bar")
  177. }
  178. exitCode := checkErrorCodeForCommand(command)
  179. assert.Equal(t, 1, exitCode)
  180. }
  181. func TestReturnExitCode3onErrorDuringPreCreate(t *testing.T) {
  182. command := func(commandLine CommandLine, api libmachine.API) error {
  183. return crashreport.CrashError{
  184. Cause: mcnerror.ErrDuringPreCreate{
  185. Cause: errors.New("foo is not bar"),
  186. },
  187. }
  188. }
  189. exitCode := checkErrorCodeForCommand(command)
  190. assert.Equal(t, 3, exitCode)
  191. }
  192. func checkErrorCodeForCommand(command func(commandLine CommandLine, api libmachine.API) error) int {
  193. var setExitCode int
  194. originalOSExit := osExit
  195. defer func() {
  196. osExit = originalOSExit
  197. }()
  198. osExit = func(code int) {
  199. setExitCode = code
  200. }
  201. context := cli.NewContext(cli.NewApp(), &flag.FlagSet{}, nil)
  202. runCommand(command)(context)
  203. return setExitCode
  204. }