Skip to content

Commit

Permalink
memfs: Increase memfs test coverage
Browse files Browse the repository at this point in the history
Signed-off-by: Paulo Gomes <[email protected]>
  • Loading branch information
pjbgf committed Apr 9, 2024
1 parent f6e8a12 commit 656439a
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 1 deletion.
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ go 1.20
require (
github.com/cyphar/filepath-securejoin v0.2.4
github.com/onsi/gomega v1.27.10
github.com/stretchr/testify v1.9.0
golang.org/x/sys v0.13.0
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.11.0 // indirect
golang.org/x/net v0.17.0 // indirect
golang.org/x/text v0.13.0 // indirect
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg=
github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
Expand All @@ -17,9 +19,13 @@ github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU
github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI=
github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
Expand Down
2 changes: 1 addition & 1 deletion memfs/memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ type Memory struct {
}

// New returns a new Memory filesystem.
func New() billy.Filesystem {
func New(opts ...Option) billy.Filesystem {
fs := &Memory{s: newStorage()}
fs.s.New("/", 0755|os.ModeDir, 0)
return chroot.New(fs, string(separator))
Expand Down
170 changes: 170 additions & 0 deletions memfs/memory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import (
"fmt"
"io"
"os"
"path/filepath"
"runtime"
"testing"

"github.com/go-git/go-billy/v5"
"github.com/go-git/go-billy/v5/test"
"github.com/go-git/go-billy/v5/util"
"github.com/stretchr/testify/assert"

. "gopkg.in/check.v1"
)
Expand Down Expand Up @@ -122,6 +124,174 @@ func (s *MemorySuite) TestTruncateAppend(c *C) {
c.Assert(string(data), Equals, "replace")
}

func TestReadlink(t *testing.T) {
tests := []struct {
name string
link string
want string
wantErr *error
}{
{
name: "symlink not found",
link: "/404",
wantErr: &os.ErrNotExist,
},
{
name: "self-targeting symlink",
link: "/self",
want: "/self",
},
{
name: "symlink",
link: "/bar",
want: "/foo",
},
{
name: "symlink to windows path",
link: "/win",
want: "c:\\test\\123",
},
{
name: "symlink to network path",
link: "/net",
want: "\\test\\123",
},
}

fs := New()

// arrange fs for tests.
assert.NoError(t, fs.Symlink("/self", "/self"))
assert.NoError(t, fs.Symlink("/foo", "/bar"))
assert.NoError(t, fs.Symlink("c:\\test\\123", "/win"))
assert.NoError(t, fs.Symlink("\\test\\123", "/net"))

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
got, err := fs.Readlink(tc.link)

if tc.wantErr == nil {
assert.NoError(t, err)
assert.Equal(t, tc.want, got)
} else {
assert.ErrorIs(t, err, *tc.wantErr)
}
})
}
}

func TestSymlink(t *testing.T) {
tests := []struct {
name string
target string
link string
want string
wantErr string
}{
{
name: "new symlink unexistent target",
target: "/bar",
link: "/foo",
want: "/bar",
},
{
name: "self-targeting symlink",
target: "/self",
link: "/self",
want: "/self",
},
{
name: "new symlink to file",
target: "/file",
link: "/file-link",
want: "/file",
},
{
name: "new symlink to dir",
target: "/dir",
link: "/dir-link",
want: "/dir",
},
{
name: "new symlink to win",
target: "c:\\foor\\bar",
link: "/win",
want: "c:\\foor\\bar",
},
{
name: "new symlink to net",
target: "\\net\\bar",
link: "/net",
want: "\\net\\bar",
},
{
name: "new symlink to net",
target: "\\net\\bar",
link: "/net",
want: "\\net\\bar",
},
}

fs := New()

// arrange fs for tests.
err := fs.MkdirAll("/dir", 0o600)
assert.NoError(t, err)
_, err = fs.Create("/file")
assert.NoError(t, err)

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
err := fs.Symlink(tc.target, tc.link)

if tc.wantErr == "" {
got, err := fs.Readlink(tc.link)
assert.NoError(t, err)
assert.Equal(t, tc.want, got)
} else {
assert.ErrorContains(t, err, tc.wantErr)
}
})
}
}

func TestJoin(t *testing.T) {
tests := []struct {
name string
legacy bool
elem []string
want string
}{
{name: "empty", elem: []string{""}, want: ""},
{name: "c:", elem: []string{"C:"}, want: "C:"},
{name: "simple rel", elem: []string{"a", "b", "c"}, want: "a/b/c"},
{name: "simple rel backslash", elem: []string{"\\", "a", "b", "c"}, want: "\\/a/b/c"},
{name: "simple abs slash", elem: []string{"/", "a", "b", "c"}, want: "/a/b/c"},
{name: "c: rel", elem: []string{"C:\\", "a", "b", "c"}, want: "C:\\/a/b/c"},
{name: "c: abs", elem: []string{"/C:\\", "a", "b", "c"}, want: "/C:\\/a/b/c"},
{name: "\\ rel", elem: []string{"\\\\", "a", "b", "c"}, want: "\\\\/a/b/c"},
{name: "\\ abs", elem: []string{"/\\\\", "a", "b", "c"}, want: "/\\\\/a/b/c"},

{name: "[legacy] empty", legacy: true, elem: []string{""}, want: filepath.Join("")},
{name: "[legacy] c:", legacy: true, elem: []string{"C:"}, want: filepath.Join("C:")},
{name: "[legacy] simple rel", legacy: true, elem: []string{"a", "b", "c"}, want: filepath.Join("a", "b", "c")},
{name: "[legacy] simple abs slash", legacy: true, elem: []string{string(filepath.Separator), "a", "b", "c"}, want: filepath.Join(string(filepath.Separator), "a", "b", "c")},
{name: "[legacy] simple rel/abs backslash", legacy: true, elem: []string{"\\", "a", "b", "c"}, want: filepath.Join("\\", "a", "b", "c")},
{name: "[legacy] c: rellegacy: true, ", elem: []string{"C:\\", "a", "b", "c"}, want: filepath.Join("C:\\", "a", "b", "c")},
{name: "[legacy] c: abslegacy: true, ", elem: []string{string(filepath.Separator), "C:\\", "a", "b", "c"}, want: filepath.Join(string(filepath.Separator), "C:\\", "a", "b", "c")},
{name: "[legacy] \\ rel", legacy: true, elem: []string{"\\\\", "a", "b", "c"}, want: filepath.Join("\\\\", "a", "b", "c")},
{name: "[legacy] \\ abs", legacy: true, elem: []string{string(filepath.Separator), "\\\\", "a", "b", "c"}, want: filepath.Join(string(filepath.Separator), "\\\\", "a", "b", "c")},
}

for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
opts := []Option{}
got := New(opts...).Join(tc.elem...)
assert.Equal(t, tc.want, got)
})
}
}

func (s *MemorySuite) TestSymlink(c *C) {
err := s.FS.Symlink("test", "test")
c.Assert(err, IsNil)
Expand Down
10 changes: 10 additions & 0 deletions memfs/options.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package memfs

type options struct {
}

func newOptions() *options {
return &options{}
}

type Option func(*options)

0 comments on commit 656439a

Please sign in to comment.