blob: bd745cc9bfb2c5699ce0ab968107347375563b94 [file] [log] [blame]
// Copyright 2015 The LUCI Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package deps
import (
"testing"
dm "go.chromium.org/luci/dm/api/service/v1"
"go.chromium.org/luci/dm/appengine/distributor/fake"
"go.chromium.org/luci/dm/appengine/model"
ds "go.chromium.org/luci/gae/service/datastore"
. "github.com/smartystreets/goconvey/convey"
. "go.chromium.org/luci/common/testing/assertions"
)
func TestAddDeps(t *testing.T) {
t.Parallel()
Convey("EnsureGraphData (Adding deps)", t, func() {
ttest, c, dist, s := testSetup()
c = writer(c)
qid := s.ensureQuest(c, "quest", 1)
Convey("Bad", func() {
req := &dm.EnsureGraphDataReq{
RawAttempts: dm.NewAttemptList(map[string][]uint32{
"fakeQuestId": {1},
}),
}
Convey("No such originating attempt", func() {
dist.RunTask(c, dm.NewExecutionID(qid, 1, 1), func(tsk *fake.Task) error {
aTsk := tsk.MustActivate(c, s)
_, err := aTsk.EnsureGraphData(req)
So(err, ShouldBeRPCInvalidArgument, `cannot create attempts for absent quest "-asJkTOx8ORdkGZsg7Bc-w2Z_0FIB4vgD1afzInkwNE"`)
return nil
})
})
})
toQuest := s.ensureQuest(c, "to", 1)
toQuestDesc := fake.QuestDesc("to")
req := &dm.EnsureGraphDataReq{
RawAttempts: dm.NewAttemptList(map[string][]uint32{
toQuest: {1},
}),
}
fwd := model.FwdDepsFromList(c,
dm.NewAttemptID(qid, 1),
dm.NewAttemptList(map[string][]uint32{toQuest: {1}}),
)[0]
ttest.Drain(c)
Convey("Good", func() {
Convey("deps already exist", func() {
err := dist.RunTask(c, dm.NewExecutionID(qid, 1, 1), func(tsk *fake.Task) error {
aTsk := tsk.MustActivate(c, s)
rsp, err := aTsk.EnsureGraphData(req)
So(err, ShouldBeNil)
rsp.Result.PurgeTimestamps()
So(rsp, ShouldResemble, &dm.EnsureGraphDataRsp{
Accepted: true,
ShouldHalt: true,
})
return nil
})
So(err, ShouldBeNil)
})
Convey("deps already done", func() {
err := dist.RunTask(c, dm.NewExecutionID(toQuest, 1, 1), func(tsk *fake.Task) error {
tsk.MustActivate(c, s).Finish(`{"done":true}`)
return nil
})
So(err, ShouldBeNil)
ttest.Drain(c)
err = dist.RunTask(c, dm.NewExecutionID(qid, 1, 1), func(tsk *fake.Task) error {
aTsk := tsk.MustActivate(c, s)
req.Normalize() // to ensure the next assignment works
req.Include.Attempt.Result = true
rsp, err := aTsk.EnsureGraphData(req)
So(err, ShouldBeNil)
rsp.Result.PurgeTimestamps()
exAttempt := dm.NewAttemptFinished(dm.NewJsonResult(`{"done":true}`))
exAttempt.Data.NumExecutions = 1
So(rsp, ShouldResembleProto, &dm.EnsureGraphDataRsp{
Accepted: true,
Result: &dm.GraphData{Quests: map[string]*dm.Quest{
toQuest: {
Data: &dm.Quest_Data{
Desc: toQuestDesc,
BuiltBy: []*dm.Quest_TemplateSpec{},
},
Attempts: map[uint32]*dm.Attempt{1: exAttempt},
},
}},
})
return nil
})
So(err, ShouldBeNil)
ttest.Drain(c)
So(ds.Get(c, fwd), ShouldBeNil)
})
Convey("adding new deps", func() {
err := dist.RunTask(c, dm.NewExecutionID(qid, 1, 1), func(tsk *fake.Task) error {
aTsk := tsk.MustActivate(c, s)
rsp, err := aTsk.EnsureGraphData(req)
So(err, ShouldBeNil)
So(rsp, ShouldResemble, &dm.EnsureGraphDataRsp{
Accepted: true,
ShouldHalt: true,
})
So(ds.Get(c, fwd), ShouldBeNil)
a := model.AttemptFromID(dm.NewAttemptID(qid, 1))
So(ds.Get(c, a), ShouldBeNil)
So(a.State, ShouldEqual, dm.Attempt_EXECUTING)
e := model.ExecutionFromID(c, dm.NewExecutionID(qid, 1, 1))
So(ds.Get(c, e), ShouldBeNil)
So(e.State, ShouldEqual, dm.Execution_STOPPING)
return nil
})
So(err, ShouldBeNil)
})
})
})
}