-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors_test.go
More file actions
164 lines (132 loc) · 4.78 KB
/
errors_test.go
File metadata and controls
164 lines (132 loc) · 4.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
package machineid
import (
"errors"
"fmt"
"testing"
)
func TestCommandErrorMessage(t *testing.T) {
inner := fmt.Errorf("exit status 1")
err := &CommandError{Command: "sysctl", Err: inner}
want := `command "sysctl" failed: exit status 1`
if err.Error() != want {
t.Errorf("CommandError.Error() = %q, want %q", err.Error(), want)
}
}
func TestCommandErrorUnwrap(t *testing.T) {
inner := fmt.Errorf("exit status 1")
err := &CommandError{Command: "sysctl", Err: inner}
if err.Unwrap() != inner {
t.Error("CommandError.Unwrap() did not return inner error")
}
}
func TestCommandErrorAs(t *testing.T) {
inner := fmt.Errorf("exit status 1")
err := fmt.Errorf("collecting CPU: %w", &CommandError{Command: "sysctl", Err: inner})
var cmdErr *CommandError
if !errors.As(err, &cmdErr) {
t.Fatal("errors.As() should find CommandError in wrapped chain")
}
if cmdErr.Command != "sysctl" {
t.Errorf("CommandError.Command = %q, want %q", cmdErr.Command, "sysctl")
}
}
func TestParseErrorMessage(t *testing.T) {
inner := fmt.Errorf("unexpected end of JSON input")
err := &ParseError{Source: "system_profiler JSON", Err: inner}
want := "failed to parse system_profiler JSON: unexpected end of JSON input"
if err.Error() != want {
t.Errorf("ParseError.Error() = %q, want %q", err.Error(), want)
}
}
func TestParseErrorUnwrap(t *testing.T) {
inner := fmt.Errorf("unexpected end of JSON input")
err := &ParseError{Source: "system_profiler JSON", Err: inner}
if err.Unwrap() != inner {
t.Error("ParseError.Unwrap() did not return inner error")
}
}
func TestParseErrorAs(t *testing.T) {
inner := fmt.Errorf("invalid character")
err := fmt.Errorf("hardware UUID: %w", &ParseError{Source: "ioreg output", Err: inner})
var parseErr *ParseError
if !errors.As(err, &parseErr) {
t.Fatal("errors.As() should find ParseError in wrapped chain")
}
if parseErr.Source != "ioreg output" {
t.Errorf("ParseError.Source = %q, want %q", parseErr.Source, "ioreg output")
}
}
func TestComponentErrorMessage(t *testing.T) {
inner := ErrNotFound
err := &ComponentError{Component: "uuid", Err: inner}
want := `component "uuid": value not found`
if err.Error() != want {
t.Errorf("ComponentError.Error() = %q, want %q", err.Error(), want)
}
}
func TestComponentErrorUnwrap(t *testing.T) {
err := &ComponentError{Component: "cpu", Err: ErrAllMethodsFailed}
if err.Unwrap() != ErrAllMethodsFailed {
t.Error("ComponentError.Unwrap() did not return inner error")
}
}
func TestComponentErrorIs(t *testing.T) {
err := &ComponentError{Component: "cpu", Err: ErrAllMethodsFailed}
if !errors.Is(err, ErrAllMethodsFailed) {
t.Error("errors.Is(ComponentError, ErrAllMethodsFailed) should be true")
}
}
func TestComponentErrorAs(t *testing.T) {
err := fmt.Errorf("ID generation: %w", &ComponentError{Component: "disk", Err: ErrNotFound})
var compErr *ComponentError
if !errors.As(err, &compErr) {
t.Fatal("errors.As() should find ComponentError in wrapped chain")
}
if compErr.Component != "disk" {
t.Errorf("ComponentError.Component = %q, want %q", compErr.Component, "disk")
}
if !errors.Is(compErr, ErrNotFound) {
t.Error("errors.Is(ComponentError, ErrNotFound) should be true through Unwrap")
}
}
func TestSentinelErrorsWrapping(t *testing.T) {
tests := []struct {
name string
err error
sentinel error
}{
{"ErrNotFound wrapped", fmt.Errorf("UUID not found: %w", ErrNotFound), ErrNotFound},
{"ErrOEMPlaceholder wrapped", fmt.Errorf("serial is placeholder: %w", ErrOEMPlaceholder), ErrOEMPlaceholder},
{"ErrAllMethodsFailed wrapped", fmt.Errorf("CPU failed: %w", ErrAllMethodsFailed), ErrAllMethodsFailed},
{"ErrEmptyValue wrapped", fmt.Errorf("empty: %w", ErrEmptyValue), ErrEmptyValue},
{"ErrNoValues wrapped", fmt.Errorf("no values: %w", ErrNoValues), ErrNoValues},
{"ErrNoIdentifiers direct", ErrNoIdentifiers, ErrNoIdentifiers},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if !errors.Is(tt.err, tt.sentinel) {
t.Errorf("errors.Is() should find %v in %v", tt.sentinel, tt.err)
}
})
}
}
func TestDeepWrappingChain(t *testing.T) {
// CommandError -> ComponentError -> wrapped error
cmdErr := &CommandError{Command: "ioreg", Err: fmt.Errorf("not found")}
compErr := &ComponentError{Component: "uuid", Err: cmdErr}
topErr := fmt.Errorf("ID generation failed: %w", compErr)
var gotCmd *CommandError
if !errors.As(topErr, &gotCmd) {
t.Fatal("errors.As() should find CommandError through deep chain")
}
if gotCmd.Command != "ioreg" {
t.Errorf("CommandError.Command = %q, want %q", gotCmd.Command, "ioreg")
}
var gotComp *ComponentError
if !errors.As(topErr, &gotComp) {
t.Fatal("errors.As() should find ComponentError through deep chain")
}
if gotComp.Component != "uuid" {
t.Errorf("ComponentError.Component = %q, want %q", gotComp.Component, "uuid")
}
}