Change:
<!-- Please use this template while reporting a bug and provide as much info as possible. Not doing so may result in your bug not being addressed in a timely manner. Thanks! If the matter is security related, please disclose it privately via -- Can't match "serviceaccounts/token", can only match "serviceaccounts" Can match "serviceaccounts/token"
/kind feature
/sig testing
/assign
/triage accepted

Discussion:
"fmt" "reflect" "sort" <ins> "strings" </ins> "sync" jsonpatch "github.com/evanphx/json-patch"

if !verbCovers { return false } <del> resourceCovers := r.Resource == "*" || r.Resource == action.GetResource().Resource if !resourceCovers { return false } return true </del> <ins> return resourceCovers(r.Resource, action) </ins> } func (r *SimpleReactor) React(action Action) (bool, runtime.Object, error) {

} func (r *SimpleWatchReactor) Handles(action Action) bool { <del> resourceCovers := r.Resource == "*" || r.Resource == action.GetResource().Resource if !resourceCovers { return false } return true </del> <ins> return resourceCovers(r.Resource, action) </ins> } func (r *SimpleWatchReactor) React(action Action) (bool, watch.Interface, error) {

} func (r *SimpleProxyReactor) Handles(action Action) bool { <del> resourceCovers := r.Resource == "*" || r.Resource == action.GetResource().Resource if !resourceCovers { return false } return true </del> <ins> return resourceCovers(r.Resource, action) </ins> } func (r *SimpleProxyReactor) React(action Action) (bool, restclient.ResponseWrapper, error) { return r.Reaction(action) } <ins> func resourceCovers(resource string, action Action) bool { if resource == "*" { return true } if resource == action.GetResource().Resource { return true } if index := strings.Index(resource, "/"); index != -1 && resource[:index] == action.GetResource().Resource && resource[index+1:] == action.GetSubresource() { return true } return false } </ins>

errNotFound = errors.NewNotFound(gvr.GroupResource(), "pod") assert.EqualError(t, err, errNotFound.Error()) } <ins> func Test_resourceCovers(t *testing.T) { type args struct { resource string action   Action } tests := []struct { name string args args want bool }{ { args: args{ resource: "*", action:   ActionImpl{}, }, want: true, }, { args: args{ resource: "serviceaccounts", action:   ActionImpl{}, }, want: false, }, { args: args{ resource: "serviceaccounts", action: ActionImpl{ Resource: schema.GroupVersionResource{ Resource: "serviceaccounts", }, }, }, want: true, }, { args: args{ resource: "serviceaccounts/token", action: ActionImpl{ Resource: schema.GroupVersionResource{}, }, }, want: false, }, { args: args{ resource: "serviceaccounts/token", action: ActionImpl{ Resource: schema.GroupVersionResource{ Resource: "serviceaccounts", }, }, }, want: false, }, { args: args{ resource: "serviceaccounts/token", action: ActionImpl{ Resource:    schema.GroupVersionResource{}, Subresource: "token", }, }, want: false, }, { args: args{ resource: "serviceaccounts/token", action: ActionImpl{ Resource: schema.GroupVersionResource{ Resource: "serviceaccounts", }, Subresource: "token", }, }, want: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if got := resourceCovers(tt.args.resource, tt.args.action); got != tt.want { t.Errorf("resourceCovers() = %v, want %v", got, tt.want) } }) } } </ins>