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