Documentation ¶
Index ¶
- Constants
- func InfoURL(e *dm.Execution_ID) string
- func MakeToken(eid *dm.Execution_ID) distributor.Token
- func QuestDesc(name string) *dm.Quest_Desc
- func WalkShouldReturn(c context.Context, s dm.DepsServer, keepTimestamps ...bool) func(request interface{}, expect ...interface{}) string
- type ActivatedTask
- func (t *ActivatedTask) DepOn(to ...*dm.Attempt_ID) (bool, error)
- func (t *ActivatedTask) EnsureGraphData(req *dm.EnsureGraphDataReq) (*dm.EnsureGraphDataRsp, error)
- func (t *ActivatedTask) Finish(resultJSON string, expire ...time.Time)
- func (t *ActivatedTask) MustDepOn(to ...*dm.Attempt_ID) (halt bool)
- func (t *ActivatedTask) WalkGraph(req *dm.WalkGraphReq) (*dm.GraphData, error)
- func (t *ActivatedTask) WalkShouldReturn(request interface{}, expect ...interface{}) string
- type BoundDistributor
- func (d *BoundDistributor) Cancel(_ *dm.Quest_Desc, tok distributor.Token) (err error)
- func (d *BoundDistributor) GetStatus(_ *dm.Quest_Desc, tok distributor.Token) (rslt *dm.Result, err error)
- func (d *BoundDistributor) HandleNotification(q *dm.Quest_Desc, n *distributor.Notification) (rslt *dm.Result, err error)
- func (d *BoundDistributor) HandleTaskQueueTask(r *http.Request) ([]*distributor.Notification, error)
- func (d *BoundDistributor) InfoURL(tok distributor.Token) string
- func (d *BoundDistributor) Run(desc *dm.Quest_Desc, exAuth *dm.Execution_Auth, prev *dm.JsonResult) (tok distributor.Token, pollbackTime time.Duration, err error)
- func (d *BoundDistributor) Validate(payload string) error
- type Distributor
- type DistributorData
- type Task
Constants ¶
const FakeURLPrefix = "https://info.example.com/"
FakeURLPrefix is the url that all fake InfoURLs are prefixed with.
Variables ¶
This section is empty.
Functions ¶
func InfoURL ¶
func InfoURL(e *dm.Execution_ID) string
InfoURL builds a fake InfoURL for the given Execution_ID
func MakeToken ¶
func MakeToken(eid *dm.Execution_ID) distributor.Token
MakeToken makes a distributor Token out of an Execution_ID. In this implementation of a Distributor there's a 1:1 mapping between Execution_ID and distributor task. This is not always the case for real distributor implementations.
func QuestDesc ¶
func QuestDesc(name string) *dm.Quest_Desc
QuestDesc generates a normalized generic QuestDesc of the form:
Quest_Desc{ DistributorConfigName: "fakeDistributor", Parameters: `{"name":"$name"}`, DistributorParameters: "{}", }
func WalkShouldReturn ¶
func WalkShouldReturn(c context.Context, s dm.DepsServer, keepTimestamps ...bool) func(request interface{}, expect ...interface{}) string
WalkShouldReturn is a convey-style assertion factory to assert that a given WalkGraph request object results in the provided GraphData.
If keepTimestamps (a singular, optional boolean) is provided and true, WalkShouldReturn will not remove timestamps from the compared GraphData. If it is absent or false, GraphData.PurgeTimestamps will be called on the returned GraphData before comparing it to the expected value.
Use this function like:
req := &dm.WalkGraphReq{...} So(req, WalkShouldReturn(c, s), &dm.GraphData{ ... })
Types ¶
type ActivatedTask ¶
type ActivatedTask struct { Auth *dm.Execution_Auth Desc *dm.Quest_Desc // State is read/writable. State *dm.JsonResult // contains filtered or unexported fields }
ActivatedTask is like a Task, but exists after calling Task.MustActivate, and contains an activated authentication token. This may be used to either add new dependencies or to provide a finished result.
The implementation of DepsServer also automatically populates all outgoing RPCs with the activated Auth value.
func (*ActivatedTask) DepOn ¶
func (t *ActivatedTask) DepOn(to ...*dm.Attempt_ID) (bool, error)
DepOn is a shorthand for EnsureGraphData which allows you to depend on multiple existing quests by attempt id. The definitions for these quests must already have been added to the deps server (probably with an EnsureGraphData call).
func (*ActivatedTask) EnsureGraphData ¶
func (t *ActivatedTask) EnsureGraphData(req *dm.EnsureGraphDataReq) (*dm.EnsureGraphDataRsp, error)
EnsureGraphData calls the bound DepsServer's EnsureGraphData method with the activated Auth field in ForExecution.
func (*ActivatedTask) Finish ¶
func (t *ActivatedTask) Finish(resultJSON string, expire ...time.Time)
Finish calls FinishAttempt with the provided JSON body and optional expiration time.
This will panic if you provide more than one expiration time (so don't do that).
func (*ActivatedTask) MustDepOn ¶
func (t *ActivatedTask) MustDepOn(to ...*dm.Attempt_ID) (halt bool)
MustDepOn is the same as DepOn but will panic if DepOn would have returned a non-nil error.
func (*ActivatedTask) WalkGraph ¶
func (t *ActivatedTask) WalkGraph(req *dm.WalkGraphReq) (*dm.GraphData, error)
WalkGraph calls the bound DepsServer's WalkGraph method with the activated Auth field.
func (*ActivatedTask) WalkShouldReturn ¶
func (t *ActivatedTask) WalkShouldReturn(request interface{}, expect ...interface{}) string
WalkShouldReturn is a shorthand for the package-level WalkShouldReturn which binds the activated auth to the WalkGraph request, but otherwise behaves identically.
Use this method like:
req := &dm.WalkGraphReq{...} So(req, activated.WalkShouldReturn, &dm.GraphData{ ... })
type BoundDistributor ¶
type BoundDistributor struct { *Distributor // contains filtered or unexported fields }
BoundDistributor binds the fake.Distributor to a Context and a distributor.Config. It implements distributor.D.
func (*BoundDistributor) Cancel ¶
func (d *BoundDistributor) Cancel(_ *dm.Quest_Desc, tok distributor.Token) (err error)
Cancel implements distributor.D
func (*BoundDistributor) GetStatus ¶
func (d *BoundDistributor) GetStatus(_ *dm.Quest_Desc, tok distributor.Token) (rslt *dm.Result, err error)
GetStatus implements distributor.D
func (*BoundDistributor) HandleNotification ¶
func (d *BoundDistributor) HandleNotification(q *dm.Quest_Desc, n *distributor.Notification) (rslt *dm.Result, err error)
HandleNotification implements distributor.D
func (*BoundDistributor) HandleTaskQueueTask ¶
func (d *BoundDistributor) HandleTaskQueueTask(r *http.Request) ([]*distributor.Notification, error)
HandleTaskQueueTask is not implemented, and shouldn't be needed for most tests. It could be implemented if some new test required it, however.
func (*BoundDistributor) InfoURL ¶
func (d *BoundDistributor) InfoURL(tok distributor.Token) string
InfoURL implements distributor.D
func (*BoundDistributor) Run ¶
func (d *BoundDistributor) Run(desc *dm.Quest_Desc, exAuth *dm.Execution_Auth, prev *dm.JsonResult) (tok distributor.Token, pollbackTime time.Duration, err error)
Run implements distributor.D
func (*BoundDistributor) Validate ¶
func (d *BoundDistributor) Validate(payload string) error
Validate implements distributor.D (by returning a nil error for every payload).
type Distributor ¶
type Distributor struct { // RunError can be set to make Run return this error when it's invoked. RunError error // This can be set to turn the distributor into a polling-based distributor. PollbackTime time.Duration sync.Mutex // contains filtered or unexported fields }
Distributor implements distributor.D, and provides a method (RunTask) to allow a test to actually run a task which has been scheduled on this Distributor, and correctly notify the deps server that the execution is complete.
func Setup ¶
func Setup(fn distributor.FinishExecutionFn) (ttest *tumble.Testing, c context.Context, dist *Distributor)
Setup creates a new combination of testing and context objects:
- ttest - a tumble.Testing to allow you to control tumble's processing state
- c - a context which includes a testing distributor registry, testsecrets, as well as everything that tumble.Testing.Context adds (datastore, memcache, etc.)
- dist - a fake Distributor implementation with a RunTask method that allows your test to 'run' a scheduled task with the Distributor. This will automatically notify the deps service (by calling `fn`).
You should pass mutate.FinishExecutionFn for fn. It's not done automatically in order to break an import cycle. You could provide your own, but YMMV.
This sets the following configuration using the memory configuration mock:
services/app/acls.cfg: readers: "reader_group" writers: "writer_group"
Usage:
ttest, c, dist := fake.Setup(mutate.FinishExecutionFn) s := deps.NewDecoratedServer() # your tests
func (*Distributor) RunTask ¶
func (d *Distributor) RunTask(c context.Context, eid *dm.Execution_ID, cb func(*Task) error) (err error)
RunTask allows you to run the task associated with the provided execution id.
If the task corresponding to `eid` returns an error, or if the distributor itself actually has an error, this method will return an error. Notably, if `cb` returns an error, it will simply mark the corresponding task as FAILED, but will return nil here.
If the task exists and hasn't been run yet, cb will be called, and can do anything that you may want to a test to do. Think of the callback as the recipe engine; it has the opportunity to do anything it wants to, interact with the deps server (or not), succeed (or not), etc.
If the callback needs to maintain state between executions, Task.State is read+write; when the callback exits, the final value of Task.State will be passed back to the DM instance under test. A re-execution of the attempt will start with the new value.
type DistributorData ¶
type DistributorData struct { NotifyTopic pubsub.Topic NotifyAuth string Auth *dm.Execution_Auth Desc *dm.Quest_Desc State *dm.JsonResult // contains filtered or unexported fields }
DistributorData is the blob of data that the fake.Distributor keeps when DM calls its Run method. This is roughly equivalent to the state that a distributor (like swarming) would store in its own datastore about a job.
type Task ¶
type Task struct { Auth *dm.Execution_Auth Desc *dm.Quest_Desc // State is read/writable. State *dm.JsonResult }
Task is the detail that the distributor task would get. This is roughly equivalent to the input that the swarming task/recipe engine would get.
func (*Task) Activate ¶
func (t *Task) Activate(c context.Context, s dm.DepsServer) (*ActivatedTask, error)
Activate does the activation handshake with the provided DepsServer and returns an ActivatedTask.
func (*Task) MustActivate ¶
func (t *Task) MustActivate(c context.Context, s dm.DepsServer) *ActivatedTask
MustActivate does the same thing as Activate, but panics if err != nil.