go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/logdog/appengine/coordinator/endpoints/services/loadStream_test.go (about) 1 // Copyright 2015 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 services 16 17 import ( 18 "errors" 19 "testing" 20 "time" 21 22 "google.golang.org/protobuf/proto" 23 "google.golang.org/protobuf/types/known/durationpb" 24 25 "go.chromium.org/luci/gae/filter/featureBreaker" 26 logdog "go.chromium.org/luci/logdog/api/endpoints/coordinator/services/v1" 27 "go.chromium.org/luci/logdog/appengine/coordinator" 28 ct "go.chromium.org/luci/logdog/appengine/coordinator/coordinatorTest" 29 30 . "github.com/smartystreets/goconvey/convey" 31 32 . "go.chromium.org/luci/common/testing/assertions" 33 ) 34 35 func TestLoadStream(t *testing.T) { 36 t.Parallel() 37 38 Convey(`With a testing configuration`, t, func() { 39 c, env := ct.Install() 40 41 svr := New(ServerSettings{NumQueues: 2}) 42 43 // Register a test stream. 44 env.AddProject(c, "proj-foo") 45 tls := ct.MakeStream(c, "proj-foo", "some-realm", "testing/+/foo/bar") 46 if err := tls.Put(c); err != nil { 47 panic(err) 48 } 49 50 // Prepare a request to load the test stream. 51 req := &logdog.LoadStreamRequest{ 52 Project: string(tls.Project), 53 Id: string(tls.Stream.ID), 54 } 55 56 Convey(`Returns Forbidden error if not a service.`, func() { 57 _, err := svr.LoadStream(c, &logdog.LoadStreamRequest{}) 58 So(err, ShouldBeRPCPermissionDenied) 59 }) 60 61 Convey(`When logged in as a service`, func() { 62 env.ActAsService() 63 64 Convey(`Will succeed.`, func() { 65 resp, err := svr.LoadStream(c, req) 66 So(err, ShouldBeNil) 67 So(resp, ShouldResembleProto, &logdog.LoadStreamResponse{ 68 State: &logdog.InternalLogStreamState{ 69 ProtoVersion: "1", 70 TerminalIndex: -1, 71 Secret: tls.State.Secret, 72 }, 73 Age: durationpb.New(0), 74 }) 75 }) 76 77 Convey(`Will return archival properties.`, func() { 78 // Add an hour to the clock. Created is +0, Updated is +1hr. 79 env.Clock.Add(1 * time.Hour) 80 tls.State.ArchivalKey = []byte("archival key") 81 tls.Reload(c) 82 if err := tls.Put(c); err != nil { 83 panic(err) 84 } 85 86 // Set time to +2hr, age should now be 1hr. 87 env.Clock.Add(1 * time.Hour) 88 resp, err := svr.LoadStream(c, req) 89 So(err, ShouldBeNil) 90 So(resp, ShouldResembleProto, &logdog.LoadStreamResponse{ 91 State: &logdog.InternalLogStreamState{ 92 ProtoVersion: "1", 93 TerminalIndex: -1, 94 Secret: tls.State.Secret, 95 }, 96 ArchivalKey: []byte("archival key"), 97 Age: durationpb.New(1 * time.Hour), 98 }) 99 }) 100 101 Convey(`Will succeed, and return the descriptor when requested.`, func() { 102 req.Desc = true 103 104 d, err := proto.Marshal(tls.Desc) 105 if err != nil { 106 panic(err) 107 } 108 109 resp, err := svr.LoadStream(c, req) 110 So(err, ShouldBeNil) 111 So(resp, ShouldResembleProto, &logdog.LoadStreamResponse{ 112 State: &logdog.InternalLogStreamState{ 113 ProtoVersion: "1", 114 TerminalIndex: -1, 115 Secret: tls.State.Secret, 116 }, 117 Desc: d, 118 Age: durationpb.New(0), 119 }) 120 }) 121 122 Convey(`Will return InvalidArgument if the stream hash is not valid.`, func() { 123 req.Id = string("!!! not a hash !!!") 124 125 _, err := svr.LoadStream(c, req) 126 So(err, ShouldBeRPCInvalidArgument, "Invalid ID") 127 }) 128 129 Convey(`Will return NotFound for non-existent streams.`, func() { 130 req.Id = string(coordinator.LogStreamID("this/stream/+/does/not/exist")) 131 132 _, err := svr.LoadStream(c, req) 133 So(err, ShouldBeRPCNotFound) 134 }) 135 136 Convey(`Will return Internal for random datastore failures.`, func() { 137 c, fb := featureBreaker.FilterRDS(c, nil) 138 fb.BreakFeatures(errors.New("test error"), "GetMulti") 139 140 _, err := svr.LoadStream(c, req) 141 So(err, ShouldBeRPCInternal) 142 }) 143 }) 144 }) 145 }