|
1 | 1 | package mounts // import "github.com/docker/docker/volume/mounts"
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "errors" |
4 | 5 | "io/ioutil"
|
5 | 6 | "os"
|
6 | 7 | "runtime"
|
7 | 8 | "strings"
|
8 | 9 | "testing"
|
9 | 10 |
|
10 | 11 | "github.com/docker/docker/api/types/mount"
|
| 12 | + "gotest.tools/assert" |
| 13 | + "gotest.tools/assert/cmp" |
11 | 14 | )
|
12 | 15 |
|
13 | 16 | type parseMountRawTestSet struct {
|
@@ -477,4 +480,51 @@ func TestParseMountSpec(t *testing.T) {
|
477 | 480 | t.Errorf("Expected mount copy data to match. Expected: '%v', Actual: '%v'", c.expected.CopyData, mp.CopyData)
|
478 | 481 | }
|
479 | 482 | }
|
| 483 | + |
| 484 | +} |
| 485 | + |
| 486 | +// always returns the configured error |
| 487 | +// this is used to test error handling |
| 488 | +type mockFiProviderWithError struct{ err error } |
| 489 | + |
| 490 | +func (m mockFiProviderWithError) fileInfo(path string) (bool, bool, error) { |
| 491 | + return false, false, m.err |
| 492 | +} |
| 493 | + |
| 494 | +// TestParseMountSpecBindWithFileinfoError makes sure that the parser returns |
| 495 | +// the error produced by the fileinfo provider. |
| 496 | +// |
| 497 | +// Some extra context for the future in case of changes and possible wtf are we |
| 498 | +// testing this for: |
| 499 | +// |
| 500 | +// Currently this "fileInfoProvider" returns (bool, bool, error) |
| 501 | +// The 1st bool is "does this path exist" |
| 502 | +// The 2nd bool is "is this path a dir" |
| 503 | +// Then of course the error is an error. |
| 504 | +// |
| 505 | +// The issue is the parser was ignoring the error and only looking at the |
| 506 | +// "does this path exist" boolean, which is always false if there is an error. |
| 507 | +// Then the error returned to the caller was a (slightly, maybe) friendlier |
| 508 | +// error string than what comes from `os.Stat` |
| 509 | +// So ...the caller was always getting an error saying the path doesn't exist |
| 510 | +// even if it does exist but got some other error (like a permission error). |
| 511 | +// This is confusing to users. |
| 512 | +func TestParseMountSpecBindWithFileinfoError(t *testing.T) { |
| 513 | + previousProvider := currentFileInfoProvider |
| 514 | + defer func() { currentFileInfoProvider = previousProvider }() |
| 515 | + |
| 516 | + testErr := errors.New("some crazy error") |
| 517 | + currentFileInfoProvider = &mockFiProviderWithError{err: testErr} |
7E82
| 518 | + |
| 519 | + p := "/bananas" |
| 520 | + if runtime.GOOS == "windows" { |
| 521 | + p = `c:\bananas` |
| 522 | + } |
| 523 | + m := mount.Mount{Type: mount.TypeBind, Source: p, Target: p} |
| 524 | + |
| 525 | + parser := NewParser(runtime.GOOS) |
| 526 | + |
| 527 | + _, err := parser.ParseMountSpec(m) |
| 528 | + assert.Assert(t, err != nil) |
| 529 | + assert.Assert(t, cmp.Contains(err.Error(), "some crazy error")) |
480 | 530 | }
|
0 commit comments