Utilerrors.Aggregate: Allow using with errors.Is()

Kubernetes-commit: 212190e25e18600bbca2eb5c77aa3fe5bcc55af1
This commit is contained in:
Alvaro Aleman
2020-02-24 15:15:04 +01:00
committed by Kubernetes Publisher
parent fe49f17efb
commit 6b7675c693
2 changed files with 130 additions and 1 deletions

View File

@@ -17,6 +17,8 @@ limitations under the License.
package clientcmd
import (
"errors"
"fmt"
"io/ioutil"
"os"
"strings"
@@ -569,3 +571,100 @@ func (c configValidationTest) testAuthInfo(authInfoName string, t *testing.T) {
}
}
}
type alwaysMatchingError struct{}
func (_ alwaysMatchingError) Error() string {
return "error"
}
func (_ alwaysMatchingError) Is(_ error) bool {
return true
}
type someError struct{ msg string }
func (se someError) Error() string {
if se.msg != "" {
return se.msg
}
return "err"
}
func TestErrConfigurationInvalidWithErrorsIs(t *testing.T) {
testCases := []struct {
name string
err error
matchAgainst error
expectMatch bool
}{
{
name: "no match",
err: errConfigurationInvalid{errors.New("my-error"), errors.New("my-other-error")},
matchAgainst: fmt.Errorf("no entry %s", "here"),
},
{
name: "match via .Is()",
err: errConfigurationInvalid{errors.New("forbidden"), alwaysMatchingError{}},
matchAgainst: errors.New("unauthorized"),
expectMatch: true,
},
{
name: "match via equality",
err: errConfigurationInvalid{errors.New("err"), someError{}},
matchAgainst: someError{},
expectMatch: true,
},
{
name: "match via nested aggregate",
err: errConfigurationInvalid{errors.New("closed today"), errConfigurationInvalid{errConfigurationInvalid{someError{}}}},
matchAgainst: someError{},
expectMatch: true,
},
{
name: "match via wrapped aggregate",
err: fmt.Errorf("wrap: %w", errConfigurationInvalid{errors.New("err"), someError{}}),
matchAgainst: someError{},
expectMatch: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := errors.Is(tc.err, tc.matchAgainst)
if result != tc.expectMatch {
t.Errorf("expected match: %t, got match: %t", tc.expectMatch, result)
}
})
}
}
type accessTrackingError struct {
wasAccessed bool
}
func (accessTrackingError) Error() string {
return "err"
}
func (ate *accessTrackingError) Is(_ error) bool {
ate.wasAccessed = true
return true
}
var _ error = &accessTrackingError{}
func TestErrConfigurationInvalidWithErrorsIsShortCircuitsOnFirstMatch(t *testing.T) {
errC := errConfigurationInvalid{&accessTrackingError{}, &accessTrackingError{}}
_ = errors.Is(errC, &accessTrackingError{})
var numAccessed int
for _, err := range errC {
if ate := err.(*accessTrackingError); ate.wasAccessed {
numAccessed++
}
}
if numAccessed != 1 {
t.Errorf("expected exactly one error to get accessed, got %d", numAccessed)
}
}