1// Copyright 2016 go-dockerclient authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package docker
6
7import (
8	"net/http"
9	"net/url"
10	"reflect"
11	"testing"
12
13	"github.com/docker/docker/api/types/swarm"
14)
15
16func TestInitSwarm(t *testing.T) {
17	t.Parallel()
18	fakeRT := &FakeRoundTripper{message: `"body"`, status: http.StatusOK}
19	client := newTestClient(fakeRT)
20	response, err := client.InitSwarm(InitSwarmOptions{})
21	if err != nil {
22		t.Fatal(err)
23	}
24	req := fakeRT.requests[0]
25	expectedMethod := "POST"
26	if req.Method != expectedMethod {
27		t.Errorf("InitSwarm: Wrong HTTP method. Want %s. Got %s.", expectedMethod, req.Method)
28	}
29	u, _ := url.Parse(client.getURL("/swarm/init"))
30	if req.URL.Path != u.Path {
31		t.Errorf("InitSwarm: Wrong request path. Want %q. Got %q.", u.Path, req.URL.Path)
32	}
33	expected := "body"
34	if response != expected {
35		t.Errorf("InitSwarm: Wrong response. Want %q. Got %q.", expected, response)
36	}
37}
38
39func TestInitSwarmAlreadyInSwarm(t *testing.T) {
40	t.Parallel()
41	client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
42	_, err := client.InitSwarm(InitSwarmOptions{})
43	if err != ErrNodeAlreadyInSwarm {
44		t.Errorf("InitSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeAlreadyInSwarm, err)
45	}
46	client = newTestClient(&FakeRoundTripper{message: "", status: http.StatusServiceUnavailable})
47	_, err = client.InitSwarm(InitSwarmOptions{})
48	if err != ErrNodeAlreadyInSwarm {
49		t.Errorf("InitSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeAlreadyInSwarm, err)
50	}
51}
52
53func TestJoinSwarm(t *testing.T) {
54	t.Parallel()
55	fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
56	client := newTestClient(fakeRT)
57	err := client.JoinSwarm(JoinSwarmOptions{})
58	if err != nil {
59		t.Fatal(err)
60	}
61	req := fakeRT.requests[0]
62	expectedMethod := "POST"
63	if req.Method != expectedMethod {
64		t.Errorf("JoinSwarm: Wrong HTTP method. Want %s. Got %s.", expectedMethod, req.Method)
65	}
66	u, _ := url.Parse(client.getURL("/swarm/join"))
67	if req.URL.Path != u.Path {
68		t.Errorf("JoinSwarm: Wrong request path. Want %q. Got %q.", u.Path, req.URL.Path)
69	}
70}
71
72func TestJoinSwarmAlreadyInSwarm(t *testing.T) {
73	t.Parallel()
74	client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
75	err := client.JoinSwarm(JoinSwarmOptions{})
76	if err != ErrNodeAlreadyInSwarm {
77		t.Errorf("JoinSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeAlreadyInSwarm, err)
78	}
79	client = newTestClient(&FakeRoundTripper{message: "", status: http.StatusServiceUnavailable})
80	err = client.JoinSwarm(JoinSwarmOptions{})
81	if err != ErrNodeAlreadyInSwarm {
82		t.Errorf("JoinSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeAlreadyInSwarm, err)
83	}
84}
85
86func TestLeaveSwarm(t *testing.T) {
87	t.Parallel()
88	fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
89	client := newTestClient(fakeRT)
90	var testData = []struct {
91		force       bool
92		expectedURI string
93	}{
94		{false, "/swarm/leave?force=false"},
95		{true, "/swarm/leave?force=true"},
96	}
97	for i, tt := range testData {
98		err := client.LeaveSwarm(LeaveSwarmOptions{Force: tt.force})
99		if err != nil {
100			t.Fatal(err)
101		}
102		expectedMethod := "POST"
103		req := fakeRT.requests[i]
104		if req.Method != expectedMethod {
105			t.Errorf("LeaveSwarm: Wrong HTTP method. Want %s. Got %s.", expectedMethod, req.Method)
106		}
107		expected, _ := url.Parse(client.getURL(tt.expectedURI))
108		if req.URL.String() != expected.String() {
109			t.Errorf("LeaveSwarm: Wrong request string. Want %q. Got %q.", expected.String(), req.URL.String())
110		}
111	}
112}
113
114func TestLeaveSwarmNotInSwarm(t *testing.T) {
115	t.Parallel()
116	client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
117	err := client.LeaveSwarm(LeaveSwarmOptions{})
118	if err != ErrNodeNotInSwarm {
119		t.Errorf("LeaveSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeNotInSwarm, err)
120	}
121	client = newTestClient(&FakeRoundTripper{message: "", status: http.StatusServiceUnavailable})
122	err = client.LeaveSwarm(LeaveSwarmOptions{})
123	if err != ErrNodeNotInSwarm {
124		t.Errorf("LeaveSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeNotInSwarm, err)
125	}
126}
127
128func TestUpdateSwarm(t *testing.T) {
129	t.Parallel()
130	fakeRT := &FakeRoundTripper{message: "", status: http.StatusOK}
131	client := newTestClient(fakeRT)
132	opts := UpdateSwarmOptions{
133		Version:            10,
134		RotateManagerToken: true,
135		RotateWorkerToken:  false,
136	}
137	err := client.UpdateSwarm(opts)
138	if err != nil {
139		t.Fatal(err)
140	}
141	req := fakeRT.requests[0]
142	expectedMethod := "POST"
143	if req.Method != expectedMethod {
144		t.Errorf("UpdateSwarm: Wrong HTTP method. Want %s. Got %s.", expectedMethod, req.Method)
145	}
146	expectedPath := "/swarm/update"
147	if req.URL.Path != expectedPath {
148		t.Errorf("UpdateSwarm: Wrong request path. Want %q. Got %q.", expectedPath, req.URL.Path)
149	}
150	expected := map[string][]string{
151		"version":            {"10"},
152		"rotateManagerToken": {"true"},
153		"rotateWorkerToken":  {"false"},
154	}
155	got := map[string][]string(req.URL.Query())
156	if !reflect.DeepEqual(got, expected) {
157		t.Errorf("UpdateSwarm: Wrong request query. Want %v. Got %v", expected, got)
158	}
159}
160
161func TestUpdateSwarmNotInSwarm(t *testing.T) {
162	t.Parallel()
163	client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
164	err := client.UpdateSwarm(UpdateSwarmOptions{})
165	if err != ErrNodeNotInSwarm {
166		t.Errorf("UpdateSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeNotInSwarm, err)
167	}
168	client = newTestClient(&FakeRoundTripper{message: "", status: http.StatusServiceUnavailable})
169	err = client.UpdateSwarm(UpdateSwarmOptions{})
170	if err != ErrNodeNotInSwarm {
171		t.Errorf("UpdateSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeNotInSwarm, err)
172	}
173}
174
175func TestInspectSwarm(t *testing.T) {
176	t.Parallel()
177	fakeRT := &FakeRoundTripper{message: `{"ID": "123"}`, status: http.StatusOK}
178	client := newTestClient(fakeRT)
179	response, err := client.InspectSwarm(nil)
180	if err != nil {
181		t.Fatal(err)
182	}
183	req := fakeRT.requests[0]
184	expectedMethod := "GET"
185	if req.Method != expectedMethod {
186		t.Errorf("InspectSwarm: Wrong HTTP method. Want %s. Got %s.", expectedMethod, req.Method)
187	}
188	u, _ := url.Parse(client.getURL("/swarm"))
189	if req.URL.Path != u.Path {
190		t.Errorf("InspectSwarm: Wrong request path. Want %q. Got %q.", u.Path, req.URL.Path)
191	}
192	expected := swarm.Swarm{ClusterInfo: swarm.ClusterInfo{ID: "123"}}
193	if !reflect.DeepEqual(expected, response) {
194		t.Errorf("InspectSwarm: Wrong response. Want %#v. Got %#v.", expected, response)
195	}
196}
197
198func TestInspectSwarmNotInSwarm(t *testing.T) {
199	t.Parallel()
200	client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusNotAcceptable})
201	_, err := client.InspectSwarm(nil)
202	if err != ErrNodeNotInSwarm {
203		t.Errorf("InspectSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeNotInSwarm, err)
204	}
205	client = newTestClient(&FakeRoundTripper{message: "", status: http.StatusServiceUnavailable})
206	_, err = client.InspectSwarm(nil)
207	if err != ErrNodeNotInSwarm {
208		t.Errorf("InspectSwarm: Wrong error type. Want %#v. Got %#v", ErrNodeNotInSwarm, err)
209	}
210}
211