1// Copyright 2013 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"
9	"net/http"
10	"net/url"
11	"reflect"
12	"testing"
13)
14
15type DockerVersion struct {
16	Version   string
17	GitCommit string
18	GoVersion string
19}
20
21func TestVersion(t *testing.T) {
22	t.Parallel()
23	body := `{
24     "Version":"0.2.2",
25     "GitCommit":"5a2a5cc+CHANGES",
26     "GoVersion":"go1.0.3"
27}`
28	fakeRT := FakeRoundTripper{message: body, status: http.StatusOK}
29	client := newTestClient(&fakeRT)
30	expected := DockerVersion{
31		Version:   "0.2.2",
32		GitCommit: "5a2a5cc+CHANGES",
33		GoVersion: "go1.0.3",
34	}
35	version, err := client.Version()
36	if err != nil {
37		t.Fatal(err)
38	}
39
40	if result := version.Get("Version"); result != expected.Version {
41		t.Errorf("Version(): Wrong result. Want %#v. Got %#v.", expected.Version, version.Get("Version"))
42	}
43	if result := version.Get("GitCommit"); result != expected.GitCommit {
44		t.Errorf("GitCommit(): Wrong result. Want %#v. Got %#v.", expected.GitCommit, version.Get("GitCommit"))
45	}
46	if result := version.Get("GoVersion"); result != expected.GoVersion {
47		t.Errorf("GoVersion(): Wrong result. Want %#v. Got %#v.", expected.GoVersion, version.Get("GoVersion"))
48	}
49	req := fakeRT.requests[0]
50	if req.Method != "GET" {
51		t.Errorf("Version(): wrong request method. Want GET. Got %s.", req.Method)
52	}
53	u, _ := url.Parse(client.getURL("/version"))
54	if req.URL.Path != u.Path {
55		t.Errorf("Version(): wrong request path. Want %q. Got %q.", u.Path, req.URL.Path)
56	}
57}
58
59func TestVersionError(t *testing.T) {
60	t.Parallel()
61	fakeRT := &FakeRoundTripper{message: "internal error", status: http.StatusInternalServerError}
62	client := newTestClient(fakeRT)
63	version, err := client.Version()
64	if version != nil {
65		t.Errorf("Version(): expected <nil> value, got %#v.", version)
66	}
67	if err == nil {
68		t.Error("Version(): unexpected <nil> error")
69	}
70}
71
72func TestInfo(t *testing.T) {
73	t.Parallel()
74	body := `{
75     "Containers":11,
76     "Images":16,
77     "Debug":false,
78     "NFd":11,
79     "NGoroutines":21,
80     "MemoryLimit":true,
81     "SwapLimit":false,
82     "RegistryConfig":{
83       "InsecureRegistryCIDRs":["127.0.0.0/8"],
84       "IndexConfigs":{
85         "docker.io":{
86           "Name":"docker.io",
87           "Mirrors":null,
88           "Secure":true,
89           "Official":true
90         }
91       },
92       "Mirrors":null
93     },
94     "SecurityOptions": [
95     	"name=apparmor",
96     	"name=seccomp",
97     	"profile=default"
98     ]
99}`
100	fakeRT := FakeRoundTripper{message: body, status: http.StatusOK}
101	client := newTestClient(&fakeRT)
102	expected := &DockerInfo{
103		Containers:  11,
104		Images:      16,
105		Debug:       false,
106		NFd:         11,
107		NGoroutines: 21,
108		MemoryLimit: true,
109		SwapLimit:   false,
110		RegistryConfig: &ServiceConfig{
111			InsecureRegistryCIDRs: []*NetIPNet{
112				{
113					Mask: net.CIDRMask(8, 32),
114					IP:   net.ParseIP("127.0.0.0").To4(),
115				},
116			},
117			IndexConfigs: map[string]*IndexInfo{
118				"docker.io": {
119					Name:     "docker.io",
120					Secure:   true,
121					Official: true,
122				},
123			},
124		},
125		SecurityOptions: []string{
126			"name=apparmor",
127			"name=seccomp",
128			"profile=default",
129		},
130	}
131	info, err := client.Info()
132	if err != nil {
133		t.Fatal(err)
134	}
135	if !reflect.DeepEqual(expected, info) {
136		t.Errorf("Info(): Wrong result.\nWant %#v.\nGot %#v.", expected, info)
137	}
138	req := fakeRT.requests[0]
139	if req.Method != "GET" {
140		t.Errorf("Info(): Wrong HTTP method. Want GET. Got %s.", req.Method)
141	}
142	u, _ := url.Parse(client.getURL("/info"))
143	if req.URL.Path != u.Path {
144		t.Errorf("Info(): Wrong request path. Want %q. Got %q.", u.Path, req.URL.Path)
145	}
146}
147
148func TestInfoError(t *testing.T) {
149	t.Parallel()
150	fakeRT := &FakeRoundTripper{message: "internal error", status: http.StatusInternalServerError}
151	client := newTestClient(fakeRT)
152	version, err := client.Info()
153	if version != nil {
154		t.Errorf("Info(): expected <nil> value, got %#v.", version)
155	}
156	if err == nil {
157		t.Error("Info(): unexpected <nil> error")
158	}
159}
160
161func TestParseRepositoryTag(t *testing.T) {
162	t.Parallel()
163	var tests = []struct {
164		input        string
165		expectedRepo string
166		expectedTag  string
167	}{
168		{
169			"localhost.localdomain:5000/samalba/hipache:latest",
170			"localhost.localdomain:5000/samalba/hipache",
171			"latest",
172		},
173		{
174			"localhost.localdomain:5000/samalba/hipache",
175			"localhost.localdomain:5000/samalba/hipache",
176			"",
177		},
178		{
179			"tsuru/python",
180			"tsuru/python",
181			"",
182		},
183		{
184			"tsuru/python:2.7",
185			"tsuru/python",
186			"2.7",
187		},
188		{
189			"busybox@sha256:4a731fb46adc5cefe3ae374a8b6020fc1b6ad667a279647766e9a3cd89f6fa92",
190			"busybox",
191			"",
192		},
193		{
194			"localhost.localdomain:5000/samalba/hipache:v1@sha256:4a731fb46adc5cefe3ae374a8b6020fc1b6ad667a279647766e9a3cd89f6fa92",
195			"localhost.localdomain:5000/samalba/hipache",
196			"v1",
197		},
198	}
199	for _, tt := range tests {
200		repo, tag := ParseRepositoryTag(tt.input)
201		if repo != tt.expectedRepo {
202			t.Errorf("ParseRepositoryTag(%q): wrong repository. Want %q. Got %q", tt.input, tt.expectedRepo, repo)
203		}
204		if tag != tt.expectedTag {
205			t.Errorf("ParseRepositoryTag(%q): wrong tag. Want %q. Got %q", tt.input, tt.expectedTag, tag)
206		}
207	}
208}
209