go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/milo/internal/utils/utils_test.go (about) 1 // Copyright 2019 The LUCI Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package utils 16 17 import ( 18 "context" 19 "testing" 20 21 "go.chromium.org/luci/auth/identity" 22 buildbucketpb "go.chromium.org/luci/buildbucket/proto" 23 "go.chromium.org/luci/common/errors" 24 "go.chromium.org/luci/gae/impl/memory" 25 "go.chromium.org/luci/grpc/grpcutil" 26 "go.chromium.org/luci/server/auth" 27 "go.chromium.org/luci/server/auth/authtest" 28 "google.golang.org/grpc/codes" 29 "google.golang.org/grpc/status" 30 31 . "github.com/smartystreets/goconvey/convey" 32 ) 33 34 type TestStruct struct { 35 Prop string 36 } 37 38 func TestTagGRPC(t *testing.T) { 39 t.Parallel() 40 41 Convey("GRPC tagging works", t, func() { 42 c := memory.Use(context.Background()) 43 cUser := auth.WithState(c, &authtest.FakeState{Identity: "user:user@example.com"}) 44 cAnon := auth.WithState(c, &authtest.FakeState{Identity: identity.AnonymousIdentity}) 45 46 Convey("For not found errors", func() { 47 errGRPCNotFound := status.Errorf(codes.NotFound, "not found") 48 So(grpcutil.Code(TagGRPC(cAnon, errGRPCNotFound)), ShouldEqual, codes.Unauthenticated) 49 So(grpcutil.Code(TagGRPC(cUser, errGRPCNotFound)), ShouldEqual, codes.NotFound) 50 }) 51 52 Convey("For permission denied errors", func() { 53 errGRPCPermissionDenied := status.Errorf(codes.PermissionDenied, "permission denied") 54 So(grpcutil.Code(TagGRPC(cAnon, errGRPCPermissionDenied)), ShouldEqual, codes.Unauthenticated) 55 So(grpcutil.Code(TagGRPC(cUser, errGRPCPermissionDenied)), ShouldEqual, codes.NotFound) 56 }) 57 58 Convey("For invalid argument errors", func() { 59 errGRPCInvalidArgument := status.Errorf(codes.InvalidArgument, "invalid argument") 60 So(grpcutil.Code(TagGRPC(cAnon, errGRPCInvalidArgument)), ShouldEqual, codes.InvalidArgument) 61 So(grpcutil.Code(TagGRPC(cUser, errGRPCInvalidArgument)), ShouldEqual, codes.InvalidArgument) 62 }) 63 64 Convey("For invalid argument multi-errors", func() { 65 errGRPCInvalidArgument := status.Errorf(codes.InvalidArgument, "invalid argument") 66 errMulti := errors.NewMultiError(errGRPCInvalidArgument) 67 So(grpcutil.Code(TagGRPC(cAnon, errMulti)), ShouldEqual, codes.InvalidArgument) 68 So(grpcutil.Code(TagGRPC(cUser, errMulti)), ShouldEqual, codes.InvalidArgument) 69 }) 70 }) 71 72 Convey("ParseLegacyBuilderID", t, func() { 73 Convey("For valid ID", func() { 74 builderID, err := ParseLegacyBuilderID("buildbucket/luci.test project.test bucket/test builder") 75 So(err, ShouldBeNil) 76 So(builderID, ShouldResemble, &buildbucketpb.BuilderID{ 77 Project: "test project", 78 Bucket: "test bucket", 79 Builder: "test builder", 80 }) 81 }) 82 83 Convey("Allow '.' in builder ID", func() { 84 builderID, err := ParseLegacyBuilderID("buildbucket/luci.test project.test bucket/test.builder") 85 So(err, ShouldBeNil) 86 So(builderID, ShouldResemble, &buildbucketpb.BuilderID{ 87 Project: "test project", 88 Bucket: "test bucket", 89 Builder: "test.builder", 90 }) 91 }) 92 93 Convey("Allow '.' in bucket ID", func() { 94 builderID, err := ParseLegacyBuilderID("buildbucket/luci.test project.test.bucket/test builder") 95 So(err, ShouldBeNil) 96 So(builderID, ShouldResemble, &buildbucketpb.BuilderID{ 97 Project: "test project", 98 Bucket: "test.bucket", 99 Builder: "test builder", 100 }) 101 }) 102 103 Convey("For invalid ID", func() { 104 builderID, err := ParseLegacyBuilderID("buildbucket/123456") 105 So(err, ShouldEqual, ErrInvalidLegacyBuilderID) 106 So(builderID, ShouldBeNil) 107 }) 108 }) 109 110 Convey("ParseBuilderID", t, func() { 111 Convey("For valid ID", func() { 112 builderID, err := ParseBuilderID("test project/test bucket/test builder") 113 So(builderID, ShouldResemble, &buildbucketpb.BuilderID{ 114 Project: "test project", 115 Bucket: "test bucket", 116 Builder: "test builder", 117 }) 118 So(err, ShouldBeNil) 119 }) 120 121 Convey("For invalid ID", func() { 122 builderID, err := ParseBuilderID("test project/123456") 123 So(builderID, ShouldBeNil) 124 So(err, ShouldEqual, ErrInvalidBuilderID) 125 }) 126 }) 127 128 Convey("ParseBuildbucketBuildID", t, func() { 129 Convey("For valid build ID", func() { 130 bid, err := ParseBuildbucketBuildID("buildbucket/123456") 131 So(err, ShouldBeNil) 132 So(bid, ShouldEqual, 123456) 133 }) 134 135 Convey("For invalid build ID", func() { 136 bid, err := ParseBuildbucketBuildID("notbuildbucket/123456") 137 So(err, ShouldEqual, ErrInvalidLegacyBuildID) 138 So(bid, ShouldEqual, 0) 139 }) 140 }) 141 142 Convey("ParseLegacyBuildbucketBuildID", t, func() { 143 Convey("For valid build ID", func() { 144 builderID, buildNum, err := ParseLegacyBuildbucketBuildID("buildbucket/luci.test project.test bucket/test builder/123456") 145 So(err, ShouldBeNil) 146 So(builderID, ShouldResemble, &buildbucketpb.BuilderID{ 147 Project: "test project", 148 Bucket: "test bucket", 149 Builder: "test builder", 150 }) 151 So(buildNum, ShouldEqual, 123456) 152 }) 153 154 Convey("Allow '.' in builder ID", func() { 155 builderID, buildNum, err := ParseLegacyBuildbucketBuildID("buildbucket/luci.test project.test bucket/test.builder/123456") 156 So(err, ShouldBeNil) 157 So(builderID, ShouldResemble, &buildbucketpb.BuilderID{ 158 Project: "test project", 159 Bucket: "test bucket", 160 Builder: "test.builder", 161 }) 162 So(buildNum, ShouldEqual, 123456) 163 }) 164 165 Convey("Allow '.' in bucket ID", func() { 166 builderID, buildNum, err := ParseLegacyBuildbucketBuildID("buildbucket/luci.test project.test.bucket/test builder/123456") 167 So(err, ShouldBeNil) 168 So(builderID, ShouldResemble, &buildbucketpb.BuilderID{ 169 Project: "test project", 170 Bucket: "test.bucket", 171 Builder: "test builder", 172 }) 173 So(buildNum, ShouldEqual, 123456) 174 }) 175 176 Convey("For invalid build ID", func() { 177 builderID, buildNum, err := ParseLegacyBuildbucketBuildID("buildbucket/123456") 178 So(err, ShouldEqual, ErrInvalidLegacyBuildID) 179 So(builderID, ShouldBeNil) 180 So(buildNum, ShouldEqual, 0) 181 }) 182 }) 183 }