Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(129)

Unified Diff: build_scheduler/go/db/task_test.go

Issue 2296763008: [task scheduler] Move files from build_scheduler/ to task_scheduler/ (Closed) Base URL: https://skia.googlesource.com/buildbot@master
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « build_scheduler/go/db/task.go ('k') | build_scheduler/go/db/testutil.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build_scheduler/go/db/task_test.go
diff --git a/build_scheduler/go/db/task_test.go b/build_scheduler/go/db/task_test.go
deleted file mode 100644
index abcef66c6c7861c369e0716aa771d994d8c8b934..0000000000000000000000000000000000000000
--- a/build_scheduler/go/db/task_test.go
+++ /dev/null
@@ -1,532 +0,0 @@
-package db
-
-import (
- "bytes"
- "encoding/gob"
- "fmt"
- "sort"
- "testing"
- "time"
-
- swarming_api "github.com/luci/luci-go/common/api/swarming/swarming/v1"
- assert "github.com/stretchr/testify/require"
-
- "go.skia.org/infra/go/swarming"
- "go.skia.org/infra/go/testutils"
-)
-
-// Test that Task.UpdateFromSwarming returns an error when the input data is
-// invalid.
-func TestUpdateFromSwarmingInvalid(t *testing.T) {
- now := time.Now().UTC().Round(time.Microsecond)
- task := &Task{
- Id: "A",
- Name: "A",
- Repo: "A",
- Revision: "A",
- Created: now,
- Commits: []string{"A", "B"},
- }
- copy := task.Copy()
-
- testError := func(s *swarming_api.SwarmingRpcsTaskResult, msg string) {
- changed, err := task.UpdateFromSwarming(s)
- assert.False(t, changed)
- assert.Error(t, err)
- assert.Contains(t, err.Error(), msg)
- }
-
- testError(nil, "Missing TaskResult")
-
- testError(&swarming_api.SwarmingRpcsTaskResult{
- CreatedTs: now.Format(swarming.TIMESTAMP_FORMAT),
- State: SWARMING_STATE_COMPLETED,
- Tags: []string{"invalid"},
- }, "Invalid Swarming task tag")
-
- testError(&swarming_api.SwarmingRpcsTaskResult{
- CreatedTs: "20160817T142302.543490",
- State: SWARMING_STATE_COMPLETED,
- }, "Unable to parse task creation time")
-
- testError(&swarming_api.SwarmingRpcsTaskResult{
- CreatedTs: now.Format(swarming.TIMESTAMP_FORMAT),
- State: SWARMING_STATE_COMPLETED,
- StartedTs: "20160817T142302.543490",
- }, "Unable to parse StartedTs")
-
- testError(&swarming_api.SwarmingRpcsTaskResult{
- CreatedTs: now.Format(swarming.TIMESTAMP_FORMAT),
- State: SWARMING_STATE_COMPLETED,
- CompletedTs: "20160817T142302.543490",
- }, "Unable to parse CompletedTs")
-
- testError(&swarming_api.SwarmingRpcsTaskResult{
- CreatedTs: now.Format(swarming.TIMESTAMP_FORMAT),
- State: SWARMING_STATE_EXPIRED,
- AbandonedTs: "20160817T142302.543490",
- }, "Unable to parse AbandonedTs")
-
- // Unchanged.
- testutils.AssertDeepEqual(t, task, copy)
-}
-
-// Test that Task.UpdateFromSwarming returns an error when the task "identity"
-// fields do not match.
-func TestUpdateFromSwarmingMismatched(t *testing.T) {
- now := time.Now().UTC().Round(time.Microsecond)
- task := &Task{
- Id: "A",
- Name: "A",
- Repo: "A",
- Revision: "A",
- Created: now,
- Commits: []string{"A", "B"},
- SwarmingTaskId: "A",
- }
- copy := task.Copy()
-
- testError := func(s *swarming_api.SwarmingRpcsTaskResult, msg string) {
- changed, err := task.UpdateFromSwarming(s)
- assert.False(t, changed)
- assert.Error(t, err)
- assert.Contains(t, err.Error(), msg)
- }
-
- s := &swarming_api.SwarmingRpcsTaskResult{
- TaskId: "A",
- CreatedTs: now.Format(swarming.TIMESTAMP_FORMAT),
- Failure: false,
- State: SWARMING_STATE_COMPLETED,
- Tags: []string{
- fmt.Sprintf("%s:B", SWARMING_TAG_ID),
- fmt.Sprintf("%s:A", SWARMING_TAG_NAME),
- fmt.Sprintf("%s:A", SWARMING_TAG_REPO),
- fmt.Sprintf("%s:A", SWARMING_TAG_REVISION),
- },
- }
- testError(s, "Id does not match")
-
- s.Tags[0] = fmt.Sprintf("%s:A", SWARMING_TAG_ID)
- s.Tags[1] = fmt.Sprintf("%s:B", SWARMING_TAG_NAME)
- testError(s, "Name does not match")
-
- s.Tags[1] = fmt.Sprintf("%s:A", SWARMING_TAG_NAME)
- s.Tags[2] = fmt.Sprintf("%s:B", SWARMING_TAG_REPO)
- testError(s, "Repo does not match")
-
- s.Tags[2] = fmt.Sprintf("%s:A", SWARMING_TAG_REPO)
- s.Tags[3] = fmt.Sprintf("%s:B", SWARMING_TAG_REVISION)
- testError(s, "Revision does not match")
-
- s.Tags[3] = fmt.Sprintf("%s:A", SWARMING_TAG_REVISION)
- s.CreatedTs = now.Add(time.Hour).Format(swarming.TIMESTAMP_FORMAT)
- testError(s, "Creation time has changed")
-
- s.CreatedTs = now.Format(swarming.TIMESTAMP_FORMAT)
- s.TaskId = "D"
- testError(s, "Swarming task ID does not match")
-
- // Unchanged.
- testutils.AssertDeepEqual(t, task, copy)
-}
-
-// Test that Task.UpdateFromSwarming sets the expected fields in an empty Task.
-func TestUpdateFromSwarmingInit(t *testing.T) {
- now := time.Now().UTC().Round(time.Microsecond)
- task1 := &Task{}
- s := &swarming_api.SwarmingRpcsTaskResult{
- TaskId: "E",
- // Include both AbandonedTs and CompletedTs to test that CompletedTs takes
- // precedence.
- AbandonedTs: now.Add(-1 * time.Minute).Format(swarming.TIMESTAMP_FORMAT),
- CreatedTs: now.Add(-3 * time.Hour).Format(swarming.TIMESTAMP_FORMAT),
- CompletedTs: now.Add(-2 * time.Minute).Format(swarming.TIMESTAMP_FORMAT),
- Failure: false,
- StartedTs: now.Add(-time.Hour).Format(swarming.TIMESTAMP_FORMAT),
- State: SWARMING_STATE_COMPLETED,
- Tags: []string{
- fmt.Sprintf("%s:A", SWARMING_TAG_ID),
- fmt.Sprintf("%s:B", SWARMING_TAG_NAME),
- fmt.Sprintf("%s:C", SWARMING_TAG_REPO),
- fmt.Sprintf("%s:D", SWARMING_TAG_REVISION),
- },
- OutputsRef: &swarming_api.SwarmingRpcsFilesRef{
- Isolated: "F",
- },
- }
- changed1, err1 := task1.UpdateFromSwarming(s)
- assert.NoError(t, err1)
- assert.True(t, changed1)
- testutils.AssertDeepEqual(t, task1, &Task{
- Id: "A",
- Name: "B",
- Repo: "C",
- Revision: "D",
- Created: now.Add(-3 * time.Hour),
- Commits: nil,
- Started: now.Add(-time.Hour),
- Finished: now.Add(-2 * time.Minute),
- Status: TASK_STATUS_SUCCESS,
- SwarmingTaskId: "E",
- IsolatedOutput: "F",
- })
-
- // Repeat to get Finished from AbandonedTs.
- task2 := &Task{}
- s.CompletedTs = ""
- s.State = SWARMING_STATE_EXPIRED
- changed2, err2 := task2.UpdateFromSwarming(s)
- assert.NoError(t, err2)
- assert.True(t, changed2)
- testutils.AssertDeepEqual(t, task2, &Task{
- Id: "A",
- Name: "B",
- Repo: "C",
- Revision: "D",
- Created: now.Add(-3 * time.Hour),
- Commits: nil,
- Started: now.Add(-time.Hour),
- Finished: now.Add(-time.Minute),
- Status: TASK_STATUS_MISHAP,
- SwarmingTaskId: "E",
- IsolatedOutput: "F",
- })
-}
-
-// Test that Task.UpdateFromSwarming updates the expected fields in an existing
-// Task.
-func TestUpdateFromSwarmingUpdate(t *testing.T) {
- now := time.Now().UTC().Round(time.Microsecond)
- task := &Task{
- Id: "A",
- Name: "B",
- Repo: "C",
- Revision: "D",
- Created: now.Add(-3 * time.Hour),
- Commits: []string{"D", "Z"},
- Started: now.Add(-2 * time.Hour),
- Finished: now.Add(-1 * time.Hour),
- Status: TASK_STATUS_SUCCESS,
- SwarmingTaskId: "E",
- IsolatedOutput: "F",
- }
- s := &swarming_api.SwarmingRpcsTaskResult{
- TaskId: "E",
- // Include both AbandonedTs and CompletedTs to test that CompletedTs takes
- // precedence.
- AbandonedTs: now.Add(-90 * time.Second).Format(swarming.TIMESTAMP_FORMAT),
- CreatedTs: now.Add(-3 * time.Hour).Format(swarming.TIMESTAMP_FORMAT),
- CompletedTs: now.Add(-1 * time.Minute).Format(swarming.TIMESTAMP_FORMAT),
- Failure: true,
- StartedTs: now.Add(-2 * time.Minute).Format(swarming.TIMESTAMP_FORMAT),
- State: SWARMING_STATE_COMPLETED,
- Tags: []string{
- fmt.Sprintf("%s:A", SWARMING_TAG_ID),
- fmt.Sprintf("%s:B", SWARMING_TAG_NAME),
- fmt.Sprintf("%s:C", SWARMING_TAG_REPO),
- fmt.Sprintf("%s:D", SWARMING_TAG_REVISION),
- },
- OutputsRef: &swarming_api.SwarmingRpcsFilesRef{
- Isolated: "G",
- },
- }
- changed, err := task.UpdateFromSwarming(s)
- assert.NoError(t, err)
- assert.True(t, changed)
- testutils.AssertDeepEqual(t, task, &Task{
- Id: "A",
- Name: "B",
- Repo: "C",
- Revision: "D",
- Created: now.Add(-3 * time.Hour),
- Commits: []string{"D", "Z"},
- Started: now.Add(-2 * time.Minute),
- Finished: now.Add(-1 * time.Minute),
- Status: TASK_STATUS_FAILURE,
- SwarmingTaskId: "E",
- IsolatedOutput: "G",
- })
-
- // Make an unrelated change, no change to Task.
- s.ModifiedTs = now.Format(swarming.TIMESTAMP_FORMAT)
- changed, err = task.UpdateFromSwarming(s)
- assert.NoError(t, err)
- assert.False(t, changed)
- testutils.AssertDeepEqual(t, task, &Task{
- Id: "A",
- Name: "B",
- Repo: "C",
- Revision: "D",
- Created: now.Add(-3 * time.Hour),
- Commits: []string{"D", "Z"},
- Started: now.Add(-2 * time.Minute),
- Finished: now.Add(-1 * time.Minute),
- Status: TASK_STATUS_FAILURE,
- SwarmingTaskId: "E",
- IsolatedOutput: "G",
- })
-
- // Modify so that we get Finished from AbandonedTs.
- s.CompletedTs = ""
- s.State = SWARMING_STATE_EXPIRED
- changed, err = task.UpdateFromSwarming(s)
- assert.NoError(t, err)
- assert.True(t, changed)
- testutils.AssertDeepEqual(t, task, &Task{
- Id: "A",
- Name: "B",
- Repo: "C",
- Revision: "D",
- Created: now.Add(-3 * time.Hour),
- Commits: []string{"D", "Z"},
- Started: now.Add(-2 * time.Minute),
- Finished: now.Add(-90 * time.Second),
- Status: TASK_STATUS_MISHAP,
- SwarmingTaskId: "E",
- IsolatedOutput: "G",
- })
-}
-
-// Test that Task.UpdateFromSwarming updates the Status field correctly.
-func TestUpdateFromSwarmingUpdateStatus(t *testing.T) {
- now := time.Now().UTC().Round(time.Microsecond)
-
- testUpdateStatus := func(s *swarming_api.SwarmingRpcsTaskResult, newStatus TaskStatus) {
- task := &Task{
- Id: "A",
- Name: "B",
- Repo: "C",
- Revision: "D",
- Created: now.Add(-3 * time.Hour),
- Commits: []string{"D", "Z"},
- Status: TASK_STATUS_SUCCESS,
- SwarmingTaskId: "E",
- }
- changed, err := task.UpdateFromSwarming(s)
- assert.NoError(t, err)
- assert.True(t, changed)
- testutils.AssertDeepEqual(t, task, &Task{
- Id: "A",
- Name: "B",
- Repo: "C",
- Revision: "D",
- Created: now.Add(-3 * time.Hour),
- Commits: []string{"D", "Z"},
- Status: newStatus,
- SwarmingTaskId: "E",
- })
- }
-
- s := &swarming_api.SwarmingRpcsTaskResult{
- TaskId: "E",
- CreatedTs: now.Add(-3 * time.Hour).Format(swarming.TIMESTAMP_FORMAT),
- Failure: false,
- State: SWARMING_STATE_PENDING,
- Tags: []string{
- fmt.Sprintf("%s:A", SWARMING_TAG_ID),
- fmt.Sprintf("%s:B", SWARMING_TAG_NAME),
- fmt.Sprintf("%s:C", SWARMING_TAG_REPO),
- fmt.Sprintf("%s:D", SWARMING_TAG_REVISION),
- },
- OutputsRef: nil,
- }
-
- testUpdateStatus(s, TASK_STATUS_PENDING)
-
- s.State = SWARMING_STATE_RUNNING
- testUpdateStatus(s, TASK_STATUS_RUNNING)
-
- for _, state := range []string{SWARMING_STATE_BOT_DIED, SWARMING_STATE_CANCELED, SWARMING_STATE_EXPIRED, SWARMING_STATE_TIMED_OUT} {
- s.State = state
- testUpdateStatus(s, TASK_STATUS_MISHAP)
- }
-
- s.State = SWARMING_STATE_COMPLETED
- s.Failure = true
- testUpdateStatus(s, TASK_STATUS_FAILURE)
-}
-
-func TestUpdateDBFromSwarmingTask(t *testing.T) {
- db := NewInMemoryDB()
- defer testutils.AssertCloses(t, db)
-
- // Create task, initialize from swarming, and save.
- now := time.Now().UTC().Round(time.Microsecond)
- task := &Task{
- Name: "B",
- Repo: "C",
- Revision: "D",
- Commits: []string{"D", "Z"},
- Status: TASK_STATUS_PENDING,
- }
- assert.NoError(t, db.AssignId(task))
-
- s := &swarming_api.SwarmingRpcsTaskResult{
- TaskId: "E", // This is the Swarming TaskId.
- CreatedTs: now.Add(time.Second).Format(swarming.TIMESTAMP_FORMAT),
- State: SWARMING_STATE_PENDING,
- Tags: []string{
- fmt.Sprintf("%s:%s", SWARMING_TAG_ID, task.Id),
- fmt.Sprintf("%s:B", SWARMING_TAG_NAME),
- fmt.Sprintf("%s:C", SWARMING_TAG_REPO),
- fmt.Sprintf("%s:D", SWARMING_TAG_REVISION),
- },
- }
- modified, err := task.UpdateFromSwarming(s)
- assert.NoError(t, err)
- assert.True(t, modified)
- assert.NoError(t, db.PutTask(task))
-
- // Get update from Swarming.
- s.StartedTs = now.Add(time.Minute).Format(swarming.TIMESTAMP_FORMAT)
- s.CompletedTs = now.Add(2 * time.Minute).Format(swarming.TIMESTAMP_FORMAT)
- s.State = SWARMING_STATE_COMPLETED
- s.Failure = true
- s.OutputsRef = &swarming_api.SwarmingRpcsFilesRef{
- Isolated: "G",
- }
-
- assert.NoError(t, UpdateDBFromSwarmingTask(db, s))
-
- updatedTask, err := db.GetTaskById(task.Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, updatedTask, &Task{
- Id: task.Id,
- Name: "B",
- Repo: "C",
- Revision: "D",
- Created: now.Add(time.Second),
- Commits: []string{"D", "Z"},
- Started: now.Add(time.Minute),
- Finished: now.Add(2 * time.Minute),
- Status: TASK_STATUS_FAILURE,
- SwarmingTaskId: "E",
- IsolatedOutput: "G",
- // Use value from updatedTask so they are deep-equal.
- DbModified: updatedTask.DbModified,
- })
-
- lastDbModified := updatedTask.DbModified
-
- // Make an unrelated change; assert no change to Task.
- s.ModifiedTs = now.Format(swarming.TIMESTAMP_FORMAT)
-
- assert.NoError(t, UpdateDBFromSwarmingTask(db, s))
- updatedTask, err = db.GetTaskById(task.Id)
- assert.NoError(t, err)
- assert.True(t, lastDbModified.Equal(updatedTask.DbModified))
-}
-
-// Test that sort.Sort(TaskSlice(...)) works correctly.
-func TestSort(t *testing.T) {
- tasks := []*Task{}
- addTask := func(ts time.Time) {
- task := &Task{
- Created: ts,
- }
- tasks = append(tasks, task)
- }
-
- // Add tasks with various creation timestamps.
- addTask(time.Date(2008, time.August, 8, 8, 8, 8, 8, time.UTC)) // 0
- addTask(time.Date(1776, time.July, 4, 13, 0, 0, 0, time.UTC)) // 1
- addTask(time.Date(2016, time.December, 31, 23, 59, 59, 999999999, time.UTC)) // 2
- addTask(time.Date(2000, time.January, 1, 0, 0, 0, 0, time.UTC)) // 3
-
- // Manually sort.
- expected := []*Task{tasks[1], tasks[3], tasks[0], tasks[2]}
-
- sort.Sort(TaskSlice(tasks))
-
- testutils.AssertDeepEqual(t, expected, tasks)
-}
-
-func TestTaskEncoder(t *testing.T) {
- // TODO(benjaminwagner): Is there any way to cause an error?
- e := TaskEncoder{}
- expectedTasks := map[*Task][]byte{}
- for i := 0; i < 25; i++ {
- task := &Task{}
- task.Id = fmt.Sprintf("Id-%d", i)
- task.Name = "Bingo-was-his-name-o"
- task.Commits = []string{fmt.Sprintf("a%d", i), fmt.Sprintf("b%d", i+1)}
- var buf bytes.Buffer
- err := gob.NewEncoder(&buf).Encode(task)
- assert.NoError(t, err)
- expectedTasks[task] = buf.Bytes()
- assert.True(t, e.Process(task))
- }
-
- actualTasks := map[*Task][]byte{}
- for task, serialized, err := e.Next(); task != nil; task, serialized, err = e.Next() {
- assert.NoError(t, err)
- actualTasks[task] = serialized
- }
- testutils.AssertDeepEqual(t, expectedTasks, actualTasks)
-}
-
-func TestTaskEncoderNoTasks(t *testing.T) {
- e := TaskEncoder{}
- task, serialized, err := e.Next()
- assert.NoError(t, err)
- assert.Nil(t, task)
- assert.Nil(t, serialized)
-}
-
-func TestTaskDecoder(t *testing.T) {
- d := TaskDecoder{}
- expectedTasks := map[string]*Task{}
- for i := 0; i < 250; i++ {
- task := &Task{}
- task.Id = fmt.Sprintf("Id-%d", i)
- task.Name = "Bingo-was-his-name-o"
- task.Commits = []string{fmt.Sprintf("a%d", i), fmt.Sprintf("b%d", i+1)}
- var buf bytes.Buffer
- err := gob.NewEncoder(&buf).Encode(task)
- assert.NoError(t, err)
- expectedTasks[task.Id] = task
- assert.True(t, d.Process(buf.Bytes()))
- }
-
- actualTasks := map[string]*Task{}
- result, err := d.Result()
- assert.NoError(t, err)
- assert.Equal(t, len(expectedTasks), len(result))
- for _, task := range result {
- actualTasks[task.Id] = task
- }
- testutils.AssertDeepEqual(t, expectedTasks, actualTasks)
-}
-
-func TestTaskDecoderNoTasks(t *testing.T) {
- d := TaskDecoder{}
- result, err := d.Result()
- assert.NoError(t, err)
- assert.Equal(t, 0, len(result))
-}
-
-func TestTaskDecoderError(t *testing.T) {
- task := &Task{}
- task.Id = "Id"
- var buf bytes.Buffer
- err := gob.NewEncoder(&buf).Encode(task)
- assert.NoError(t, err)
- serialized := buf.Bytes()
- invalid := append([]byte("Hi Mom!"), serialized...)
-
- d := TaskDecoder{}
- // Process should return true before it encounters an invalid result.
- assert.True(t, d.Process(serialized))
- assert.True(t, d.Process(serialized))
- // Process may return true or false after encountering an invalid value.
- _ = d.Process(invalid)
- for i := 0; i < 250; i++ {
- _ = d.Process(serialized)
- }
-
- // Result should return error.
- result, err := d.Result()
- assert.Error(t, err)
- assert.Equal(t, 0, len(result))
-}
« no previous file with comments | « build_scheduler/go/db/task.go ('k') | build_scheduler/go/db/testutil.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698