diff --git a/go.mod b/go.mod index 5d33e57..0e0368e 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/cosi-project/state-etcd go 1.23.0 require ( - github.com/cosi-project/runtime v0.6.1 + github.com/cosi-project/runtime v0.6.3 github.com/siderolabs/gen v0.5.0 github.com/stretchr/testify v1.9.0 go.etcd.io/etcd/api/v3 v3.5.15 diff --git a/go.sum b/go.sum index 0113f97..d6e2d2a 100644 --- a/go.sum +++ b/go.sum @@ -34,8 +34,8 @@ github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmf github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cosi-project/runtime v0.6.1 h1:mKNACtmdO9rBdI83zpVDuDRap7w4kCyE40gYn7oricM= -github.com/cosi-project/runtime v0.6.1/go.mod h1:2iQ2Wu57UNm89ZksFLoMLGEZnPzUkk5g64+AlWHopo4= +github.com/cosi-project/runtime v0.6.3 h1:nCmEIY1jypCoraRaNsFvaLHkBI/ALYk/X1CGea7Ie1E= +github.com/cosi-project/runtime v0.6.3/go.mod h1:2iQ2Wu57UNm89ZksFLoMLGEZnPzUkk5g64+AlWHopo4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/pkg/state/impl/etcd/errors.go b/pkg/state/impl/etcd/errors.go index 10df78a..1e0dc62 100644 --- a/pkg/state/impl/etcd/errors.go +++ b/pkg/state/impl/etcd/errors.go @@ -25,10 +25,15 @@ func ErrNotFound(r resource.Pointer) error { type eConflict struct { error + resource resource.Pointer } func (eConflict) ConflictError() {} +func (e eConflict) GetResource() resource.Pointer { + return e.resource +} + type eOwnerConflict struct { eConflict } @@ -50,21 +55,24 @@ func (eUnsupported) UnsupportedError() {} // ErrAlreadyExists generates error compatible with state.ErrConflict. func ErrAlreadyExists(r resource.Reference) error { return eConflict{ - fmt.Errorf("resource %s already exists", r), + error: fmt.Errorf("resource %s already exists", r), + resource: r, } } // ErrVersionConflict generates error compatible with state.ErrConflict. func ErrVersionConflict(r resource.Pointer, expected, found int64) error { return eConflict{ - fmt.Errorf("resource %s update conflict: expected version %q, actual version %q", r, expected, found), + error: fmt.Errorf("resource %s update conflict: expected version %q, actual version %q", r, expected, found), + resource: r, } } // ErrPendingFinalizers generates error compatible with state.ErrConflict. func ErrPendingFinalizers(r resource.Metadata) error { return eConflict{ - fmt.Errorf("resource %s has pending finalizers %s", r, r.Finalizers()), + error: fmt.Errorf("resource %s has pending finalizers %s", r, r.Finalizers()), + resource: r, } } @@ -72,7 +80,8 @@ func ErrPendingFinalizers(r resource.Metadata) error { func ErrOwnerConflict(r resource.Reference, owner string) error { return eOwnerConflict{ eConflict{ - fmt.Errorf("resource %s is owned by %q", r, owner), + error: fmt.Errorf("resource %s is owned by %q", r, owner), + resource: r, }, } } @@ -81,7 +90,8 @@ func ErrOwnerConflict(r resource.Reference, owner string) error { func ErrPhaseConflict(r resource.Reference, expectedPhase resource.Phase) error { return ePhaseConflict{ eConflict{ - fmt.Errorf("resource %s is not in phase %s", r, expectedPhase), + error: fmt.Errorf("resource %s is not in phase %s", r, expectedPhase), + resource: r, }, } } diff --git a/pkg/state/impl/etcd/errors_test.go b/pkg/state/impl/etcd/errors_test.go new file mode 100644 index 0000000..ac830e3 --- /dev/null +++ b/pkg/state/impl/etcd/errors_test.go @@ -0,0 +1,29 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package etcd_test + +import ( + "testing" + + "github.com/cosi-project/runtime/pkg/resource" + "github.com/cosi-project/runtime/pkg/state" + "github.com/cosi-project/state-etcd/pkg/state/impl/etcd" + "github.com/stretchr/testify/require" +) + +func TestErrors(t *testing.T) { + res := resource.NewMetadata("ns", "a", "b", resource.VersionUndefined) + + require.Implements(t, (*state.ErrConflict)(nil), etcd.ErrAlreadyExists(res)) + require.Implements(t, (*state.ErrConflict)(nil), etcd.ErrVersionConflict(res, 1, 2)) + require.Implements(t, (*state.ErrConflict)(nil), etcd.ErrOwnerConflict(res, "owner")) + require.Implements(t, (*state.ErrConflict)(nil), etcd.ErrPendingFinalizers(res)) + require.Implements(t, (*state.ErrConflict)(nil), etcd.ErrPhaseConflict(res, resource.PhaseRunning)) + require.Implements(t, (*state.ErrNotFound)(nil), etcd.ErrNotFound(res)) + + require.True(t, state.IsConflictError(etcd.ErrAlreadyExists(res), state.WithResourceType("a"))) + require.False(t, state.IsConflictError(etcd.ErrAlreadyExists(res), state.WithResourceType("b"))) + require.True(t, state.IsConflictError(etcd.ErrAlreadyExists(res), state.WithResourceNamespace("ns"))) +}