Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions e2e/proxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -839,8 +839,7 @@ var _ = Describe("Proxy", func() {
if lockMode == proxyrule.OptimisticLockMode {
Expect(err).To(Succeed())
} else {
fmt.Println(err)
Expect(k8serrors.IsUnauthorized(err)).To(BeTrue())
Expect(k8serrors.IsConflict(err) || k8serrors.IsUnauthorized(err)).To(BeTrue())
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ecordell or @vroldanbet can you confirm whether this is OK?

// paul sees the request fail, so he tries again:
Expect(DeletePod(ctx, paulClient, paulNamespace, paulPod)).To(Succeed())
}
Expand Down
14 changes: 12 additions & 2 deletions magefiles/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@ func (t Test) Unit() error {

// E2e runs the end-to-end tests against a real apiserver.
func (t Test) E2e() error {
args := append(e2eArgs(), "../e2e")
return RunSh("go", Tool())(args...)
}

// E2eUntilItFails runs the end-to-end tests indefinitely against a real apiserver until it fails.
func (t Test) E2eUntilItFails() error {
args := append(e2eArgs(), "--until-it-fails", "../e2e")
return RunSh("go", Tool())(args...)
}

func e2eArgs() []string {
args := []string{"run", "github.com/onsi/ginkgo/v2/ginkgo"}
args = append(args,
"--tags=e2e,failpoints",
Expand All @@ -41,6 +52,5 @@ func (t Test) E2e() error {
"-vv",
"--fail-fast",
"--randomize-all")
args = append(args, "../e2e")
return RunSh("go", Tool())(args...)
return args
}
24 changes: 21 additions & 3 deletions pkg/authz/distributedtx/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,11 +420,29 @@ func ResourceLockRel(input *WriteObjInput, workflowID string) *v1.RelationshipUp
// KubeConflict wraps an error and turns it into a standard kube conflict
// response.
func KubeConflict(err error, input *WriteObjInput) *KubeResp {
var group, resource, name string

if input == nil {
klog.Warningf("input to KubeConflict is nil for error %s", err)
} else {
if input.RequestInfo == nil {
klog.Warningf("input to KubeConflict has nil RequestInfo for error %s", err)
} else {
group = input.RequestInfo.APIGroup
resource = input.RequestInfo.Resource
}
if input.ObjectMeta == nil {
klog.Warningf("input to KubeConflict has nil ObjectMeta for error %s", err)
} else {
name = input.ObjectMeta.Name
}
}

var out KubeResp
statusError := k8serrors.NewConflict(schema.GroupResource{
Group: input.RequestInfo.APIGroup,
Resource: input.RequestInfo.Resource,
}, input.ObjectMeta.Name, err)
Group: group,
Resource: resource,
}, name, err)
out.StatusCode = http.StatusConflict
out.Err = *statusError
out.Body, _ = json.Marshal(statusError)
Expand Down
92 changes: 92 additions & 0 deletions pkg/authz/distributedtx/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package distributedtx

import (
"context"
"errors"
"io"
"net/http"
"strings"
Expand Down Expand Up @@ -119,3 +120,94 @@ func TestWorkflow(t *testing.T) {
})
}
}

func TestKubeConflict(t *testing.T) {
t.Parallel()
testCases := map[string]struct {
inputErr error
input *WriteObjInput
expectedJSON string
}{
`nil input`: {
inputErr: errors.New("some err"),
input: nil,
expectedJSON: `{
"ErrStatus" : {
"metadata" : { },
"status" : "Failure",
"message" : "Operation cannot be fulfilled on \"\": some err",
"reason" : "Conflict",
"details" : { },
"code" : 409
}
}`,
},
`nil request info`: {
inputErr: errors.New("some err"),
input: &WriteObjInput{
ObjectMeta: &metav1.ObjectMeta{Name: "my_object_meta"},
},
expectedJSON: `{
"ErrStatus" : {
"metadata" : { },
"status" : "Failure",
"message" : "Operation cannot be fulfilled on \"my_object_meta\": some err",
"reason" : "Conflict",
"details" : {
"name" : "my_object_meta"
},
"code" : 409
}
}`,
},
`nil object meta`: {
inputErr: errors.New("some err"),
input: &WriteObjInput{
RequestInfo: &request.RequestInfo{APIGroup: "foo", Resource: "bar"},
},
expectedJSON: `{
"ErrStatus" : {
"metadata" : { },
"status" : "Failure",
"message" : "Operation cannot be fulfilled on bar.foo \"\": some err",
"reason" : "Conflict",
"details" : {
"group" : "foo",
"kind" : "bar"
},
"code" : 409
}
}`,
},
`valid input`: {
inputErr: errors.New("some err"),
input: &WriteObjInput{
RequestInfo: &request.RequestInfo{APIGroup: "foo", Resource: "bar"},
ObjectMeta: &metav1.ObjectMeta{Name: "my_object_meta"},
},
expectedJSON: `{
"ErrStatus" : {
"metadata" : { },
"status" : "Failure",
"message" : "Operation cannot be fulfilled on bar.foo \"my_object_meta\": some err",
"reason" : "Conflict",
"details" : {
"name" : "my_object_meta",
"group" : "foo",
"kind" : "bar"
},
"code" : 409
}
}`,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
t.Parallel()

res := KubeConflict(tc.inputErr, tc.input)
require.NotNil(t, res, "expected non-nil response")
require.JSONEq(t, tc.expectedJSON, string(res.Body), "unexpected response body")
})
}
}
Loading