github.com/haraldrudell/parl@v0.4.176/punix/errno_test.go (about) 1 /* 2 © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/) 3 ISC License 4 */ 5 6 package punix 7 8 import ( 9 "errors" 10 "fmt" 11 "math" 12 "os" 13 "reflect" 14 "strconv" 15 "strings" 16 "testing" 17 18 "github.com/haraldrudell/parl/perrors" 19 "golang.org/x/sys/unix" 20 ) 21 22 func TestIsENOENT(t *testing.T) { 23 err := perrors.Errorf("err: %w", unix.ENOENT) 24 if !IsENOENT(err) { 25 t.Error("IsENOENT returned false") 26 } 27 28 err = perrors.New("error") 29 if IsENOENT(err) { 30 t.Error("IsENOENT returned true") 31 } 32 } 33 34 func TestErrnoValues(t *testing.T) { 35 36 // this test will only run from the command-line like: 37 // go test -v -run '^TestErrnoValues$' ./punix 38 39 // skip test if go test -v flag was not provided 40 hasVFlag := false 41 verboseFlag := "-test.v=true" 42 for _, s := range os.Args { 43 if hasVFlag = s == verboseFlag; hasVFlag { 44 break 45 } 46 } 47 if !hasVFlag { 48 t.Skip() 49 } 50 51 // /var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-build2538455228/b001/punix.test, 52 // -test.testlogfile=/var/folders/sq/0x1_9fyn1bv907s7ypfryt1c0000gn/T/go-build2538455228/b001/testlog.txt, 53 // -test.paniconexit0, 54 // -test.timeout=10m0s, 55 // -test.v=true, 56 // -test.run=/TestErrnoValues$ 57 //t.Logf("%#v", os.Args) 58 59 var errno unix.Errno 60 var _ error = errno 61 var _ error = &errno 62 var errnop = &errno 63 _ = errnop 64 65 // two-level indirection interface matching does not work 66 // cannot use &errnop (value of type **unix.Errno) as *error value in variable declaration: 67 // **unix.Errno does not implement *error (type *error is pointer to interface, not interface) 68 //var _ *error = &errnop 69 70 // invalid operation: cannot compare errno == nil 71 // (mismatched types unix.Errno and untyped nil) 72 //t.Logf("errno == nil: %t", errno == nil) 73 74 // errno is compared to int, not nil 75 // errno == 0 → true 76 t.Logf("errno == 0 → %t", errno == 0) 77 78 // to print properly, errno need to be cast to int 79 // printing errno: %s: state not recoverable %q: "state not recoverable" %v: state not recoverable 80 // printing int(errno): %d: 104 0x%x: 0x68 81 errno = unix.ENOTRECOVERABLE 82 t.Logf("printing errno: %%s: %s %%q: %[1]q %%v: %[1]v", errno) 83 t.Logf("printing int(errno): %%d: %d 0x%%x: 0x%[1]x", int(errno)) 84 85 var e unix.Errno 86 if e == 0 { 87 t.Logf("if errno != 0 {…") 88 } 89 90 // %T: unix.Errno %#v: 0x68 91 t.Logf("%%T: %T %%#v: %#[1]v", errno) 92 93 t.Fail() // causes prints to be output 94 } 95 96 func TestErrno(t *testing.T) { 97 var errno unix.Errno 98 99 // test nil 100 errno = Errno(nil) 101 if errno != 0 { 102 t.Errorf("punix.Errno returned non-zero") 103 } 104 105 // test non-unix.Errno 106 errno = Errno(perrors.New("error")) 107 if errno != 0 { 108 t.Errorf("punix.Errno returned non-zero") 109 } 110 111 err := fmt.Errorf("err: %w", unix.ENOENT) 112 113 var sList []string 114 for e := err; e != nil; e = errors.Unwrap(e) { 115 sList = append(sList, reflect.TypeOf(e).String()) 116 } 117 t.Logf("err types: %s", strings.Join(sList, "\x20")) 118 t.Logf("unix.ENOENT type: %s", reflect.TypeOf(unix.ENOENT).String()) 119 120 // test non-unix.Errno 121 errno = Errno(err) 122 if errno == 0 { 123 t.Errorf("punix.Errno returned zero") 124 } 125 if errno != unix.ENOENT { 126 t.Errorf("punix.Errno returned wrong value: %#v", errno) 127 } 128 129 } 130 131 func TestErrnoValue(t *testing.T) { 132 var epermInt = 1 133 var epermString = "operation not permitted" 134 var epermName = "EPERM" 135 136 var isError bool 137 var errnoValue int 138 var actual string 139 140 isError = unix.EPERM != 0 141 if !isError { 142 t.Error("isError false") 143 } 144 errnoValue = int(unix.EPERM) 145 if errnoValue != epermInt { 146 t.Errorf("errnoValue %d exp %d", errnoValue, epermInt) 147 } 148 actual = fmt.Sprintf("%d", unix.EPERM) 149 if actual != strconv.Itoa(epermInt) { 150 t.Errorf("%%d: %q exp %q", actual, strconv.Itoa(epermInt)) 151 } 152 actual = fmt.Sprintf("%v", unix.EPERM) 153 if actual != epermString { 154 t.Errorf("%%v: %q exp %q", actual, epermString) 155 } 156 actual = unix.ErrnoName(unix.EPERM) 157 if actual != epermName { 158 t.Errorf("ErrnoName: %q exp %q", actual, epermName) 159 } 160 } 161 162 func TestErrorNumberString(t *testing.T) { 163 type args struct { 164 label string 165 err error 166 } 167 tests := []struct { 168 name string 169 args args 170 wantErrnoNumericString string 171 }{ 172 {"no error", args{"abc", nil}, ""}, 173 {"EPERM", args{"errno", unix.EPERM}, "errno: EPERM 1 0x1"}, 174 {"-1", args{"", unix.Errno(math.MaxUint)}, "-1 -0x1"}, 175 } 176 for _, tt := range tests { 177 t.Run(tt.name, func(t *testing.T) { 178 if gotErrnoNumericString := ErrnoString(tt.args.label, tt.args.err); gotErrnoNumericString != tt.wantErrnoNumericString { 179 t.Errorf("ErrorNumberString() = %v, want %v", gotErrnoNumericString, tt.wantErrnoNumericString) 180 } 181 }) 182 } 183 }