go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/scheduler/appengine/task/utils/tasktest/controller.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 tasktest 16 17 import ( 18 "context" 19 "errors" 20 "fmt" 21 "net/http" 22 "time" 23 24 "github.com/golang/protobuf/proto" 25 26 "go.chromium.org/luci/server/auth" 27 "go.chromium.org/luci/server/auth/realms" 28 29 "go.chromium.org/luci/scheduler/appengine/internal" 30 "go.chromium.org/luci/scheduler/appengine/task" 31 ) 32 33 // TimerSpec corresponds to single AddTimer call. 34 type TimerSpec struct { 35 Delay time.Duration 36 Name string 37 Payload []byte 38 } 39 40 // TestController implements task.Controller and can be used in unit tests. 41 type TestController struct { 42 OverrideJobID string // return value of JobID() if not "" 43 OverrideInvID int64 // return value of InvocationID() if not 0 44 OverrideRealmID string // return value of RealmID if not "" 45 46 Req task.Request // return value of Request 47 48 TaskMessage proto.Message // return value of Task 49 TaskState task.State // return value of State(), mutated in place 50 Client *http.Client // return value by GetClient() 51 Log []string // individual log lines passed to DebugLog() 52 53 SaveCallback func() error // mock for Save() 54 PrepareTopicCallback func(string) (string, string, error) // mock for PrepareTopic() 55 56 Timers []TimerSpec 57 Triggers []*internal.Trigger 58 } 59 60 // JobID is part of Controller interface. 61 func (c *TestController) JobID() string { 62 if c.OverrideJobID != "" { 63 return c.OverrideJobID 64 } 65 return "some-project/some-job" 66 } 67 68 // InvocationID is part of Controller interface. 69 func (c *TestController) InvocationID() int64 { 70 if c.OverrideInvID != 0 { 71 return c.OverrideInvID 72 } 73 return 1 74 } 75 76 // RealmID is part of Controller interface. 77 func (c *TestController) RealmID() string { 78 if c.OverrideRealmID != "" { 79 return c.OverrideRealmID 80 } 81 return realms.Join("some-project", "some-realm") 82 } 83 84 // Request is part of Controller interface. 85 func (c *TestController) Request() task.Request { 86 return c.Req 87 } 88 89 // Task is part of Controller interface. 90 func (c *TestController) Task() proto.Message { 91 return c.TaskMessage 92 } 93 94 // State is part of Controller interface. 95 func (c *TestController) State() *task.State { 96 return &c.TaskState 97 } 98 99 // AddTimer is part of Controller interface. 100 func (c *TestController) AddTimer(ctx context.Context, delay time.Duration, name string, payload []byte) { 101 c.Timers = append(c.Timers, TimerSpec{ 102 Delay: delay, 103 Name: name, 104 Payload: payload, 105 }) 106 } 107 108 // DebugLog is part of Controller interface. 109 func (c *TestController) DebugLog(format string, args ...any) { 110 c.Log = append(c.Log, fmt.Sprintf(format, args...)) 111 } 112 113 // Save is part of Controller interface. 114 func (c *TestController) Save(ctx context.Context) error { 115 if c.SaveCallback != nil { 116 return c.SaveCallback() 117 } 118 return errors.New("Save must not be called (not mocked)") 119 } 120 121 // PrepareTopic is part of Controller interface. 122 func (c *TestController) PrepareTopic(ctx context.Context, publisher string) (topic string, token string, err error) { 123 if c.PrepareTopicCallback != nil { 124 return c.PrepareTopicCallback(publisher) 125 } 126 return "", "", errors.New("PrepareTopic must not be called (not mocked)") 127 } 128 129 // GetClient is part of Controller interface. 130 func (c *TestController) GetClient(ctx context.Context, opts ...auth.RPCOption) (*http.Client, error) { 131 if c.Client != nil { 132 return c.Client, nil 133 } 134 return nil, errors.New("GetClient must not be called (not mocked)") 135 } 136 137 func (c *TestController) EmitTrigger(ctx context.Context, trigger *internal.Trigger) { 138 c.Triggers = append(c.Triggers, trigger) 139 } 140 141 var _ task.Controller = (*TestController)(nil)