blob: d006142391ef8e0fc9cf0c147e8268a28905d7c6 [file] [log] [blame]
package scheduling
import (
"fmt"
"testing"
"time"
"github.com/stretchr/testify/require"
"go.skia.org/infra/go/deepequal/assertdeep"
"go.skia.org/infra/go/testutils/unittest"
"go.skia.org/infra/task_scheduler/go/specs"
"go.skia.org/infra/task_scheduler/go/types"
)
func fullTaskCandidate() *taskCandidate {
return &taskCandidate{
Attempt: 3,
BuildbucketBuildId: 8888,
Commits: []string{"a", "b"},
Diagnostics: &taskCandidateDiagnostics{},
CasInput: "lonely-parameter",
CasDigests: []string{"browns"},
CasUsesIsolate: true,
Jobs: []*types.Job{{
Id: "dummy",
}},
ParentTaskIds: []string{"38", "39", "40"},
RetryOf: "41",
Score: 99,
StealingFromId: "rich",
TaskKey: types.TaskKey{
RepoState: types.RepoState{
Repo: "nou.git",
Revision: "1",
},
Name: "Build",
},
TaskSpec: &specs.TaskSpec{
Isolate: "confine",
},
}
}
func TestCopyTaskCandidate(t *testing.T) {
unittest.SmallTest(t)
v := fullTaskCandidate()
cp := v.CopyNoDiagnostics()
require.Nil(t, cp.Diagnostics)
cp.Diagnostics = &taskCandidateDiagnostics{}
assertdeep.Copy(t, v, cp)
}
func TestTaskCandidateJSON(t *testing.T) {
unittest.SmallTest(t)
v := fullTaskCandidate()
assertdeep.JSONRoundTripEqual(t, v)
}
func TestTaskCandidateId(t *testing.T) {
unittest.SmallTest(t)
t1 := makeTaskCandidate("task1", []string{"k:v"})
t1.Repo = "Myrepo"
t1.Revision = "abc123"
t1.ForcedJobId = "someID"
id1 := t1.MakeId()
k1, err := parseId(id1)
require.NoError(t, err)
require.Equal(t, t1.TaskKey, k1)
// ForcedJobId is allowed to be empty.
t1.ForcedJobId = ""
id1 = t1.MakeId()
k1, err = parseId(id1)
require.NoError(t, err)
require.Equal(t, t1.TaskKey, k1)
// Test a try job.
t1.Server = "https://my-patch.com"
t1.Issue = "10101"
t1.Patchset = "42"
id1 = t1.MakeId()
k1, err = parseId(id1)
require.NoError(t, err)
require.Equal(t, t1.TaskKey, k1)
badIds := []string{
"",
"taskCandidate|a",
"taskCandidate|a|b||ab",
"20160831T000018.497703717Z_000000000000015b",
}
for _, id := range badIds {
_, err := parseId(id)
require.Error(t, err)
}
}
func TestReplaceVar(t *testing.T) {
unittest.SmallTest(t)
c := makeTaskCandidate("c", []string{"k:v"})
c.Repo = "my-repo"
c.Revision = "abc123"
c.Name = "my-task"
dummyId := "id123"
require.Equal(t, "", replaceVars(c, "", dummyId))
require.Equal(t, "my-repo", replaceVars(c, "<(REPO)", dummyId))
require.Equal(t, "my-task", replaceVars(c, "<(TASK_NAME)", dummyId))
require.Equal(t, "abc123", replaceVars(c, "<(REVISION)", dummyId))
require.Equal(t, "<(REVISION", replaceVars(c, "<(REVISION", dummyId))
require.Equal(t, "my-repo_my-task_abc123", replaceVars(c, "<(REPO)_<(TASK_NAME)_<(REVISION)", dummyId))
require.Equal(t, dummyId, replaceVars(c, "<(TASK_ID)", dummyId))
require.Equal(t, "", replaceVars(c, "<(PATCH_REF)", dummyId))
c.Issue = "12345"
c.Patchset = "3"
c.Server = "https://server"
require.Equal(t, "refs/changes/45/12345/3", replaceVars(c, "<(PATCH_REF)", dummyId))
}
func TestTaskCandidateJobs(t *testing.T) {
unittest.SmallTest(t)
c := taskCandidate{}
now := time.Now().UTC()
j1 := &types.Job{
Created: now,
Id: "j1",
}
j2 := &types.Job{
Created: now,
Id: "j2",
}
j3 := &types.Job{
Created: now.Add(time.Second),
Id: "j3",
}
j4 := &types.Job{
Created: now.Add(2 * time.Second),
Id: "j4",
}
for _, j := range []*types.Job{j1, j2, j3, j4} {
require.False(t, c.HasJob(j))
}
c.AddJob(j3)
require.Len(t, c.Jobs, 1)
require.False(t, c.HasJob(j1))
require.False(t, c.HasJob(j2))
require.True(t, c.HasJob(j3))
require.False(t, c.HasJob(j4))
c.AddJob(j1)
require.Len(t, c.Jobs, 2)
require.True(t, c.HasJob(j1))
require.False(t, c.HasJob(j2))
require.True(t, c.HasJob(j3))
require.False(t, c.HasJob(j4))
require.Equal(t, []*types.Job{j1, j3}, c.Jobs)
c.AddJob(j4)
require.Len(t, c.Jobs, 3)
require.True(t, c.HasJob(j1))
require.False(t, c.HasJob(j2))
require.True(t, c.HasJob(j3))
require.True(t, c.HasJob(j4))
require.Equal(t, []*types.Job{j1, j3, j4}, c.Jobs)
c.AddJob(j2)
require.Len(t, c.Jobs, 4)
require.True(t, c.HasJob(j1))
require.True(t, c.HasJob(j2))
require.True(t, c.HasJob(j3))
require.True(t, c.HasJob(j4))
// Order is deterministic.
require.Equal(t, []*types.Job{j1, j2, j3, j4}, c.Jobs)
c.AddJob(j4)
require.Len(t, c.Jobs, 4)
c.AddJob(j2)
require.Len(t, c.Jobs, 4)
c.AddJob(j1)
require.Len(t, c.Jobs, 4)
for i := 5; i < 100; i++ {
c.AddJob(&types.Job{
Created: now.Add(time.Duration(i*23%7) * time.Second),
Id: fmt.Sprintf("j%d", i),
})
}
last := time.Time{}
for _, j := range c.Jobs {
require.True(t, !last.After(j.Created))
last = j.Created
}
}