1// Copyright 2015 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	"encoding/json"
9	"net/http"
10	"net/url"
11	"reflect"
12	"testing"
13)
14
15func TestListVolumes(t *testing.T) {
16	t.Parallel()
17	volumesData := `[
18	{
19		"Name": "tardis",
20		"Driver": "local",
21		"Mountpoint": "/var/lib/docker/volumes/tardis",
22		"CreatedAt": "2017-07-19T12:00:26Z"
23	},
24	{
25		"Name": "foo",
26		"Driver": "bar",
27		"Mountpoint": "/var/lib/docker/volumes/bar",
28		"CreatedAt": "2017-07-19T12:01:26Z"
29	}
30]`
31	body := `{ "Volumes": ` + volumesData + ` }`
32	var expected []Volume
33	if err := json.Unmarshal([]byte(volumesData), &expected); err != nil {
34		t.Fatal(err)
35	}
36	client := newTestClient(&FakeRoundTripper{message: body, status: http.StatusOK})
37	volumes, err := client.ListVolumes(ListVolumesOptions{})
38	if err != nil {
39		t.Error(err)
40	}
41	if !reflect.DeepEqual(volumes, expected) {
42		t.Errorf("ListVolumes: Wrong return value. Want %#v. Got %#v.", expected, volumes)
43	}
44}
45
46func TestCreateVolume(t *testing.T) {
47	t.Parallel()
48	body := `{
49		"Name": "tardis",
50		"Driver": "local",
51		"Mountpoint": "/var/lib/docker/volumes/tardis"
52	}`
53	var expected Volume
54	if err := json.Unmarshal([]byte(body), &expected); err != nil {
55		t.Fatal(err)
56	}
57	fakeRT := &FakeRoundTripper{message: body, status: http.StatusOK}
58	client := newTestClient(fakeRT)
59	volume, err := client.CreateVolume(
60		CreateVolumeOptions{
61			Name:   "tardis",
62			Driver: "local",
63			DriverOpts: map[string]string{
64				"foo": "bar",
65			},
66		},
67	)
68	if err != nil {
69		t.Fatal(err)
70	}
71	if !reflect.DeepEqual(volume, &expected) {
72		t.Errorf("CreateVolume: Wrong return value. Want %#v. Got %#v.", expected, volume)
73	}
74	req := fakeRT.requests[0]
75	expectedMethod := "POST"
76	if req.Method != expectedMethod {
77		t.Errorf("CreateVolume(): Wrong HTTP method. Want %s. Got %s.", expectedMethod, req.Method)
78	}
79	u, _ := url.Parse(client.getURL("/volumes/create"))
80	if req.URL.Path != u.Path {
81		t.Errorf("CreateVolume(): Wrong request path. Want %q. Got %q.", u.Path, req.URL.Path)
82	}
83}
84
85func TestInspectVolume(t *testing.T) {
86	t.Parallel()
87	body := `{
88		"Name": "tardis",
89		"Driver": "local",
90		"Mountpoint": "/var/lib/docker/volumes/tardis",
91		"Options": {
92			"foo": "bar"
93		}
94	}`
95	var expected Volume
96	if err := json.Unmarshal([]byte(body), &expected); err != nil {
97		t.Fatal(err)
98	}
99	fakeRT := &FakeRoundTripper{message: body, status: http.StatusOK}
100	client := newTestClient(fakeRT)
101	name := "tardis"
102	volume, err := client.InspectVolume(name)
103	if err != nil {
104		t.Fatal(err)
105	}
106	if !reflect.DeepEqual(volume, &expected) {
107		t.Errorf("InspectVolume: Wrong return value. Want %#v. Got %#v.", expected, volume)
108	}
109	req := fakeRT.requests[0]
110	expectedMethod := "GET"
111	if req.Method != expectedMethod {
112		t.Errorf("InspectVolume(%q): Wrong HTTP method. Want %s. Got %s.", name, expectedMethod, req.Method)
113	}
114	u, _ := url.Parse(client.getURL("/volumes/" + name))
115	if req.URL.Path != u.Path {
116		t.Errorf("CreateVolume(%q): Wrong request path. Want %q. Got %q.", name, u.Path, req.URL.Path)
117	}
118}
119
120func TestRemoveVolume(t *testing.T) {
121	t.Parallel()
122	name := "test"
123	fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
124	client := newTestClient(fakeRT)
125	if err := client.RemoveVolume(name); err != nil {
126		t.Fatal(err)
127	}
128	req := fakeRT.requests[0]
129	expectedMethod := "DELETE"
130	if req.Method != expectedMethod {
131		t.Errorf("RemoveVolume(%q): Wrong HTTP method. Want %s. Got %s.", name, expectedMethod, req.Method)
132	}
133	u, _ := url.Parse(client.getURL("/volumes/" + name))
134	if req.URL.Path != u.Path {
135		t.Errorf("RemoveVolume(%q): Wrong request path. Want %q. Got %q.", name, u.Path, req.URL.Path)
136	}
137}
138
139func TestRemoveVolumeWithOptions(t *testing.T) {
140	t.Parallel()
141	name := "test"
142	fakeRT := &FakeRoundTripper{message: "", status: http.StatusNoContent}
143	client := newTestClient(fakeRT)
144	if err := client.RemoveVolumeWithOptions(RemoveVolumeOptions{
145		Name:  name,
146		Force: true,
147	}); err != nil {
148		t.Fatal(err)
149	}
150	req := fakeRT.requests[0]
151	expectedMethod := "DELETE"
152	if req.Method != expectedMethod {
153		t.Errorf("RemoveVolume(%q): Wrong HTTP method. Want %s. Got %s.", name, expectedMethod, req.Method)
154	}
155	u, _ := url.Parse(client.getURL("/volumes/" + name + "?force=1"))
156	if req.URL.RequestURI() != u.RequestURI() {
157		t.Errorf("RemoveVolume(%q): Wrong request path. Want %q. Got %q.", name, u.RequestURI(), req.URL.RequestURI())
158	}
159}
160
161func TestRemoveVolumeNotFound(t *testing.T) {
162	t.Parallel()
163	client := newTestClient(&FakeRoundTripper{message: "no such volume", status: http.StatusNotFound})
164	if err := client.RemoveVolume("test:"); err != ErrNoSuchVolume {
165		t.Errorf("RemoveVolume: wrong error. Want %#v. Got %#v.", ErrNoSuchVolume, err)
166	}
167}
168
169func TestRemoveVolumeInternalError(t *testing.T) {
170	t.Parallel()
171	client := newTestClient(&FakeRoundTripper{message: "something went wrong", status: http.StatusInternalServerError})
172	if err := client.RemoveVolume("test:test"); err == nil {
173		t.Error("RemoveVolume: unexpected <nil> error")
174	}
175}
176
177func TestRemoveVolumeInUse(t *testing.T) {
178	t.Parallel()
179	client := newTestClient(&FakeRoundTripper{message: "volume in use and cannot be removed", status: http.StatusConflict})
180	if err := client.RemoveVolume("test:"); err != ErrVolumeInUse {
181		t.Errorf("RemoveVolume: wrong error. Want %#v. Got %#v.", ErrVolumeInUse, err)
182	}
183}
184
185func TestPruneVolumes(t *testing.T) {
186	t.Parallel()
187	results := `{
188		"VolumesDeleted": [
189			"a", "b", "c"
190		],
191		"SpaceReclaimed": 123
192	}`
193
194	expected := &PruneVolumesResults{}
195	err := json.Unmarshal([]byte(results), expected)
196	if err != nil {
197		t.Fatal(err)
198	}
199	client := newTestClient(&FakeRoundTripper{message: results, status: http.StatusOK})
200	got, err := client.PruneVolumes(PruneVolumesOptions{})
201	if err != nil {
202		t.Fatal(err)
203	}
204	if !reflect.DeepEqual(got, expected) {
205		t.Errorf("PruneContainers: Expected %#v. Got %#v.", expected, got)
206	}
207}
208