merge v0.23.0-rc changes
This commit is contained in:
+182
-111
@@ -2,6 +2,7 @@ package filesystem_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"image"
|
||||
"image/png"
|
||||
"mime/multipart"
|
||||
@@ -19,11 +20,11 @@ func TestFileSystemExists(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
scenarios := []struct {
|
||||
file string
|
||||
@@ -35,12 +36,18 @@ func TestFileSystemExists(t *testing.T) {
|
||||
{"image.png", true},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
exists, _ := fs.Exists(scenario.file)
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.file, func(t *testing.T) {
|
||||
exists, err := fsys.Exists(s.file)
|
||||
|
||||
if exists != scenario.exists {
|
||||
t.Errorf("(%d) Expected %v, got %v", i, scenario.exists, exists)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if exists != s.exists {
|
||||
t.Fatalf("Expected exists %v, got %v", s.exists, exists)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,11 +55,11 @@ func TestFileSystemAttributes(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
scenarios := []struct {
|
||||
file string
|
||||
@@ -65,20 +72,24 @@ func TestFileSystemAttributes(t *testing.T) {
|
||||
{"image.png", false, "image/png"},
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
attr, err := fs.Attributes(scenario.file)
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.file, func(t *testing.T) {
|
||||
attr, err := fsys.Attributes(s.file)
|
||||
|
||||
if err == nil && scenario.expectError {
|
||||
t.Errorf("(%d) Expected error, got nil", i)
|
||||
}
|
||||
hasErr := err != nil
|
||||
|
||||
if err != nil && !scenario.expectError {
|
||||
t.Errorf("(%d) Expected nil, got error, %v", i, err)
|
||||
}
|
||||
if hasErr != s.expectError {
|
||||
t.Fatalf("Expected hasErr %v, got %v", s.expectError, hasErr)
|
||||
}
|
||||
|
||||
if err == nil && attr.ContentType != scenario.expectContentType {
|
||||
t.Errorf("(%d) Expected attr.ContentType to be %q, got %q", i, scenario.expectContentType, attr.ContentType)
|
||||
}
|
||||
if hasErr && !errors.Is(err, filesystem.ErrNotFound) {
|
||||
t.Fatalf("Expected ErrNotFound err, got %q", err)
|
||||
}
|
||||
|
||||
if !hasErr && attr.ContentType != s.expectContentType {
|
||||
t.Fatalf("Expected attr.ContentType to be %q, got %q", s.expectContentType, attr.ContentType)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,17 +97,17 @@ func TestFileSystemDelete(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
if err := fs.Delete("missing.txt"); err == nil {
|
||||
t.Fatal("Expected error, got nil")
|
||||
if err := fsys.Delete("missing.txt"); err == nil || !errors.Is(err, filesystem.ErrNotFound) {
|
||||
t.Fatalf("Expected ErrNotFound error, got %v", err)
|
||||
}
|
||||
|
||||
if err := fs.Delete("image.png"); err != nil {
|
||||
if err := fsys.Delete("image.png"); err != nil {
|
||||
t.Fatalf("Expected nil, got error %v", err)
|
||||
}
|
||||
}
|
||||
@@ -105,29 +116,29 @@ func TestFileSystemDeletePrefixWithoutTrailingSlash(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
if errs := fs.DeletePrefix(""); len(errs) == 0 {
|
||||
if errs := fsys.DeletePrefix(""); len(errs) == 0 {
|
||||
t.Fatal("Expected error, got nil", errs)
|
||||
}
|
||||
|
||||
if errs := fs.DeletePrefix("missing"); len(errs) != 0 {
|
||||
if errs := fsys.DeletePrefix("missing"); len(errs) != 0 {
|
||||
t.Fatalf("Not existing prefix shouldn't error, got %v", errs)
|
||||
}
|
||||
|
||||
if errs := fs.DeletePrefix("test"); len(errs) != 0 {
|
||||
if errs := fsys.DeletePrefix("test"); len(errs) != 0 {
|
||||
t.Fatalf("Expected nil, got errors %v", errs)
|
||||
}
|
||||
|
||||
// ensure that the test/* files are deleted
|
||||
if exists, _ := fs.Exists("test/sub1.txt"); exists {
|
||||
if exists, _ := fsys.Exists("test/sub1.txt"); exists {
|
||||
t.Fatalf("Expected test/sub1.txt to be deleted")
|
||||
}
|
||||
if exists, _ := fs.Exists("test/sub2.txt"); exists {
|
||||
if exists, _ := fsys.Exists("test/sub2.txt"); exists {
|
||||
t.Fatalf("Expected test/sub2.txt to be deleted")
|
||||
}
|
||||
|
||||
@@ -141,25 +152,25 @@ func TestFileSystemDeletePrefixWithTrailingSlash(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
if errs := fs.DeletePrefix("missing/"); len(errs) != 0 {
|
||||
if errs := fsys.DeletePrefix("missing/"); len(errs) != 0 {
|
||||
t.Fatalf("Not existing prefix shouldn't error, got %v", errs)
|
||||
}
|
||||
|
||||
if errs := fs.DeletePrefix("test/"); len(errs) != 0 {
|
||||
if errs := fsys.DeletePrefix("test/"); len(errs) != 0 {
|
||||
t.Fatalf("Expected nil, got errors %v", errs)
|
||||
}
|
||||
|
||||
// ensure that the test/* files are deleted
|
||||
if exists, _ := fs.Exists("test/sub1.txt"); exists {
|
||||
if exists, _ := fsys.Exists("test/sub1.txt"); exists {
|
||||
t.Fatalf("Expected test/sub1.txt to be deleted")
|
||||
}
|
||||
if exists, _ := fs.Exists("test/sub2.txt"); exists {
|
||||
if exists, _ := fsys.Exists("test/sub2.txt"); exists {
|
||||
t.Fatalf("Expected test/sub2.txt to be deleted")
|
||||
}
|
||||
|
||||
@@ -169,6 +180,41 @@ func TestFileSystemDeletePrefixWithTrailingSlash(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileSystemIsEmptyDir(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fsys.Close()
|
||||
|
||||
scenarios := []struct {
|
||||
dir string
|
||||
expected bool
|
||||
}{
|
||||
{"", false}, // special case that shouldn't be suffixed with delimiter to search for any files within the bucket
|
||||
{"/", true},
|
||||
{"missing", true},
|
||||
{"missing/", true},
|
||||
{"test", false},
|
||||
{"test/", false},
|
||||
{"empty", true},
|
||||
{"empty/", true},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.dir, func(t *testing.T) {
|
||||
result := fsys.IsEmptyDir(s.dir)
|
||||
|
||||
if result != s.expected {
|
||||
t.Fatalf("Expected %v, got %v", s.expected, result)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFileSystemUploadMultipart(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
@@ -193,24 +239,24 @@ func TestFileSystemUploadMultipart(t *testing.T) {
|
||||
defer file.Close()
|
||||
// ---
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
fileKey := "newdir/newkey.txt"
|
||||
|
||||
uploadErr := fs.UploadMultipart(fh, fileKey)
|
||||
uploadErr := fsys.UploadMultipart(fh, fileKey)
|
||||
if uploadErr != nil {
|
||||
t.Fatal(uploadErr)
|
||||
}
|
||||
|
||||
if exists, _ := fs.Exists(fileKey); !exists {
|
||||
if exists, _ := fsys.Exists(fileKey); !exists {
|
||||
t.Fatalf("Expected %q to exist", fileKey)
|
||||
}
|
||||
|
||||
attrs, err := fs.Attributes(fileKey)
|
||||
attrs, err := fsys.Attributes(fileKey)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to fetch file attributes: %v", err)
|
||||
}
|
||||
@@ -223,11 +269,11 @@ func TestFileSystemUploadFile(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
fileKey := "newdir/newkey.txt"
|
||||
|
||||
@@ -238,16 +284,16 @@ func TestFileSystemUploadFile(t *testing.T) {
|
||||
|
||||
file.OriginalName = "test.txt"
|
||||
|
||||
uploadErr := fs.UploadFile(file, fileKey)
|
||||
uploadErr := fsys.UploadFile(file, fileKey)
|
||||
if uploadErr != nil {
|
||||
t.Fatal(uploadErr)
|
||||
}
|
||||
|
||||
if exists, _ := fs.Exists(fileKey); !exists {
|
||||
if exists, _ := fsys.Exists(fileKey); !exists {
|
||||
t.Fatalf("Expected %q to exist", fileKey)
|
||||
}
|
||||
|
||||
attrs, err := fs.Attributes(fileKey)
|
||||
attrs, err := fsys.Attributes(fileKey)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to fetch file attributes: %v", err)
|
||||
}
|
||||
@@ -260,20 +306,20 @@ func TestFileSystemUpload(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
fileKey := "newdir/newkey.txt"
|
||||
|
||||
uploadErr := fs.Upload([]byte("demo"), fileKey)
|
||||
uploadErr := fsys.Upload([]byte("demo"), fileKey)
|
||||
if uploadErr != nil {
|
||||
t.Fatal(uploadErr)
|
||||
}
|
||||
|
||||
if exists, _ := fs.Exists(fileKey); !exists {
|
||||
if exists, _ := fsys.Exists(fileKey); !exists {
|
||||
t.Fatalf("Expected %s to exist", fileKey)
|
||||
}
|
||||
}
|
||||
@@ -282,11 +328,11 @@ func TestFileSystemServe(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
csp := "default-src 'none'; media-src 'self'; style-src 'unsafe-inline'; sandbox"
|
||||
cacheControl := "max-age=2592000, stale-while-revalidate=86400"
|
||||
@@ -409,39 +455,41 @@ func TestFileSystemServe(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
res := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
t.Run(s.path, func(t *testing.T) {
|
||||
res := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
|
||||
query := req.URL.Query()
|
||||
for k, v := range s.query {
|
||||
query.Set(k, v)
|
||||
}
|
||||
req.URL.RawQuery = query.Encode()
|
||||
|
||||
for k, v := range s.headers {
|
||||
res.Header().Set(k, v)
|
||||
}
|
||||
|
||||
err := fs.Serve(res, req, s.path, s.name)
|
||||
hasErr := err != nil
|
||||
|
||||
if hasErr != s.expectError {
|
||||
t.Errorf("(%s) Expected hasError %v, got %v (%v)", s.path, s.expectError, hasErr, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if s.expectError {
|
||||
continue
|
||||
}
|
||||
|
||||
result := res.Result()
|
||||
|
||||
for hName, hValue := range s.expectHeaders {
|
||||
v := result.Header.Get(hName)
|
||||
if v != hValue {
|
||||
t.Errorf("(%s) Expected value %q for header %q, got %q", s.path, hValue, hName, v)
|
||||
query := req.URL.Query()
|
||||
for k, v := range s.query {
|
||||
query.Set(k, v)
|
||||
}
|
||||
}
|
||||
req.URL.RawQuery = query.Encode()
|
||||
|
||||
for k, v := range s.headers {
|
||||
res.Header().Set(k, v)
|
||||
}
|
||||
|
||||
err := fsys.Serve(res, req, s.path, s.name)
|
||||
hasErr := err != nil
|
||||
|
||||
if hasErr != s.expectError {
|
||||
t.Fatalf("Expected hasError %v, got %v (%v)", s.expectError, hasErr, err)
|
||||
}
|
||||
|
||||
if s.expectError {
|
||||
return
|
||||
}
|
||||
|
||||
result := res.Result()
|
||||
defer result.Body.Close()
|
||||
|
||||
for hName, hValue := range s.expectHeaders {
|
||||
v := result.Header.Get(hName)
|
||||
if v != hValue {
|
||||
t.Errorf("Expected value %q for header %q, got %q", hValue, hName, v)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -449,20 +497,38 @@ func TestFileSystemGetFile(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
f, err := fs.GetFile("image.png")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
scenarios := []struct {
|
||||
file string
|
||||
expectError bool
|
||||
}{
|
||||
{"missing.png", true},
|
||||
{"image.png", false},
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if f == nil {
|
||||
t.Fatal("File is supposed to be found")
|
||||
for _, s := range scenarios {
|
||||
t.Run(s.file, func(t *testing.T) {
|
||||
f, err := fsys.GetFile(s.file)
|
||||
|
||||
hasErr := err != nil
|
||||
|
||||
if !hasErr {
|
||||
defer f.Close()
|
||||
}
|
||||
|
||||
if hasErr != s.expectError {
|
||||
t.Fatalf("Expected hasErr %v, got %v", s.expectError, hasErr)
|
||||
}
|
||||
|
||||
if hasErr && !errors.Is(err, filesystem.ErrNotFound) {
|
||||
t.Fatalf("Expected ErrNotFound error, got %v", err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -470,25 +536,26 @@ func TestFileSystemCopy(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
src := "image.png"
|
||||
dst := "image.png_copy"
|
||||
|
||||
// copy missing file
|
||||
if err := fs.Copy(dst, src); err == nil {
|
||||
if err := fsys.Copy(dst, src); err == nil {
|
||||
t.Fatalf("Expected to fail copying %q to %q, got nil", dst, src)
|
||||
}
|
||||
|
||||
// copy existing file
|
||||
if err := fs.Copy(src, dst); err != nil {
|
||||
if err := fsys.Copy(src, dst); err != nil {
|
||||
t.Fatalf("Failed to copy %q to %q: %v", src, dst, err)
|
||||
}
|
||||
f, err := fs.GetFile(dst)
|
||||
f, err := fsys.GetFile(dst)
|
||||
//nolint
|
||||
defer f.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("Missing copied file %q: %v", dst, err)
|
||||
@@ -502,11 +569,11 @@ func TestFileSystemList(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
scenarios := []struct {
|
||||
prefix string
|
||||
@@ -537,7 +604,7 @@ func TestFileSystemList(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
objs, err := fs.List(s.prefix)
|
||||
objs, err := fsys.List(s.prefix)
|
||||
if err != nil {
|
||||
t.Fatalf("[%s] %v", s.prefix, err)
|
||||
}
|
||||
@@ -563,17 +630,17 @@ func TestFileSystemServeSingleRange(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
res := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Add("Range", "bytes=0-20")
|
||||
|
||||
if err := fs.Serve(res, req, "image.png", "image.png"); err != nil {
|
||||
if err := fsys.Serve(res, req, "image.png", "image.png"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -597,17 +664,17 @@ func TestFileSystemServeMultiRange(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
res := httptest.NewRecorder()
|
||||
req := httptest.NewRequest("GET", "/", nil)
|
||||
req.Header.Add("Range", "bytes=0-20, 25-30")
|
||||
|
||||
if err := fs.Serve(res, req, "image.png", "image.png"); err != nil {
|
||||
if err := fsys.Serve(res, req, "image.png", "image.png"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -626,11 +693,11 @@ func TestFileSystemCreateThumb(t *testing.T) {
|
||||
dir := createTestDir(t)
|
||||
defer os.RemoveAll(dir)
|
||||
|
||||
fs, err := filesystem.NewLocal(dir)
|
||||
fsys, err := filesystem.NewLocal(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer fs.Close()
|
||||
defer fsys.Close()
|
||||
|
||||
scenarios := []struct {
|
||||
file string
|
||||
@@ -651,7 +718,7 @@ func TestFileSystemCreateThumb(t *testing.T) {
|
||||
}
|
||||
|
||||
for i, scenario := range scenarios {
|
||||
err := fs.CreateThumb(scenario.file, scenario.thumb, "100x100")
|
||||
err := fsys.CreateThumb(scenario.file, scenario.thumb, "100x100")
|
||||
|
||||
hasErr := err != nil
|
||||
if hasErr != scenario.expectError {
|
||||
@@ -663,7 +730,7 @@ func TestFileSystemCreateThumb(t *testing.T) {
|
||||
continue
|
||||
}
|
||||
|
||||
if exists, _ := fs.Exists(scenario.thumb); !exists {
|
||||
if exists, _ := fsys.Exists(scenario.thumb); !exists {
|
||||
t.Errorf("(%d) Couldn't find %q thumb", i, scenario.thumb)
|
||||
}
|
||||
}
|
||||
@@ -677,6 +744,10 @@ func createTestDir(t *testing.T) string {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Join(dir, "empty"), os.ModePerm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if err := os.MkdirAll(filepath.Join(dir, "test"), os.ModePerm); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user