Loading android/fixture.go +29 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android import ( "fmt" "strings" "testing" ) Loading Loading @@ -241,6 +242,7 @@ type MockFS map[string][]byte // Fails if the supplied map files with the same paths are present in both of them. func (fs MockFS) Merge(extra map[string][]byte) { for p, c := range extra { validateFixtureMockFSPath(p) if _, ok := fs[p]; ok { panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists", p)) } Loading @@ -248,6 +250,27 @@ func (fs MockFS) Merge(extra map[string][]byte) { } } // Ensure that tests cannot add paths into the mock file system which would not be allowed in the // runtime, e.g. absolute paths, paths relative to the 'out/' directory. func validateFixtureMockFSPath(path string) { // This uses validateSafePath rather than validatePath because the latter prevents adding files // that include a $ but there are tests that allow files with a $ to be used, albeit only by // globbing. validatedPath, err := validateSafePath(path) if err != nil { panic(err) } // Make sure that the path is canonical. if validatedPath != path { panic(fmt.Errorf("path %q is not a canonical path, use %q instead", path, validatedPath)) } if path == "out" || strings.HasPrefix(path, "out/") { panic(fmt.Errorf("cannot add output path %q to the mock file system", path)) } } func (fs MockFS) AddToFixture() FixturePreparer { return FixtureMergeMockFs(fs) } Loading Loading @@ -290,6 +313,11 @@ func FixtureRegisterWithContext(registeringFunc func(ctx RegistrationContext)) F func FixtureModifyMockFS(mutator func(fs MockFS)) FixturePreparer { return newSimpleFixturePreparer(func(f *fixture) { mutator(f.mockFS) // Make sure that invalid paths were not added to the mock filesystem. for p, _ := range f.mockFS { validateFixtureMockFSPath(p) } }) } Loading @@ -307,6 +335,7 @@ func FixtureMergeMockFs(mockFS MockFS) FixturePreparer { // Fail if the filesystem already contains a file with that path, use FixtureOverrideFile instead. func FixtureAddFile(path string, contents []byte) FixturePreparer { return FixtureModifyMockFS(func(fs MockFS) { validateFixtureMockFSPath(path) if _, ok := fs[path]; ok { panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists, use FixtureOverride*File instead", path)) } Loading android/fixture_test.go +38 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,9 @@ package android import "testing" import ( "testing" ) // Make sure that FixturePreparer instances are only called once per fixture and in the order in // which they were added. Loading Loading @@ -47,3 +49,38 @@ func TestFixtureDedup(t *testing.T) { AssertDeepEquals(t, "preparers called in wrong order", []string{"preparer1", "preparer2", "preparer4", "preparer3"}, list) } func TestFixtureValidateMockFS(t *testing.T) { buildDir := "<unused>" factory := NewFixtureFactory(&buildDir) t.Run("absolute path", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", "Path is outside directory: /abs/path/Android.bp", func() { factory.Fixture(t, FixtureAddFile("/abs/path/Android.bp", nil)) }) }) t.Run("not canonical", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", `path "path/with/../in/it/Android.bp" is not a canonical path, use "path/in/it/Android.bp" instead`, func() { factory.Fixture(t, FixtureAddFile("path/with/../in/it/Android.bp", nil)) }) }) t.Run("FixtureAddFile", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() { factory.Fixture(t, FixtureAddFile("out/Android.bp", nil)) }) }) t.Run("FixtureMergeMockFs", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() { factory.Fixture(t, FixtureMergeMockFs(MockFS{ "out/Android.bp": nil, })) }) }) t.Run("FixtureModifyMockFS", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() { factory.Fixture(t, FixtureModifyMockFS(func(fs MockFS) { fs["out/Android.bp"] = nil })) }) }) } Loading
android/fixture.go +29 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android import ( "fmt" "strings" "testing" ) Loading Loading @@ -241,6 +242,7 @@ type MockFS map[string][]byte // Fails if the supplied map files with the same paths are present in both of them. func (fs MockFS) Merge(extra map[string][]byte) { for p, c := range extra { validateFixtureMockFSPath(p) if _, ok := fs[p]; ok { panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists", p)) } Loading @@ -248,6 +250,27 @@ func (fs MockFS) Merge(extra map[string][]byte) { } } // Ensure that tests cannot add paths into the mock file system which would not be allowed in the // runtime, e.g. absolute paths, paths relative to the 'out/' directory. func validateFixtureMockFSPath(path string) { // This uses validateSafePath rather than validatePath because the latter prevents adding files // that include a $ but there are tests that allow files with a $ to be used, albeit only by // globbing. validatedPath, err := validateSafePath(path) if err != nil { panic(err) } // Make sure that the path is canonical. if validatedPath != path { panic(fmt.Errorf("path %q is not a canonical path, use %q instead", path, validatedPath)) } if path == "out" || strings.HasPrefix(path, "out/") { panic(fmt.Errorf("cannot add output path %q to the mock file system", path)) } } func (fs MockFS) AddToFixture() FixturePreparer { return FixtureMergeMockFs(fs) } Loading Loading @@ -290,6 +313,11 @@ func FixtureRegisterWithContext(registeringFunc func(ctx RegistrationContext)) F func FixtureModifyMockFS(mutator func(fs MockFS)) FixturePreparer { return newSimpleFixturePreparer(func(f *fixture) { mutator(f.mockFS) // Make sure that invalid paths were not added to the mock filesystem. for p, _ := range f.mockFS { validateFixtureMockFSPath(p) } }) } Loading @@ -307,6 +335,7 @@ func FixtureMergeMockFs(mockFS MockFS) FixturePreparer { // Fail if the filesystem already contains a file with that path, use FixtureOverrideFile instead. func FixtureAddFile(path string, contents []byte) FixturePreparer { return FixtureModifyMockFS(func(fs MockFS) { validateFixtureMockFSPath(path) if _, ok := fs[path]; ok { panic(fmt.Errorf("attempted to add file %s to the mock filesystem but it already exists, use FixtureOverride*File instead", path)) } Loading
android/fixture_test.go +38 −1 Original line number Diff line number Diff line Loading @@ -14,7 +14,9 @@ package android import "testing" import ( "testing" ) // Make sure that FixturePreparer instances are only called once per fixture and in the order in // which they were added. Loading Loading @@ -47,3 +49,38 @@ func TestFixtureDedup(t *testing.T) { AssertDeepEquals(t, "preparers called in wrong order", []string{"preparer1", "preparer2", "preparer4", "preparer3"}, list) } func TestFixtureValidateMockFS(t *testing.T) { buildDir := "<unused>" factory := NewFixtureFactory(&buildDir) t.Run("absolute path", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", "Path is outside directory: /abs/path/Android.bp", func() { factory.Fixture(t, FixtureAddFile("/abs/path/Android.bp", nil)) }) }) t.Run("not canonical", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", `path "path/with/../in/it/Android.bp" is not a canonical path, use "path/in/it/Android.bp" instead`, func() { factory.Fixture(t, FixtureAddFile("path/with/../in/it/Android.bp", nil)) }) }) t.Run("FixtureAddFile", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() { factory.Fixture(t, FixtureAddFile("out/Android.bp", nil)) }) }) t.Run("FixtureMergeMockFs", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() { factory.Fixture(t, FixtureMergeMockFs(MockFS{ "out/Android.bp": nil, })) }) }) t.Run("FixtureModifyMockFS", func(t *testing.T) { AssertPanicMessageContains(t, "source path validation failed", `cannot add output path "out/Android.bp" to the mock file system`, func() { factory.Fixture(t, FixtureModifyMockFS(func(fs MockFS) { fs["out/Android.bp"] = nil })) }) }) }