123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- package volume
- import (
- "runtime"
- "strings"
- "testing"
- )
- func TestParseMountSpec(t *testing.T) {
- var (
- valid []string
- invalid map[string]string
- )
- if runtime.GOOS == "windows" {
- valid = []string{
- `d:\`,
- `d:`,
- `d:\path`,
- `d:\path with space`,
- // TODO Windows post TP5 - readonly support `d:\pathandmode:ro`,
- `c:\:d:\`,
- `c:\windows\:d:`,
- `c:\windows:d:\s p a c e`,
- `c:\windows:d:\s p a c e:RW`,
- `c:\program files:d:\s p a c e i n h o s t d i r`,
- `0123456789name:d:`,
- `MiXeDcAsEnAmE:d:`,
- `name:D:`,
- `name:D::rW`,
- `name:D::RW`,
- // TODO Windows post TP5 - readonly support `name:D::RO`,
- `c:/:d:/forward/slashes/are/good/too`,
- // TODO Windows post TP5 - readonly support `c:/:d:/including with/spaces:ro`,
- `c:\Windows`, // With capital
- `c:\Program Files (x86)`, // With capitals and brackets
- }
- invalid = map[string]string{
- ``: "Invalid volume specification: ",
- `.`: "Invalid volume specification: ",
- `..\`: "Invalid volume specification: ",
- `c:\:..\`: "Invalid volume specification: ",
- `c:\:d:\:xyzzy`: "Invalid volume specification: ",
- `c:`: "cannot be c:",
- `c:\`: `cannot be c:\`,
- `c:\notexist:d:`: `The system cannot find the file specified`,
- `c:\windows\system32\ntdll.dll:d:`: `Source 'c:\windows\system32\ntdll.dll' is not a directory`,
- `name<:d:`: `Invalid volume specification`,
- `name>:d:`: `Invalid volume specification`,
- `name::d:`: `Invalid volume specification`,
- `name":d:`: `Invalid volume specification`,
- `name\:d:`: `Invalid volume specification`,
- `name*:d:`: `Invalid volume specification`,
- `name|:d:`: `Invalid volume specification`,
- `name?:d:`: `Invalid volume specification`,
- `name/:d:`: `Invalid volume specification`,
- `d:\pathandmode:rw`: `Invalid volume specification`,
- `con:d:`: `cannot be a reserved word for Windows filenames`,
- `PRN:d:`: `cannot be a reserved word for Windows filenames`,
- `aUx:d:`: `cannot be a reserved word for Windows filenames`,
- `nul:d:`: `cannot be a reserved word for Windows filenames`,
- `com1:d:`: `cannot be a reserved word for Windows filenames`,
- `com2:d:`: `cannot be a reserved word for Windows filenames`,
- `com3:d:`: `cannot be a reserved word for Windows filenames`,
- `com4:d:`: `cannot be a reserved word for Windows filenames`,
- `com5:d:`: `cannot be a reserved word for Windows filenames`,
- `com6:d:`: `cannot be a reserved word for Windows filenames`,
- `com7:d:`: `cannot be a reserved word for Windows filenames`,
- `com8:d:`: `cannot be a reserved word for Windows filenames`,
- `com9:d:`: `cannot be a reserved word for Windows filenames`,
- `lpt1:d:`: `cannot be a reserved word for Windows filenames`,
- `lpt2:d:`: `cannot be a reserved word for Windows filenames`,
- `lpt3:d:`: `cannot be a reserved word for Windows filenames`,
- `lpt4:d:`: `cannot be a reserved word for Windows filenames`,
- `lpt5:d:`: `cannot be a reserved word for Windows filenames`,
- `lpt6:d:`: `cannot be a reserved word for Windows filenames`,
- `lpt7:d:`: `cannot be a reserved word for Windows filenames`,
- `lpt8:d:`: `cannot be a reserved word for Windows filenames`,
- `lpt9:d:`: `cannot be a reserved word for Windows filenames`,
- }
- } else {
- valid = []string{
- "/home",
- "/home:/home",
- "/home:/something/else",
- "/with space",
- "/home:/with space",
- "relative:/absolute-path",
- "hostPath:/containerPath:ro",
- "/hostPath:/containerPath:rw",
- "/rw:/ro",
- }
- invalid = map[string]string{
- "": "Invalid volume specification",
- "./": "Invalid volume destination",
- "../": "Invalid volume destination",
- "/:../": "Invalid volume destination",
- "/:path": "Invalid volume destination",
- ":": "Invalid volume specification",
- "/tmp:": "Invalid volume destination",
- ":test": "Invalid volume specification",
- ":/test": "Invalid volume specification",
- "tmp:": "Invalid volume destination",
- ":test:": "Invalid volume specification",
- "::": "Invalid volume specification",
- ":::": "Invalid volume specification",
- "/tmp:::": "Invalid volume specification",
- ":/tmp::": "Invalid volume specification",
- "/path:rw": "Invalid volume specification",
- "/path:ro": "Invalid volume specification",
- "/rw:rw": "Invalid volume specification",
- "path:ro": "Invalid volume specification",
- "/path:/path:sw": `invalid mode: sw`,
- "/path:/path:rwz": `invalid mode: rwz`,
- }
- }
- for _, path := range valid {
- if _, err := ParseMountSpec(path, "local"); err != nil {
- t.Fatalf("ParseMountSpec(`%q`) should succeed: error %q", path, err)
- }
- }
- for path, expectedError := range invalid {
- if _, err := ParseMountSpec(path, "local"); err == nil {
- t.Fatalf("ParseMountSpec(`%q`) should have failed validation. Err %v", path, err)
- } else {
- if !strings.Contains(err.Error(), expectedError) {
- t.Fatalf("ParseMountSpec(`%q`) error should contain %q, got %v", path, expectedError, err.Error())
- }
- }
- }
- }
- // testParseMountSpec is a structure used by TestParseMountSpecSplit for
- // specifying test cases for the ParseMountSpec() function.
- type testParseMountSpec struct {
- bind string
- driver string
- expDest string
- expSource string
- expName string
- expDriver string
- expRW bool
- fail bool
- }
- func TestParseMountSpecSplit(t *testing.T) {
- var cases []testParseMountSpec
- if runtime.GOOS == "windows" {
- cases = []testParseMountSpec{
- {`c:\:d:`, "local", `d:`, `c:\`, ``, "", true, false},
- {`c:\:d:\`, "local", `d:\`, `c:\`, ``, "", true, false},
- // TODO Windows post TP5 - Add readonly support {`c:\:d:\:ro`, "local", `d:\`, `c:\`, ``, "", false, false},
- {`c:\:d:\:rw`, "local", `d:\`, `c:\`, ``, "", true, false},
- {`c:\:d:\:foo`, "local", `d:\`, `c:\`, ``, "", false, true},
- {`name:d::rw`, "local", `d:`, ``, `name`, "local", true, false},
- {`name:d:`, "local", `d:`, ``, `name`, "local", true, false},
- // TODO Windows post TP5 - Add readonly support {`name:d::ro`, "local", `d:`, ``, `name`, "local", false, false},
- {`name:c:`, "", ``, ``, ``, "", true, true},
- {`driver/name:c:`, "", ``, ``, ``, "", true, true},
- }
- } else {
- cases = []testParseMountSpec{
- {"/tmp:/tmp1", "", "/tmp1", "/tmp", "", "", true, false},
- {"/tmp:/tmp2:ro", "", "/tmp2", "/tmp", "", "", false, false},
- {"/tmp:/tmp3:rw", "", "/tmp3", "/tmp", "", "", true, false},
- {"/tmp:/tmp4:foo", "", "", "", "", "", false, true},
- {"name:/named1", "", "/named1", "", "name", "", true, false},
- {"name:/named2", "external", "/named2", "", "name", "external", true, false},
- {"name:/named3:ro", "local", "/named3", "", "name", "local", false, false},
- {"local/name:/tmp:rw", "", "/tmp", "", "local/name", "", true, false},
- {"/tmp:tmp", "", "", "", "", "", true, true},
- }
- }
- for _, c := range cases {
- m, err := ParseMountSpec(c.bind, c.driver)
- if c.fail {
- if err == nil {
- t.Fatalf("Expected error, was nil, for spec %s\n", c.bind)
- }
- continue
- }
- if m == nil || err != nil {
- t.Fatalf("ParseMountSpec failed for spec %s driver %s error %v\n", c.bind, c.driver, err.Error())
- continue
- }
- if m.Destination != c.expDest {
- t.Fatalf("Expected destination %s, was %s, for spec %s\n", c.expDest, m.Destination, c.bind)
- }
- if m.Source != c.expSource {
- t.Fatalf("Expected source %s, was %s, for spec %s\n", c.expSource, m.Source, c.bind)
- }
- if m.Name != c.expName {
- t.Fatalf("Expected name %s, was %s for spec %s\n", c.expName, m.Name, c.bind)
- }
- if m.Driver != c.expDriver {
- t.Fatalf("Expected driver %s, was %s, for spec %s\n", c.expDriver, m.Driver, c.bind)
- }
- if m.RW != c.expRW {
- t.Fatalf("Expected RW %v, was %v for spec %s\n", c.expRW, m.RW, c.bind)
- }
- }
- }
|