diff options
Diffstat (limited to 'pkg/errors')
-rw-r--r-- | pkg/errors/linuxerr/BUILD | 1 | ||||
-rw-r--r-- | pkg/errors/linuxerr/linuxerr.go | 22 | ||||
-rw-r--r-- | pkg/errors/linuxerr/linuxerr_test.go | 73 |
3 files changed, 90 insertions, 6 deletions
diff --git a/pkg/errors/linuxerr/BUILD b/pkg/errors/linuxerr/BUILD index 8afc9688c..201727780 100644 --- a/pkg/errors/linuxerr/BUILD +++ b/pkg/errors/linuxerr/BUILD @@ -9,6 +9,7 @@ go_library( deps = [ "//pkg/abi/linux/errno", "//pkg/errors", + "@org_golang_x_sys//unix:go_default_library", ], ) diff --git a/pkg/errors/linuxerr/linuxerr.go b/pkg/errors/linuxerr/linuxerr.go index bbdcdecd0..f9f8412e0 100644 --- a/pkg/errors/linuxerr/linuxerr.go +++ b/pkg/errors/linuxerr/linuxerr.go @@ -20,6 +20,7 @@ package linuxerr import ( "fmt" + "golang.org/x/sys/unix" "gvisor.dev/gvisor/pkg/abi/linux/errno" "gvisor.dev/gvisor/pkg/errors" ) @@ -165,6 +166,8 @@ var ( EWOULDBLOCK = EAGAIN EDEADLOCK = EDEADLK ENONET = ENOENT + ENOATTR = ENODATA + ENOTSUP = EOPNOTSUPP ) // A nil *errors.Error denotes no error and is placed at the 0 index of @@ -325,3 +328,22 @@ func ErrorFromErrno(e errno.Errno) *errors.Error { } panic(fmt.Sprintf("invalid error requested with errno: %d", e)) } + +// Equals compars a linuxerr to a given error +// TODO(b/34162363): Remove when syserror is removed. +func Equals(e *errors.Error, err error) bool { + if err == nil { + return e == NOERROR || e == nil + } + if e == nil { + return err == NOERROR || err == unix.Errno(0) + } + + switch err.(type) { + case *errors.Error: + return e == err + case unix.Errno, error: + return unix.Errno(e.Errno()) == err + } + return false +} diff --git a/pkg/errors/linuxerr/linuxerr_test.go b/pkg/errors/linuxerr/linuxerr_test.go index a81dd9560..f09d61b02 100644 --- a/pkg/errors/linuxerr/linuxerr_test.go +++ b/pkg/errors/linuxerr/linuxerr_test.go @@ -16,6 +16,8 @@ package syserror_test import ( "errors" + "io" + "io/fs" "syscall" "testing" @@ -42,7 +44,7 @@ func BenchmarkAssignLinuxerr(b *testing.B) { func BenchmarkAssignSyserror(b *testing.B) { for i := b.N; i > 0; i-- { - globalError = syserror.EINVAL + globalError = linuxerr.ENOMSG } } @@ -67,10 +69,10 @@ func BenchmarkCompareLinuxerr(b *testing.B) { } func BenchmarkCompareSyserror(b *testing.B) { - globalError = syserror.EAGAIN + globalError = linuxerr.EAGAIN j := 0 for i := b.N; i > 0; i-- { - if globalError == syserror.EINVAL { + if globalError == linuxerr.EACCES { j++ } } @@ -107,15 +109,15 @@ func BenchmarkSwitchLinuxerr(b *testing.B) { } func BenchmarkSwitchSyserror(b *testing.B) { - globalError = syserror.EPERM + globalError = linuxerr.EPERM j := 0 for i := b.N; i > 0; i-- { switch globalError { - case syserror.EINVAL: + case linuxerr.EACCES: j++ case syserror.EINTR: j += 2 - case syserror.EAGAIN: + case linuxerr.EAGAIN: j += 3 } } @@ -243,3 +245,62 @@ func TestSyscallErrnoToErrors(t *testing.T) { }) } } + +// TestEqualsMethod tests that the Equals method correctly compares syerror, +// unix.Errno and linuxerr. +// TODO (b/34162363): Remove this. +func TestEqualsMethod(t *testing.T) { + for _, tc := range []struct { + name string + linuxErr []*gErrors.Error + err []error + equal bool + }{ + { + name: "compare nil", + linuxErr: []*gErrors.Error{nil, linuxerr.NOERROR}, + err: []error{nil, linuxerr.NOERROR, unix.Errno(0)}, + equal: true, + }, + { + name: "linuxerr nil error not", + linuxErr: []*gErrors.Error{nil, linuxerr.NOERROR}, + err: []error{unix.Errno(1), linuxerr.EPERM, linuxerr.EACCES}, + equal: false, + }, + { + name: "linuxerr not nil error nil", + linuxErr: []*gErrors.Error{linuxerr.ENOENT}, + err: []error{nil, unix.Errno(0), linuxerr.NOERROR}, + equal: false, + }, + { + name: "equal errors", + linuxErr: []*gErrors.Error{linuxerr.ESRCH}, + err: []error{linuxerr.ESRCH, linuxerr.ESRCH, unix.Errno(linuxerr.ESRCH.Errno())}, + equal: true, + }, + { + name: "unequal errors", + linuxErr: []*gErrors.Error{linuxerr.ENOENT}, + err: []error{linuxerr.ESRCH, linuxerr.ESRCH, unix.Errno(linuxerr.ESRCH.Errno())}, + equal: false, + }, + { + name: "other error", + linuxErr: []*gErrors.Error{nil, linuxerr.NOERROR, linuxerr.E2BIG, linuxerr.EINVAL}, + err: []error{fs.ErrInvalid, io.EOF}, + equal: false, + }, + } { + t.Run(tc.name, func(t *testing.T) { + for _, le := range tc.linuxErr { + for _, e := range tc.err { + if linuxerr.Equals(le, e) != tc.equal { + t.Fatalf("Expected %t from Equals method for linuxerr: %s %T and error: %s %T", tc.equal, le, le, e, e) + } + } + } + }) + } +} |