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  }