1// Copyright 2018 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 "context" 9 "encoding/json" 10 "fmt" 11 "net/http" 12 13 "reflect" 14 15 "testing" 16) 17 18var ( 19 expectPluginDetail = PluginDetail{ 20 ID: "5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078", 21 Name: "tiborvass/sample-volume-plugin", 22 Tag: "latest", 23 Active: true, 24 Settings: PluginSettings{ 25 Env: []string{"DEBUG=0"}, 26 Args: nil, 27 Devices: nil, 28 }, 29 Config: PluginConfig{ 30 Description: "A sample volume plugin for Docker", 31 Documentation: "https://docs.docker.com/engine/extend/plugins/", 32 Interface: PluginInterface{ 33 Types: []string{"docker.volumedriver/1.0"}, 34 Socket: "plugins.sock", 35 }, 36 Entrypoint: []string{ 37 "/usr/bin/sample-volume-plugin", 38 "/data", 39 }, 40 WorkDir: "", 41 User: PluginUser{}, 42 Network: PluginNetwork{Type: ""}, 43 Linux: PluginLinux{Capabilities: nil, AllowAllDevices: false, Devices: nil}, 44 Mounts: nil, 45 PropagatedMount: "/data", 46 Env: []PluginEnv{ 47 { 48 Name: "DEBUG", 49 Description: "If set, prints debug messages", 50 Settable: nil, 51 Value: "0", 52 }, 53 }, 54 Args: PluginArgs{ 55 Name: "args", 56 Description: "command line arguments", 57 Settable: nil, 58 Value: []string{}, 59 }, 60 }, 61 } 62) 63 64const ( 65 jsonPluginDetail = `{ 66 "Id": "5724e2c8652da337ab2eedd19fc6fc0ec908e4bd907c7421bf6a8dfc70c4c078", 67 "Name": "tiborvass/sample-volume-plugin", 68 "Tag": "latest", 69 "Enabled": true, 70 "Settings": { 71 "Env": [ 72 "DEBUG=0" 73 ], 74 "Args": null, 75 "Devices": null 76 }, 77 "Config": { 78 "Description": "A sample volume plugin for Docker", 79 "Documentation": "https://docs.docker.com/engine/extend/plugins/", 80 "Interface": { 81 "Types": [ 82 "docker.volumedriver/1.0" 83 ], 84 "Socket": "plugins.sock" 85 }, 86 "Entrypoint": [ 87 "/usr/bin/sample-volume-plugin", 88 "/data" 89 ], 90 "WorkDir": "", 91 "User": {}, 92 "Network": { 93 "Type": "" 94 }, 95 "Linux": { 96 "Capabilities": null, 97 "AllowAllDevices": false, 98 "Devices": null 99 }, 100 "Mounts": null, 101 "PropagatedMount": "/data", 102 "Env": [ 103 { 104 "Name": "DEBUG", 105 "Description": "If set, prints debug messages", 106 "Settable": null, 107 "Value": "0" 108 } 109 ], 110 "Args": { 111 "Name": "args", 112 "Description": "command line arguments", 113 "Settable": null, 114 "Value": [] 115 } 116 } 117 }` 118) 119 120func TestListPlugins(t *testing.T) { 121 t.Parallel() 122 jsonPlugins := fmt.Sprintf("[%s]", jsonPluginDetail) 123 var expected []PluginDetail 124 err := json.Unmarshal([]byte(jsonPlugins), &expected) 125 if err != nil { 126 t.Fatal(err) 127 } 128 client := newTestClient(&FakeRoundTripper{message: jsonPlugins, status: http.StatusOK}) 129 pluginDetails, err := client.ListPlugins(context.Background()) 130 if err != nil { 131 t.Fatal(err) 132 } 133 if !reflect.DeepEqual(pluginDetails, expected) { 134 t.Errorf("ListPlugins: Expected %#v. Got %#v.", expected, pluginDetails) 135 } 136} 137 138func TestListFilteredPlugins(t *testing.T) { 139 t.Parallel() 140 jsonPlugins := fmt.Sprintf("[%s]", jsonPluginDetail) 141 var expected []PluginDetail 142 err := json.Unmarshal([]byte(jsonPlugins), &expected) 143 if err != nil { 144 t.Fatal(err) 145 } 146 client := newTestClient(&FakeRoundTripper{message: jsonPlugins, status: http.StatusOK}) 147 148 pluginDetails, err := client.ListFilteredPlugins( 149 ListFilteredPluginsOptions{ 150 Filters: map[string][]string{ 151 "capability": {"volumedriver"}, 152 "enabled": {"true"}, 153 }, 154 Context: context.Background()}) 155 if err != nil { 156 t.Fatal(err) 157 } 158 if !reflect.DeepEqual(pluginDetails, expected) { 159 t.Errorf("ListPlugins: Expected %#v. Got %#v.", expected, pluginDetails) 160 } 161} 162 163func TestListFilteredPluginsFailure(t *testing.T) { 164 t.Parallel() 165 var tests = []struct { 166 status int 167 message string 168 }{ 169 {400, "bad parameter"}, 170 {500, "internal server error"}, 171 } 172 for _, tt := range tests { 173 client := newTestClient(&FakeRoundTripper{message: tt.message, status: tt.status}) 174 expected := Error{Status: tt.status, Message: tt.message} 175 pluginDetails, err := client.ListFilteredPlugins(ListFilteredPluginsOptions{}) 176 if !reflect.DeepEqual(expected, *err.(*Error)) { 177 t.Errorf("Wrong error in ListFilteredPlugins. Want %#v. Got %#v.", expected, err) 178 } 179 if len(pluginDetails) > 0 { 180 t.Errorf("ListFilteredPlugins failure. Expected empty list. Got %#v.", pluginDetails) 181 } 182 } 183} 184 185func TestGetPluginPrivileges(t *testing.T) { 186 t.Parallel() 187 name := "test_plugin" 188 jsonPluginPrivileges := `[ { "Name": "network", "Description": "", "Value": [ "host" ] }]` 189 fakeRT := &FakeRoundTripper{message: jsonPluginPrivileges, status: http.StatusNoContent} 190 client := newTestClient(fakeRT) 191 expected := []PluginPrivilege{ 192 { 193 Name: "network", 194 Description: "", 195 Value: []string{"host"}, 196 }} 197 pluginPrivileges, err := client.GetPluginPrivileges(name, context.Background()) 198 if err != nil { 199 t.Fatal(err) 200 } 201 if !reflect.DeepEqual(pluginPrivileges, expected) { 202 t.Errorf("PluginPrivileges: Expected %#v. Got %#v.", expected, pluginPrivileges) 203 } 204} 205 206func TestInstallPlugins(t *testing.T) { 207 opts := InstallPluginOptions{ 208 Remote: "", Name: "test", 209 Plugins: []PluginPrivilege{ 210 { 211 Name: "network", 212 Description: "", 213 Value: []string{"host"}, 214 }, 215 }, 216 Context: context.Background(), 217 Auth: AuthConfiguration{}, 218 } 219 220 client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusOK}) 221 err := client.InstallPlugins(opts) 222 if err != nil { 223 t.Fatal(err) 224 } 225} 226 227func TestInspectPlugin(t *testing.T) { 228 name := "test_plugin" 229 fakeRT := &FakeRoundTripper{message: jsonPluginDetail, status: http.StatusNoContent} 230 client := newTestClient(fakeRT) 231 pluginPrivileges, err := client.InspectPlugins(name, context.Background()) 232 if err != nil { 233 t.Fatal(err) 234 } 235 if !reflect.DeepEqual(pluginPrivileges, &expectPluginDetail) { 236 t.Errorf("InspectPlugins: Expected %#v. Got %#v.", &expectPluginDetail, pluginPrivileges) 237 } 238} 239 240func TestRemovePlugin(t *testing.T) { 241 opts := RemovePluginOptions{ 242 Name: "test_plugin", 243 Force: false, 244 Context: context.Background(), 245 } 246 fakeRT := &FakeRoundTripper{message: jsonPluginDetail, status: http.StatusNoContent} 247 client := newTestClient(fakeRT) 248 pluginPrivileges, err := client.RemovePlugin(opts) 249 if err != nil { 250 t.Fatal(err) 251 } 252 if !reflect.DeepEqual(pluginPrivileges, &expectPluginDetail) { 253 t.Errorf("RemovePlugin: Expected %#v. Got %#v.", &expectPluginDetail, pluginPrivileges) 254 } 255} 256 257func TestEnablePlugin(t *testing.T) { 258 opts := EnablePluginOptions{ 259 Name: "test", 260 Timeout: 5, 261 Context: context.Background(), 262 } 263 client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusOK}) 264 err := client.EnablePlugin(opts) 265 if err != nil { 266 t.Fatal(err) 267 } 268} 269 270func TestDisablePlugin(t *testing.T) { 271 opts := DisablePluginOptions{ 272 Name: "test", 273 Context: context.Background(), 274 } 275 client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusOK}) 276 err := client.DisablePlugin(opts) 277 if err != nil { 278 t.Fatal(err) 279 } 280} 281 282func TestCreatePlugin(t *testing.T) { 283 opts := CreatePluginOptions{ 284 Name: "test", 285 Path: "", 286 Context: context.Background(), 287 } 288 client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusOK}) 289 _, err := client.CreatePlugin(opts) 290 if err != nil { 291 t.Fatal(err) 292 } 293} 294 295func TestPushPlugin(t *testing.T) { 296 opts := PushPluginOptions{ 297 Name: "test", 298 Context: context.Background(), 299 } 300 client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusOK}) 301 err := client.PushPlugin(opts) 302 if err != nil { 303 t.Fatal(err) 304 } 305} 306 307func TestConfigurePlugin(t *testing.T) { 308 opts := ConfigurePluginOptions{ 309 Name: "test", 310 Envs: []string{}, 311 Context: context.Background(), 312 } 313 client := newTestClient(&FakeRoundTripper{message: "", status: http.StatusOK}) 314 err := client.ConfigurePlugin(opts) 315 if err != nil { 316 t.Fatal(err) 317 } 318} 319