github.com/sijibomii/docker@v0.0.0-20231230191044-5cf6ca554647/volume/local/local_test.go (about) 1 package local 2 3 import ( 4 "io/ioutil" 5 "os" 6 "runtime" 7 "strings" 8 "testing" 9 10 "github.com/docker/docker/pkg/mount" 11 ) 12 13 func TestRemove(t *testing.T) { 14 // TODO Windows: Investigate why this test fails on Windows under CI 15 // but passes locally. 16 if runtime.GOOS == "windows" { 17 t.Skip("Test failing on Windows CI") 18 } 19 rootDir, err := ioutil.TempDir("", "local-volume-test") 20 if err != nil { 21 t.Fatal(err) 22 } 23 defer os.RemoveAll(rootDir) 24 25 r, err := New(rootDir, 0, 0) 26 if err != nil { 27 t.Fatal(err) 28 } 29 30 vol, err := r.Create("testing", nil) 31 if err != nil { 32 t.Fatal(err) 33 } 34 35 if err := r.Remove(vol); err != nil { 36 t.Fatal(err) 37 } 38 39 vol, err = r.Create("testing2", nil) 40 if err != nil { 41 t.Fatal(err) 42 } 43 if err := os.RemoveAll(vol.Path()); err != nil { 44 t.Fatal(err) 45 } 46 47 if err := r.Remove(vol); err != nil { 48 t.Fatal(err) 49 } 50 51 if _, err := os.Stat(vol.Path()); err != nil && !os.IsNotExist(err) { 52 t.Fatal("volume dir not removed") 53 } 54 55 if l, _ := r.List(); len(l) != 0 { 56 t.Fatal("expected there to be no volumes") 57 } 58 } 59 60 func TestInitializeWithVolumes(t *testing.T) { 61 rootDir, err := ioutil.TempDir("", "local-volume-test") 62 if err != nil { 63 t.Fatal(err) 64 } 65 defer os.RemoveAll(rootDir) 66 67 r, err := New(rootDir, 0, 0) 68 if err != nil { 69 t.Fatal(err) 70 } 71 72 vol, err := r.Create("testing", nil) 73 if err != nil { 74 t.Fatal(err) 75 } 76 77 r, err = New(rootDir, 0, 0) 78 if err != nil { 79 t.Fatal(err) 80 } 81 82 v, err := r.Get(vol.Name()) 83 if err != nil { 84 t.Fatal(err) 85 } 86 87 if v.Path() != vol.Path() { 88 t.Fatal("expected to re-initialize root with existing volumes") 89 } 90 } 91 92 func TestCreate(t *testing.T) { 93 rootDir, err := ioutil.TempDir("", "local-volume-test") 94 if err != nil { 95 t.Fatal(err) 96 } 97 defer os.RemoveAll(rootDir) 98 99 r, err := New(rootDir, 0, 0) 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 cases := map[string]bool{ 105 "name": true, 106 "name-with-dash": true, 107 "name_with_underscore": true, 108 "name/with/slash": false, 109 "name/with/../../slash": false, 110 "./name": false, 111 "../name": false, 112 "./": false, 113 "../": false, 114 "~": false, 115 ".": false, 116 "..": false, 117 "...": false, 118 } 119 120 for name, success := range cases { 121 v, err := r.Create(name, nil) 122 if success { 123 if err != nil { 124 t.Fatal(err) 125 } 126 if v.Name() != name { 127 t.Fatalf("Expected volume with name %s, got %s", name, v.Name()) 128 } 129 } else { 130 if err == nil { 131 t.Fatalf("Expected error creating volume with name %s, got nil", name) 132 } 133 } 134 } 135 } 136 137 func TestValidateName(t *testing.T) { 138 r := &Root{} 139 names := map[string]bool{ 140 "/testvol": false, 141 "thing.d": true, 142 "hello-world": true, 143 "./hello": false, 144 ".hello": false, 145 } 146 147 for vol, expected := range names { 148 err := r.validateName(vol) 149 if expected && err != nil { 150 t.Fatalf("expected %s to be valid got %v", vol, err) 151 } 152 if !expected && err == nil { 153 t.Fatalf("expected %s to be invalid", vol) 154 } 155 } 156 } 157 158 func TestCreateWithOpts(t *testing.T) { 159 if runtime.GOOS == "windows" { 160 t.Skip() 161 } 162 163 rootDir, err := ioutil.TempDir("", "local-volume-test") 164 if err != nil { 165 t.Fatal(err) 166 } 167 defer os.RemoveAll(rootDir) 168 169 r, err := New(rootDir, 0, 0) 170 if err != nil { 171 t.Fatal(err) 172 } 173 174 if _, err := r.Create("test", map[string]string{"invalidopt": "notsupported"}); err == nil { 175 t.Fatal("expected invalid opt to cause error") 176 } 177 178 vol, err := r.Create("test", map[string]string{"device": "tmpfs", "type": "tmpfs", "o": "size=1m,uid=1000"}) 179 if err != nil { 180 t.Fatal(err) 181 } 182 v := vol.(*localVolume) 183 184 dir, err := v.Mount() 185 if err != nil { 186 t.Fatal(err) 187 } 188 defer func() { 189 if err := v.Unmount(); err != nil { 190 t.Fatal(err) 191 } 192 }() 193 194 mountInfos, err := mount.GetMounts() 195 if err != nil { 196 t.Fatal(err) 197 } 198 199 var found bool 200 for _, info := range mountInfos { 201 if info.Mountpoint == dir { 202 found = true 203 if info.Fstype != "tmpfs" { 204 t.Fatalf("expected tmpfs mount, got %q", info.Fstype) 205 } 206 if info.Source != "tmpfs" { 207 t.Fatalf("expected tmpfs mount, got %q", info.Source) 208 } 209 if !strings.Contains(info.VfsOpts, "uid=1000") { 210 t.Fatalf("expected mount info to have uid=1000: %q", info.VfsOpts) 211 } 212 if !strings.Contains(info.VfsOpts, "size=1024k") { 213 t.Fatalf("expected mount info to have size=1024k: %q", info.VfsOpts) 214 } 215 break 216 } 217 } 218 219 if !found { 220 t.Fatal("mount not found") 221 } 222 223 if v.active.count != 1 { 224 t.Fatalf("Expected active mount count to be 1, got %d", v.active.count) 225 } 226 227 // test double mount 228 if _, err := v.Mount(); err != nil { 229 t.Fatal(err) 230 } 231 if v.active.count != 2 { 232 t.Fatalf("Expected active mount count to be 2, got %d", v.active.count) 233 } 234 235 if err := v.Unmount(); err != nil { 236 t.Fatal(err) 237 } 238 if v.active.count != 1 { 239 t.Fatalf("Expected active mount count to be 1, got %d", v.active.count) 240 } 241 242 mounted, err := mount.Mounted(v.path) 243 if err != nil { 244 t.Fatal(err) 245 } 246 if !mounted { 247 t.Fatal("expected mount to still be active") 248 } 249 }