client_test.go 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. package client
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. "os"
  9. "strings"
  10. "testing"
  11. _ "github.com/docker/libnetwork/netutils"
  12. )
  13. // nopCloser is used to provide a dummy CallFunc for Cmd()
  14. type nopCloser struct {
  15. io.Reader
  16. }
  17. func (nopCloser) Close() error { return nil }
  18. func TestMain(m *testing.M) {
  19. setupMockHTTPCallback()
  20. os.Exit(m.Run())
  21. }
  22. var callbackFunc func(method, path string, data interface{}, headers map[string][]string) (io.ReadCloser, http.Header, int, error)
  23. var mockNwJSON, mockNwListJSON, mockServiceJSON, mockServiceListJSON, mockSbJSON, mockSbListJSON []byte
  24. var mockNwName = "test"
  25. var mockNwID = "2a3456789"
  26. var mockServiceName = "testSrv"
  27. var mockServiceID = "2a3456789"
  28. var mockContainerID = "2a3456789"
  29. var mockSandboxID = "2b3456789"
  30. func setupMockHTTPCallback() {
  31. var list []networkResource
  32. nw := networkResource{Name: mockNwName, ID: mockNwID}
  33. mockNwJSON, _ = json.Marshal(nw)
  34. list = append(list, nw)
  35. mockNwListJSON, _ = json.Marshal(list)
  36. var srvList []serviceResource
  37. ep := serviceResource{Name: mockServiceName, ID: mockServiceID, Network: mockNwName}
  38. mockServiceJSON, _ = json.Marshal(ep)
  39. srvList = append(srvList, ep)
  40. mockServiceListJSON, _ = json.Marshal(srvList)
  41. var sbxList []sandboxResource
  42. sb := sandboxResource{ID: mockSandboxID, ContainerID: mockContainerID}
  43. mockSbJSON, _ = json.Marshal(sb)
  44. sbxList = append(sbxList, sb)
  45. mockSbListJSON, _ = json.Marshal(sbxList)
  46. dummyHTTPHdr := http.Header{}
  47. callbackFunc = func(method, path string, data interface{}, headers map[string][]string) (io.ReadCloser, http.Header, int, error) {
  48. var rsp string
  49. switch method {
  50. case "GET":
  51. if strings.Contains(path, fmt.Sprintf("networks?name=%s", mockNwName)) {
  52. rsp = string(mockNwListJSON)
  53. } else if strings.Contains(path, "networks?name=") {
  54. rsp = "[]"
  55. } else if strings.Contains(path, fmt.Sprintf("networks?partial-id=%s", mockNwID)) {
  56. rsp = string(mockNwListJSON)
  57. } else if strings.Contains(path, "networks?partial-id=") {
  58. rsp = "[]"
  59. } else if strings.HasSuffix(path, "networks") {
  60. rsp = string(mockNwListJSON)
  61. } else if strings.HasSuffix(path, "networks/"+mockNwID) {
  62. rsp = string(mockNwJSON)
  63. } else if strings.Contains(path, fmt.Sprintf("services?name=%s", mockServiceName)) {
  64. rsp = string(mockServiceListJSON)
  65. } else if strings.Contains(path, "services?name=") {
  66. rsp = "[]"
  67. } else if strings.Contains(path, fmt.Sprintf("services?partial-id=%s", mockServiceID)) {
  68. rsp = string(mockServiceListJSON)
  69. } else if strings.Contains(path, "services?partial-id=") {
  70. rsp = "[]"
  71. } else if strings.HasSuffix(path, "services") {
  72. rsp = string(mockServiceListJSON)
  73. } else if strings.HasSuffix(path, "services/"+mockServiceID) {
  74. rsp = string(mockServiceJSON)
  75. } else if strings.Contains(path, "containers") {
  76. return nopCloser{bytes.NewBufferString("")}, dummyHTTPHdr, 400, fmt.Errorf("Bad Request")
  77. } else if strings.Contains(path, fmt.Sprintf("sandboxes?container-id=%s", mockContainerID)) {
  78. rsp = string(mockSbListJSON)
  79. }
  80. case "POST":
  81. var data []byte
  82. if strings.HasSuffix(path, "networks") {
  83. data, _ = json.Marshal(mockNwID)
  84. } else if strings.HasSuffix(path, "services") {
  85. data, _ = json.Marshal(mockServiceID)
  86. } else if strings.HasSuffix(path, "backend") {
  87. data, _ = json.Marshal(mockSandboxID)
  88. }
  89. rsp = string(data)
  90. case "PUT":
  91. case "DELETE":
  92. rsp = ""
  93. }
  94. return nopCloser{bytes.NewBufferString(rsp)}, dummyHTTPHdr, 200, nil
  95. }
  96. }
  97. func TestClientDummyCommand(t *testing.T) {
  98. var out, errOut bytes.Buffer
  99. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  100. err := cli.Cmd("docker", "dummy")
  101. if err == nil {
  102. t.Fatalf("Incorrect Command must fail")
  103. }
  104. }
  105. func TestClientNetworkInvalidCommand(t *testing.T) {
  106. var out, errOut bytes.Buffer
  107. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  108. err := cli.Cmd("docker", "network", "invalid")
  109. if err == nil {
  110. t.Fatalf("Passing invalid commands must fail")
  111. }
  112. }
  113. func TestClientNetworkCreate(t *testing.T) {
  114. var out, errOut bytes.Buffer
  115. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  116. err := cli.Cmd("docker", "network", "create", mockNwName)
  117. if err != nil {
  118. t.Fatal(err.Error())
  119. }
  120. }
  121. func TestClientNetworkCreateWithDriver(t *testing.T) {
  122. var out, errOut bytes.Buffer
  123. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  124. err := cli.Cmd("docker", "network", "create", "-f=dummy", mockNwName)
  125. if err == nil {
  126. t.Fatalf("Passing incorrect flags to the create command must fail")
  127. }
  128. err = cli.Cmd("docker", "network", "create", "-d=dummy", mockNwName)
  129. if err != nil {
  130. t.Fatalf(err.Error())
  131. }
  132. }
  133. func TestClientNetworkRm(t *testing.T) {
  134. var out, errOut bytes.Buffer
  135. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  136. err := cli.Cmd("docker", "network", "rm", mockNwName)
  137. if err != nil {
  138. t.Fatal(err.Error())
  139. }
  140. }
  141. func TestClientNetworkLs(t *testing.T) {
  142. var out, errOut bytes.Buffer
  143. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  144. err := cli.Cmd("docker", "network", "ls")
  145. if err != nil {
  146. t.Fatal(err.Error())
  147. }
  148. }
  149. func TestClientNetworkInfo(t *testing.T) {
  150. var out, errOut bytes.Buffer
  151. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  152. err := cli.Cmd("docker", "network", "info", mockNwName)
  153. if err != nil {
  154. t.Fatal(err.Error())
  155. }
  156. }
  157. func TestClientNetworkInfoById(t *testing.T) {
  158. var out, errOut bytes.Buffer
  159. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  160. err := cli.Cmd("docker", "network", "info", mockNwID)
  161. if err != nil {
  162. t.Fatal(err.Error())
  163. }
  164. }
  165. // Docker Flag processing in flag.go uses os.Exit() frequently, even for --help
  166. // TODO : Handle the --help test-case in the IT when CLI is available
  167. /*
  168. func TestClientNetworkServiceCreateHelp(t *testing.T) {
  169. var out, errOut bytes.Buffer
  170. cFunc := func(method, path string, data interface{}, headers map[string][]string) (io.ReadCloser, int, error) {
  171. return nil, 0, nil
  172. }
  173. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  174. err := cli.Cmd("docker", "network", "create", "--help")
  175. if err != nil {
  176. t.Fatalf(err.Error())
  177. }
  178. }
  179. */
  180. // Docker flag processing in flag.go uses os.Exit(1) for incorrect parameter case.
  181. // TODO : Handle the missing argument case in the IT when CLI is available
  182. /*
  183. func TestClientNetworkServiceCreateMissingArgument(t *testing.T) {
  184. var out, errOut bytes.Buffer
  185. cFunc := func(method, path string, data interface{}, headers map[string][]string) (io.ReadCloser, int, error) {
  186. return nil, 0, nil
  187. }
  188. cli := NewNetworkCli(&out, &errOut, callbackFunc)
  189. err := cli.Cmd("docker", "network", "create")
  190. if err != nil {
  191. t.Fatal(err.Error())
  192. }
  193. }
  194. */