github.com/yuanlv/docker@v1.8.1/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  }