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