volume/mounts: don't use global variable for fileinfoprovider

This allows stubbing the provider for a test without side effects for
other tests, making it no longer needed to reset it to its original
value in a defer()

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn 2021-06-29 13:19:02 +02:00
parent 28b0f47599
commit 73378d2042
No known key found for this signature in database
GPG key ID: 76698F39D527CE8C
6 changed files with 51 additions and 49 deletions

View file

@ -9,7 +9,11 @@ import (
// NewLCOWParser creates a parser with Linux Containers on Windows semantics.
func NewLCOWParser() Parser {
return &lcowParser{}
return &lcowParser{
windowsParser{
fi: defaultFileInfoProvider{},
},
}
}
// rxLCOWDestination is the regex expression for the mount destination for LCOW

View file

@ -8,10 +8,6 @@ import (
)
func TestLCOWParseMountRaw(t *testing.T) {
previousProvider := currentFileInfoProvider
defer func() { currentFileInfoProvider = previousProvider }()
currentFileInfoProvider = mockFiProvider{}
valid := []string{
`/foo`,
`/foo/`,
@ -81,6 +77,9 @@ func TestLCOWParseMountRaw(t *testing.T) {
}
parser := NewLCOWParser()
if p, ok := parser.(*lcowParser); ok {
p.fi = mockFiProvider{}
}
for _, path := range valid {
if _, err := parser.ParseMountRaw(path, "local"); err != nil {
@ -100,10 +99,6 @@ func TestLCOWParseMountRaw(t *testing.T) {
}
func TestLCOWParseMountRawSplit(t *testing.T) {
previousProvider := currentFileInfoProvider
defer func() { currentFileInfoProvider = previousProvider }()
currentFileInfoProvider = mockFiProvider{}
cases := []struct {
bind string
driver string
@ -130,6 +125,10 @@ func TestLCOWParseMountRawSplit(t *testing.T) {
}
parser := NewLCOWParser()
if p, ok := parser.(*lcowParser); ok {
p.fi = mockFiProvider{}
}
for i, c := range cases {
t.Logf("case %d", i)
m, err := parser.ParseMountRaw(c.bind, c.driver)

View file

@ -14,10 +14,14 @@ import (
// NewLinuxParser creates a parser with Linux semantics.
func NewLinuxParser() Parser {
return &linuxParser{}
return &linuxParser{
fi: defaultFileInfoProvider{},
}
}
type linuxParser struct{}
type linuxParser struct {
fi fileInfoProvider
}
func linuxSplitRawSpec(raw string) ([]string, error) {
if strings.Count(raw, ":") > 2 {
@ -86,7 +90,7 @@ func (p *linuxParser) validateMountConfigImpl(mnt *mount.Mount, validateBindSour
}
if validateBindSourceExists {
exists, _, err := currentFileInfoProvider.fileInfo(mnt.Source)
exists, _, err := p.fi.fileInfo(mnt.Source)
if err != nil {
return &errMountConfig{mnt, err}
}

View file

@ -10,10 +10,6 @@ import (
)
func TestLinuxParseMountRaw(t *testing.T) {
previousProvider := currentFileInfoProvider
defer func() { currentFileInfoProvider = previousProvider }()
currentFileInfoProvider = mockFiProvider{}
valid := []string{
"/home",
"/home:/home",
@ -80,6 +76,9 @@ func TestLinuxParseMountRaw(t *testing.T) {
}
parser := NewLinuxParser()
if p, ok := parser.(*linuxParser); ok {
p.fi = mockFiProvider{}
}
for _, path := range valid {
if _, err := parser.ParseMountRaw(path, "local"); err != nil {
@ -99,10 +98,6 @@ func TestLinuxParseMountRaw(t *testing.T) {
}
func TestLinuxParseMountRawSplit(t *testing.T) {
previousProvider := currentFileInfoProvider
defer func() { currentFileInfoProvider = previousProvider }()
currentFileInfoProvider = mockFiProvider{}
cases := []struct {
bind string
driver string
@ -126,6 +121,10 @@ func TestLinuxParseMountRawSplit(t *testing.T) {
}
parser := NewLinuxParser()
if p, ok := parser.(*linuxParser); ok {
p.fi = mockFiProvider{}
}
for i, c := range cases {
t.Logf("case %d", i)
m, err := parser.ParseMountRaw(c.bind, c.driver)
@ -185,13 +184,11 @@ func TestLinuxParseMountRawSplit(t *testing.T) {
// even if it does exist but got some other error (like a permission error).
// This is confusing to users.
func TestLinuxParseMountSpecBindWithFileinfoError(t *testing.T) {
previousProvider := currentFileInfoProvider
defer func() { currentFileInfoProvider = previousProvider }()
testErr := fmt.Errorf("some crazy error")
currentFileInfoProvider = &mockFiProviderWithError{err: testErr}
parser := NewLinuxParser()
testErr := fmt.Errorf("some crazy error")
if pr, ok := parser.(*linuxParser); ok {
pr.fi = &mockFiProviderWithError{err: testErr}
}
_, err := parser.ParseMountSpec(mount.Mount{
Type: mount.TypeBind,

View file

@ -14,10 +14,14 @@ import (
// NewWindowsParser creates a parser with Windows semantics.
func NewWindowsParser() Parser {
return &windowsParser{}
return &windowsParser{
fi: defaultFileInfoProvider{},
}
}
type windowsParser struct{}
type windowsParser struct {
fi fileInfoProvider
}
const (
// Spec should be in the format [source:]destination[:mode]
@ -76,7 +80,7 @@ const (
type mountValidator func(mnt *mount.Mount) error
func windowsSplitRawSpec(raw, destRegex string) ([]string, error) {
func (p *windowsParser) windowsSplitRawSpec(raw, destRegex string) ([]string, error) {
specExp := regexp.MustCompile(`^` + rxSource + destRegex + rxMode + `$`)
match := specExp.FindStringSubmatch(strings.ToLower(raw))
@ -119,8 +123,7 @@ func windowsSplitRawSpec(raw, destRegex string) ([]string, error) {
return nil, fmt.Errorf("volume name %q cannot be a reserved word for Windows filenames", matchgroups["destination"])
}
} else {
exists, isDir, _ := currentFileInfoProvider.fileInfo(matchgroups["destination"])
exists, isDir, _ := p.fi.fileInfo(matchgroups["destination"])
if exists && !isDir {
return nil, fmt.Errorf("file '%s' cannot be mapped. Only directories can be mapped on this platform", matchgroups["destination"])
@ -211,8 +214,6 @@ func (defaultFileInfoProvider) fileInfo(path string) (exist, isDir bool, err err
return true, fi.IsDir(), nil
}
var currentFileInfoProvider fileInfoProvider = defaultFileInfoProvider{}
func (p *windowsParser) validateMountConfigReg(mnt *mount.Mount, destRegex string, additionalValidators ...mountValidator) error {
for _, v := range additionalValidators {
@ -247,7 +248,7 @@ func (p *windowsParser) validateMountConfigReg(mnt *mount.Mount, destRegex strin
return &errMountConfig{mnt, err}
}
exists, isdir, err := currentFileInfoProvider.fileInfo(mnt.Source)
exists, isdir, err := p.fi.fileInfo(mnt.Source)
if err != nil {
return &errMountConfig{mnt, err}
}
@ -302,7 +303,7 @@ func (p *windowsParser) ParseMountRaw(raw, volumeDriver string) (*MountPoint, er
}
func (p *windowsParser) parseMountRaw(raw, volumeDriver, destRegex string, convertTargetToBackslash bool, additionalValidators ...mountValidator) (*MountPoint, error) {
arr, err := windowsSplitRawSpec(raw, destRegex)
arr, err := p.windowsSplitRawSpec(raw, destRegex)
if err != nil {
return nil, err
}

View file

@ -10,10 +10,6 @@ import (
)
func TestWindowsParseMountRaw(t *testing.T) {
previousProvider := currentFileInfoProvider
defer func() { currentFileInfoProvider = previousProvider }()
currentFileInfoProvider = mockFiProvider{}
valid := []string{
`d:\`,
`d:`,
@ -88,6 +84,9 @@ func TestWindowsParseMountRaw(t *testing.T) {
}
parser := NewWindowsParser()
if p, ok := parser.(*windowsParser); ok {
p.fi = mockFiProvider{}
}
for _, path := range valid {
if _, err := parser.ParseMountRaw(path, "local"); err != nil {
@ -107,10 +106,6 @@ func TestWindowsParseMountRaw(t *testing.T) {
}
func TestWindowsParseMountRawSplit(t *testing.T) {
previousProvider := currentFileInfoProvider
defer func() { currentFileInfoProvider = previousProvider }()
currentFileInfoProvider = mockFiProvider{}
cases := []struct {
bind string
driver string
@ -138,6 +133,10 @@ func TestWindowsParseMountRawSplit(t *testing.T) {
}
parser := NewWindowsParser()
if p, ok := parser.(*windowsParser); ok {
p.fi = mockFiProvider{}
}
for i, c := range cases {
t.Logf("case %d", i)
m, err := parser.ParseMountRaw(c.bind, c.driver)
@ -197,13 +196,11 @@ func TestWindowsParseMountRawSplit(t *testing.T) {
// even if it does exist but got some other error (like a permission error).
// This is confusing to users.
func TestWindowsParseMountSpecBindWithFileinfoError(t *testing.T) {
previousProvider := currentFileInfoProvider
defer func() { currentFileInfoProvider = previousProvider }()
testErr := fmt.Errorf("some crazy error")
currentFileInfoProvider = &mockFiProviderWithError{err: testErr}
parser := NewWindowsParser()
testErr := fmt.Errorf("some crazy error")
if pr, ok := parser.(*windowsParser); ok {
pr.fi = &mockFiProviderWithError{err: testErr}
}
_, err := parser.ParseMountSpec(mount.Mount{
Type: mount.TypeBind,