github.com/csfrancis/docker@v1.8.0-rc2/integration-cli/docker_cli_start_volume_driver_unix_test.go (about) 1 // +build !windows 2 3 package main 4 5 import ( 6 "encoding/json" 7 "fmt" 8 "io/ioutil" 9 "net/http" 10 "net/http/httptest" 11 "os" 12 "path/filepath" 13 "strings" 14 15 "github.com/go-check/check" 16 ) 17 18 func init() { 19 check.Suite(&DockerExternalVolumeSuite{ 20 ds: &DockerSuite{}, 21 }) 22 } 23 24 type eventCounter struct { 25 activations int 26 creations int 27 removals int 28 mounts int 29 unmounts int 30 paths int 31 } 32 33 type DockerExternalVolumeSuite struct { 34 server *httptest.Server 35 ds *DockerSuite 36 d *Daemon 37 ec *eventCounter 38 } 39 40 func (s *DockerExternalVolumeSuite) SetUpTest(c *check.C) { 41 s.d = NewDaemon(c) 42 s.ec = &eventCounter{} 43 } 44 45 func (s *DockerExternalVolumeSuite) TearDownTest(c *check.C) { 46 s.d.Stop() 47 s.ds.TearDownTest(c) 48 } 49 50 func (s *DockerExternalVolumeSuite) SetUpSuite(c *check.C) { 51 mux := http.NewServeMux() 52 s.server = httptest.NewServer(mux) 53 54 type pluginRequest struct { 55 name string 56 } 57 58 mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) { 59 s.ec.activations++ 60 61 w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") 62 fmt.Fprintln(w, `{"Implements": ["VolumeDriver"]}`) 63 }) 64 65 mux.HandleFunc("/VolumeDriver.Create", func(w http.ResponseWriter, r *http.Request) { 66 s.ec.creations++ 67 68 w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") 69 fmt.Fprintln(w, `{}`) 70 }) 71 72 mux.HandleFunc("/VolumeDriver.Remove", func(w http.ResponseWriter, r *http.Request) { 73 s.ec.removals++ 74 75 w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") 76 fmt.Fprintln(w, `{}`) 77 }) 78 79 mux.HandleFunc("/VolumeDriver.Path", func(w http.ResponseWriter, r *http.Request) { 80 s.ec.paths++ 81 82 var pr pluginRequest 83 if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { 84 http.Error(w, err.Error(), 500) 85 } 86 87 p := hostVolumePath(pr.name) 88 89 w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") 90 fmt.Fprintln(w, fmt.Sprintf("{\"Mountpoint\": \"%s\"}", p)) 91 }) 92 93 mux.HandleFunc("/VolumeDriver.Mount", func(w http.ResponseWriter, r *http.Request) { 94 s.ec.mounts++ 95 96 var pr pluginRequest 97 if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { 98 http.Error(w, err.Error(), 500) 99 } 100 101 p := hostVolumePath(pr.name) 102 if err := os.MkdirAll(p, 0755); err != nil { 103 http.Error(w, err.Error(), 500) 104 } 105 106 if err := ioutil.WriteFile(filepath.Join(p, "test"), []byte(s.server.URL), 0644); err != nil { 107 http.Error(w, err.Error(), 500) 108 } 109 110 w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") 111 fmt.Fprintln(w, fmt.Sprintf("{\"Mountpoint\": \"%s\"}", p)) 112 }) 113 114 mux.HandleFunc("/VolumeDriver.Unmount", func(w http.ResponseWriter, r *http.Request) { 115 s.ec.unmounts++ 116 117 var pr pluginRequest 118 if err := json.NewDecoder(r.Body).Decode(&pr); err != nil { 119 http.Error(w, err.Error(), 500) 120 } 121 122 p := hostVolumePath(pr.name) 123 if err := os.RemoveAll(p); err != nil { 124 http.Error(w, err.Error(), 500) 125 } 126 127 w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json") 128 fmt.Fprintln(w, `{}`) 129 }) 130 131 if err := os.MkdirAll("/etc/docker/plugins", 0755); err != nil { 132 c.Fatal(err) 133 } 134 135 if err := ioutil.WriteFile("/etc/docker/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644); err != nil { 136 c.Fatal(err) 137 } 138 } 139 140 func (s *DockerExternalVolumeSuite) TearDownSuite(c *check.C) { 141 s.server.Close() 142 143 if err := os.RemoveAll("/etc/docker/plugins"); err != nil { 144 c.Fatal(err) 145 } 146 } 147 148 func (s *DockerExternalVolumeSuite) TestStartExternalNamedVolumeDriver(c *check.C) { 149 if err := s.d.StartWithBusybox(); err != nil { 150 c.Fatal(err) 151 } 152 153 out, err := s.d.Cmd("run", "--rm", "--name", "test-data", "-v", "external-volume-test:/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", "busybox:latest", "cat", "/tmp/external-volume-test/test") 154 if err != nil { 155 c.Fatal(err) 156 } 157 158 if !strings.Contains(out, s.server.URL) { 159 c.Fatalf("External volume mount failed. Output: %s\n", out) 160 } 161 162 p := hostVolumePath("external-volume-test") 163 _, err = os.Lstat(p) 164 if err == nil { 165 c.Fatalf("Expected error checking volume path in host: %s\n", p) 166 } 167 168 if !os.IsNotExist(err) { 169 c.Fatalf("Expected volume path in host to not exist: %s, %v\n", p, err) 170 } 171 172 c.Assert(s.ec.activations, check.Equals, 1) 173 c.Assert(s.ec.creations, check.Equals, 1) 174 c.Assert(s.ec.removals, check.Equals, 1) 175 c.Assert(s.ec.mounts, check.Equals, 1) 176 c.Assert(s.ec.unmounts, check.Equals, 1) 177 } 178 179 func (s *DockerExternalVolumeSuite) TestStartExternalVolumeUnnamedDriver(c *check.C) { 180 if err := s.d.StartWithBusybox(); err != nil { 181 c.Fatal(err) 182 } 183 184 out, err := s.d.Cmd("run", "--rm", "--name", "test-data", "-v", "/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", "busybox:latest", "cat", "/tmp/external-volume-test/test") 185 if err != nil { 186 c.Fatal(err) 187 } 188 189 if !strings.Contains(out, s.server.URL) { 190 c.Fatalf("External volume mount failed. Output: %s\n", out) 191 } 192 193 c.Assert(s.ec.activations, check.Equals, 1) 194 c.Assert(s.ec.creations, check.Equals, 1) 195 c.Assert(s.ec.removals, check.Equals, 1) 196 c.Assert(s.ec.mounts, check.Equals, 1) 197 c.Assert(s.ec.unmounts, check.Equals, 1) 198 } 199 200 func (s DockerExternalVolumeSuite) TestStartExternalVolumeDriverVolumesFrom(c *check.C) { 201 if err := s.d.StartWithBusybox(); err != nil { 202 c.Fatal(err) 203 } 204 205 if _, err := s.d.Cmd("run", "-d", "--name", "vol-test1", "-v", "/foo", "--volume-driver", "test-external-volume-driver", "busybox:latest"); err != nil { 206 c.Fatal(err) 207 } 208 209 if _, err := s.d.Cmd("run", "--rm", "--volumes-from", "vol-test1", "--name", "vol-test2", "busybox", "ls", "/tmp"); err != nil { 210 c.Fatal(err) 211 } 212 213 if _, err := s.d.Cmd("rm", "-f", "vol-test1"); err != nil { 214 c.Fatal(err) 215 } 216 217 c.Assert(s.ec.activations, check.Equals, 1) 218 c.Assert(s.ec.creations, check.Equals, 2) 219 c.Assert(s.ec.removals, check.Equals, 1) 220 c.Assert(s.ec.mounts, check.Equals, 2) 221 c.Assert(s.ec.unmounts, check.Equals, 2) 222 } 223 224 func (s DockerExternalVolumeSuite) TestStartExternalVolumeDriverDeleteContainer(c *check.C) { 225 if err := s.d.StartWithBusybox(); err != nil { 226 c.Fatal(err) 227 } 228 229 if _, err := s.d.Cmd("run", "-d", "--name", "vol-test1", "-v", "/foo", "--volume-driver", "test-external-volume-driver", "busybox:latest"); err != nil { 230 c.Fatal(err) 231 } 232 233 if _, err := s.d.Cmd("rm", "-fv", "vol-test1"); err != nil { 234 c.Fatal(err) 235 } 236 237 c.Assert(s.ec.activations, check.Equals, 1) 238 c.Assert(s.ec.creations, check.Equals, 1) 239 c.Assert(s.ec.removals, check.Equals, 1) 240 c.Assert(s.ec.mounts, check.Equals, 1) 241 c.Assert(s.ec.unmounts, check.Equals, 1) 242 } 243 244 func hostVolumePath(name string) string { 245 return fmt.Sprintf("/var/lib/docker/volumes/%s", name) 246 }