diff options
author | Zach Koopmans <zkoopmans@google.com> | 2021-05-18 14:33:34 -0700 |
---|---|---|
committer | gVisor bot <gvisor-bot@google.com> | 2021-05-18 14:36:21 -0700 |
commit | 8ff6694e540d0ac2004db503a09f14b048c411f6 (patch) | |
tree | 5ba14867fa1c69de6967416f80d4d4e2c6e0e696 /pkg/linuxerr/linuxerr_test.go | |
parent | 5d04e0ae3391cfd518e73141f148ddb8e62faf60 (diff) |
[syserror] Add linuxerr package.
Add linuxerr package to replace syserror and syserr errors. This is done
to improve performance comparing/returning errors to on par with
syscall.Errno.
The below linuxerr_test (formerly syserror_test) shows linuxerr.Error
on par with unix.Error (syscall.Errno) as desired.
BenchmarkAssignErrno
BenchmarkAssignErrno-6 1000000000 0.6291 ns/op
BenchmarkLinuxerrAssignError
BenchmarkLinuxerrAssignError-6 1000000000 0.5808 ns/op
BenchmarkAssignSyserrorError
BenchmarkAssignSyserrorError-6 1000000000 0.6188 ns/op
BenchmarkCompareErrno
BenchmarkCompareErrno-6 1000000000 0.5041 ns/op
BenchmarkCompareLinuxerrError
BenchmarkCompareLinuxerrError-6 1000000000 0.4660 ns/op
BenchmarkCompareSyserrorError
BenchmarkCompareSyserrorError-6 309026907 3.386 ns/op
BenchmarkSwitchErrno
BenchmarkSwitchErrno-6 722253750 1.440 ns/op
BenchmarkSwitchLinuxerrError
BenchmarkSwitchLinuxerrError-6 709108542 1.453 ns/op
BenchmarkSwitchSyserrorError
BenchmarkSwitchSyserrorError-6 106331331 11.21 ns/op
PiperOrigin-RevId: 374507431
Diffstat (limited to 'pkg/linuxerr/linuxerr_test.go')
-rw-r--r-- | pkg/linuxerr/linuxerr_test.go | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/pkg/linuxerr/linuxerr_test.go b/pkg/linuxerr/linuxerr_test.go new file mode 100644 index 000000000..d34937e93 --- /dev/null +++ b/pkg/linuxerr/linuxerr_test.go @@ -0,0 +1,164 @@ +// Copyright 2018 The gVisor Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package syserror_test + +import ( + "errors" + "testing" + + "golang.org/x/sys/unix" + "gvisor.dev/gvisor/pkg/linuxerr" + "gvisor.dev/gvisor/pkg/syserror" +) + +var globalError error + +func BenchmarkAssignErrno(b *testing.B) { + for i := b.N; i > 0; i-- { + globalError = unix.EINVAL + } +} + +func BenchmarkLinuxerrAssignError(b *testing.B) { + for i := b.N; i > 0; i-- { + globalError = linuxerr.EINVAL + } +} + +func BenchmarkAssignSyserrorError(b *testing.B) { + for i := b.N; i > 0; i-- { + globalError = syserror.EINVAL + } +} + +func BenchmarkCompareErrno(b *testing.B) { + globalError = unix.EAGAIN + j := 0 + for i := b.N; i > 0; i-- { + if globalError == unix.EINVAL { + j++ + } + } +} + +func BenchmarkCompareLinuxerrError(b *testing.B) { + globalError = linuxerr.E2BIG + j := 0 + for i := b.N; i > 0; i-- { + if globalError == linuxerr.EINVAL { + j++ + } + } +} + +func BenchmarkCompareSyserrorError(b *testing.B) { + globalError = syserror.EAGAIN + j := 0 + for i := b.N; i > 0; i-- { + if globalError == syserror.EINVAL { + j++ + } + } +} + +func BenchmarkSwitchErrno(b *testing.B) { + globalError = unix.EPERM + j := 0 + for i := b.N; i > 0; i-- { + switch globalError { + case unix.EINVAL: + j++ + case unix.EINTR: + j += 2 + case unix.EAGAIN: + j += 3 + } + } +} + +func BenchmarkSwitchLinuxerrError(b *testing.B) { + globalError = linuxerr.EPERM + j := 0 + for i := b.N; i > 0; i-- { + switch globalError { + case linuxerr.EINVAL: + j++ + case linuxerr.EINTR: + j += 2 + case linuxerr.EAGAIN: + j += 3 + } + } +} + +func BenchmarkSwitchSyserrorError(b *testing.B) { + globalError = syserror.EPERM + j := 0 + for i := b.N; i > 0; i-- { + switch globalError { + case syserror.EINVAL: + j++ + case syserror.EINTR: + j += 2 + case syserror.EAGAIN: + j += 3 + } + } +} + +type translationTestTable struct { + fn string + errIn error + syscallErrorIn unix.Errno + expectedBool bool + expectedTranslation unix.Errno +} + +func TestErrorTranslation(t *testing.T) { + myError := errors.New("My test error") + myError2 := errors.New("Another test error") + testTable := []translationTestTable{ + {"TranslateError", myError, 0, false, 0}, + {"TranslateError", myError2, 0, false, 0}, + {"AddErrorTranslation", myError, unix.EAGAIN, true, 0}, + {"AddErrorTranslation", myError, unix.EAGAIN, false, 0}, + {"AddErrorTranslation", myError, unix.EPERM, false, 0}, + {"TranslateError", myError, 0, true, unix.EAGAIN}, + {"TranslateError", myError2, 0, false, 0}, + {"AddErrorTranslation", myError2, unix.EPERM, true, 0}, + {"AddErrorTranslation", myError2, unix.EPERM, false, 0}, + {"AddErrorTranslation", myError2, unix.EAGAIN, false, 0}, + {"TranslateError", myError, 0, true, unix.EAGAIN}, + {"TranslateError", myError2, 0, true, unix.EPERM}, + } + for _, tt := range testTable { + switch tt.fn { + case "TranslateError": + err, ok := syserror.TranslateError(tt.errIn) + if ok != tt.expectedBool { + t.Fatalf("%v(%v) => %v expected %v", tt.fn, tt.errIn, ok, tt.expectedBool) + } else if err != tt.expectedTranslation { + t.Fatalf("%v(%v) (error) => %v expected %v", tt.fn, tt.errIn, err, tt.expectedTranslation) + } + case "AddErrorTranslation": + ok := syserror.AddErrorTranslation(tt.errIn, tt.syscallErrorIn) + if ok != tt.expectedBool { + t.Fatalf("%v(%v) => %v expected %v", tt.fn, tt.errIn, ok, tt.expectedBool) + } + default: + t.Fatalf("Unknown function %v", tt.fn) + } + } +} |