diff --git a/pkg/api/unversioned/group_version.go b/pkg/api/unversioned/group_version.go index 9d29341cfcc..167002c3fc7 100644 --- a/pkg/api/unversioned/group_version.go +++ b/pkg/api/unversioned/group_version.go @@ -29,8 +29,8 @@ import ( // `resource.group.com` -> `group=com, version=group, resource=resource` and `group=group.com, resource=resource` func ParseResourceArg(arg string) (*GroupVersionResource, GroupResource) { var gvr *GroupVersionResource - s := strings.SplitN(arg, ".", 3) - if len(s) == 3 { + if strings.Count(arg, ".") >= 2 { + s := strings.SplitN(arg, ".", 3) gvr = &GroupVersionResource{Group: s[2], Version: s[1], Resource: s[0]} } @@ -64,12 +64,11 @@ func (gr *GroupResource) String() string { // ParseGroupResource turns "resource.group" string into a GroupResource struct. Empty strings are allowed // for each field. func ParseGroupResource(gr string) GroupResource { - s := strings.SplitN(gr, ".", 2) - if len(s) == 1 { - return GroupResource{Resource: s[0]} + if i := strings.Index(gr, "."); i == -1 { + return GroupResource{Resource: gr} + } else { + return GroupResource{Group: gr[i+1:], Resource: gr[:i]} } - - return GroupResource{Group: s[1], Resource: s[0]} } // GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion @@ -189,18 +188,14 @@ func ParseGroupVersion(gv string) (GroupVersion, error) { return GroupVersion{}, nil } - s := strings.Split(gv, "/") - // "v1" is the only special case. Otherwise GroupVersion is expected to contain - // one "/" dividing the string into two parts. - switch { - case len(s) == 1 && gv == "v1": - return GroupVersion{"", "v1"}, nil - case len(s) == 1: - return GroupVersion{"", s[0]}, nil - case len(s) == 2: - return GroupVersion{s[0], s[1]}, nil + switch strings.Count(gv, "/") { + case 0: + return GroupVersion{"", gv}, nil + case 1: + i := strings.Index(gv, "/") + return GroupVersion{gv[:i], gv[i+1:]}, nil default: - return GroupVersion{}, fmt.Errorf("Unexpected GroupVersion string: %v", gv) + return GroupVersion{}, fmt.Errorf("unexpected GroupVersion string: %v", gv) } } diff --git a/pkg/api/unversioned/group_version_test.go b/pkg/api/unversioned/group_version_test.go index 4a26fbb106a..d2934fdf9bc 100644 --- a/pkg/api/unversioned/group_version_test.go +++ b/pkg/api/unversioned/group_version_test.go @@ -24,6 +24,77 @@ import ( "github.com/ugorji/go/codec" ) +func TestGroupVersionParse(t *testing.T) { + tests := []struct { + input string + out GroupVersion + err func(error) bool + }{ + {input: "v1", out: GroupVersion{Version: "v1"}}, + {input: "v2", out: GroupVersion{Version: "v2"}}, + {input: "/v1", out: GroupVersion{Version: "v1"}}, + {input: "v1/", out: GroupVersion{Group: "v1"}}, + {input: "/v1/", err: func(err error) bool { return err.Error() == "unexpected GroupVersion string: /v1/" }}, + {input: "v1/a", out: GroupVersion{Group: "v1", Version: "a"}}, + } + for i, test := range tests { + out, err := ParseGroupVersion(test.input) + if test.err == nil && err != nil || err == nil && test.err != nil { + t.Errorf("%d: unexpected error: %v", i, err) + continue + } + if test.err != nil && !test.err(err) { + t.Errorf("%d: unexpected error: %v", i, err) + continue + } + if out != test.out { + t.Errorf("%d: unexpected output: %#v", i, out) + } + } +} + +func TestGroupResourceParse(t *testing.T) { + tests := []struct { + input string + out GroupResource + }{ + {input: "v1", out: GroupResource{Resource: "v1"}}, + {input: ".v1", out: GroupResource{Group: "v1"}}, + {input: "v1.", out: GroupResource{Resource: "v1"}}, + {input: "v1.a", out: GroupResource{Group: "a", Resource: "v1"}}, + {input: "b.v1.a", out: GroupResource{Group: "v1.a", Resource: "b"}}, + } + for i, test := range tests { + out := ParseGroupResource(test.input) + if out != test.out { + t.Errorf("%d: unexpected output: %#v", i, out) + } + } +} + +func TestParseResourceArg(t *testing.T) { + tests := []struct { + input string + gvr *GroupVersionResource + gr GroupResource + }{ + {input: "v1", gr: GroupResource{Resource: "v1"}}, + {input: ".v1", gr: GroupResource{Group: "v1"}}, + {input: "v1.", gr: GroupResource{Resource: "v1"}}, + {input: "v1.a", gr: GroupResource{Group: "a", Resource: "v1"}}, + {input: "b.v1.a", gvr: &GroupVersionResource{Group: "a", Version: "v1", Resource: "b"}, gr: GroupResource{Group: "v1.a", Resource: "b"}}, + } + for i, test := range tests { + gvr, gr := ParseResourceArg(test.input) + if (gvr != nil && test.gvr == nil) || (gvr == nil && test.gvr != nil) || (test.gvr != nil && *gvr != *test.gvr) { + t.Errorf("%d: unexpected output: %#v", i, gvr) + } + if gr != test.gr { + t.Errorf("%d: unexpected output: %#v", i, gr) + } + } +} + type GroupVersionHolder struct { GV GroupVersion `json:"val"` }