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

Unified Diff: build_scheduler/go/db/testutil.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_test.go ('k') | build_scheduler/go/parse_task_cfg/main.go » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: build_scheduler/go/db/testutil.go
diff --git a/build_scheduler/go/db/testutil.go b/build_scheduler/go/db/testutil.go
deleted file mode 100644
index bf3a83a60e5cf499c3ea6a49b06f994cadb70b5a..0000000000000000000000000000000000000000
--- a/build_scheduler/go/db/testutil.go
+++ /dev/null
@@ -1,846 +0,0 @@
-package db
-
-import (
- "fmt"
- "net/url"
- "testing"
- "time"
-
- assert "github.com/stretchr/testify/require"
-
- "go.skia.org/infra/go/testutils"
- "go.skia.org/infra/go/util"
-)
-
-const DEFAULT_TEST_REPO = "go-on-now.git"
-
-func makeTask(ts time.Time, commits []string) *Task {
- return &Task{
- Created: ts,
- Repo: DEFAULT_TEST_REPO,
- Commits: commits,
- Name: "Test-Task",
- }
-}
-
-func TestDB(t *testing.T, db DB) {
- defer testutils.AssertCloses(t, db)
-
- _, err := db.GetModifiedTasks("dummy-id")
- assert.True(t, IsUnknownId(err))
-
- id, err := db.StartTrackingModifiedTasks()
- assert.NoError(t, err)
-
- tasks, err := db.GetModifiedTasks(id)
- assert.NoError(t, err)
- assert.Equal(t, 0, len(tasks))
-
- t1 := makeTask(time.Time{}, []string{"a", "b", "c", "d"})
-
- // AssignId should fill in t1.Id.
- assert.Equal(t, "", t1.Id)
- assert.NoError(t, db.AssignId(t1))
- assert.NotEqual(t, "", t1.Id)
- // Ids must be URL-safe.
- assert.Equal(t, url.QueryEscape(t1.Id), t1.Id)
-
- // Task doesn't exist in DB yet.
- noTask, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- assert.Nil(t, noTask)
-
- // Set Creation time. Ensure Created is not the time of AssignId to test the
- // sequence (1) AssignId, (2) initialize task, (3) PutTask.
- now := time.Now().Add(time.Nanosecond)
- t1.Created = now
-
- // Insert the task.
- assert.NoError(t, db.PutTask(t1))
-
- // Check that DbModified was set.
- assert.False(t, util.TimeIsZero(t1.DbModified))
- t1LastModified := t1.DbModified
-
- // Task can now be retrieved by Id.
- t1Again, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, t1, t1Again)
-
- // Ensure that the task shows up in the modified list.
- tasks, err = db.GetModifiedTasks(id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1}, tasks)
-
- // Ensure that the task shows up in the correct date ranges.
- timeStart := time.Time{}
- t1Before := t1.Created
- t1After := t1Before.Add(1 * time.Nanosecond)
- timeEnd := now.Add(2 * time.Nanosecond)
- tasks, err = db.GetTasksFromDateRange(timeStart, t1Before)
- assert.NoError(t, err)
- assert.Equal(t, 0, len(tasks))
- tasks, err = db.GetTasksFromDateRange(t1Before, t1After)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1}, tasks)
- tasks, err = db.GetTasksFromDateRange(t1After, timeEnd)
- assert.NoError(t, err)
- assert.Equal(t, 0, len(tasks))
-
- // Insert two more tasks. Ensure at least 1 nanosecond between task Created
- // times so that t1After != t2Before and t2After != t3Before.
- t2 := makeTask(now.Add(time.Nanosecond), []string{"e", "f"})
- t3 := makeTask(now.Add(2*time.Nanosecond), []string{"g", "h"})
- assert.NoError(t, db.PutTasks([]*Task{t2, t3}))
-
- // Check that PutTasks assigned Ids.
- assert.NotEqual(t, "", t2.Id)
- assert.NotEqual(t, "", t3.Id)
- // Ids must be URL-safe.
- assert.Equal(t, url.QueryEscape(t2.Id), t2.Id)
- assert.Equal(t, url.QueryEscape(t3.Id), t3.Id)
-
- // Ensure that both tasks show up in the modified list.
- tasks, err = db.GetModifiedTasks(id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t2, t3}, tasks)
-
- // Make an update to t1 and t2. Ensure modified times change.
- t2LastModified := t2.DbModified
- t1.Status = TASK_STATUS_RUNNING
- t2.Status = TASK_STATUS_SUCCESS
- assert.NoError(t, db.PutTasks([]*Task{t1, t2}))
- assert.False(t, t1.DbModified.Equal(t1LastModified))
- assert.False(t, t2.DbModified.Equal(t2LastModified))
-
- // Ensure that both tasks show up in the modified list.
- tasks, err = db.GetModifiedTasks(id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1, t2}, tasks)
-
- // Ensure that all tasks show up in the correct time ranges, in sorted order.
- t2Before := t2.Created
- t2After := t2Before.Add(1 * time.Nanosecond)
-
- t3Before := t3.Created
- t3After := t3Before.Add(1 * time.Nanosecond)
-
- timeEnd = now.Add(3 * time.Nanosecond)
-
- tasks, err = db.GetTasksFromDateRange(timeStart, t1Before)
- assert.NoError(t, err)
- assert.Equal(t, 0, len(tasks))
-
- tasks, err = db.GetTasksFromDateRange(timeStart, t1After)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(timeStart, t2Before)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(timeStart, t2After)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1, t2}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(timeStart, t3Before)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1, t2}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(timeStart, t3After)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1, t2, t3}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(timeStart, timeEnd)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1, t2, t3}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(t1Before, timeEnd)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t1, t2, t3}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(t1After, timeEnd)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t2, t3}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(t2Before, timeEnd)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t2, t3}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(t2After, timeEnd)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t3}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(t3Before, timeEnd)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{t3}, tasks)
-
- tasks, err = db.GetTasksFromDateRange(t3After, timeEnd)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, []*Task{}, tasks)
-}
-
-func TestTooManyUsers(t *testing.T, db DB) {
- defer testutils.AssertCloses(t, db)
-
- // Max out the number of modified-tasks users; ensure that we error out.
- for i := 0; i < MAX_MODIFIED_TASKS_USERS; i++ {
- _, err := db.StartTrackingModifiedTasks()
- assert.NoError(t, err)
- }
- _, err := db.StartTrackingModifiedTasks()
- assert.True(t, IsTooManyUsers(err))
-}
-
-// Test that PutTask and PutTasks return ErrConcurrentUpdate when a cached Task
-// has been updated in the DB.
-func TestConcurrentUpdate(t *testing.T, db DB) {
- defer testutils.AssertCloses(t, db)
-
- // Insert a task.
- t1 := makeTask(time.Now(), []string{"a", "b", "c", "d"})
- assert.NoError(t, db.PutTask(t1))
-
- // Retrieve a copy of the task.
- t1Cached, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, t1, t1Cached)
-
- // Update the original task.
- t1.Commits = []string{"a", "b"}
- assert.NoError(t, db.PutTask(t1))
-
- // Update the cached copy; should get concurrent update error.
- t1Cached.Status = TASK_STATUS_RUNNING
- err = db.PutTask(t1Cached)
- assert.True(t, IsConcurrentUpdate(err))
-
- {
- // DB should still have the old value of t1.
- t1Again, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, t1, t1Again)
- }
-
- // Insert a second task.
- t2 := makeTask(time.Now(), []string{"e", "f"})
- assert.NoError(t, db.PutTask(t2))
-
- // Update t2 at the same time as t1Cached; should still get an error.
- t2.Status = TASK_STATUS_MISHAP
- err = db.PutTasks([]*Task{t2, t1Cached})
- assert.True(t, IsConcurrentUpdate(err))
-
- {
- // DB should still have the old value of t1.
- t1Again, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, t1, t1Again)
-
- // DB should also still have the old value of t2, but to keep InMemoryDB
- // simple, we don't check that here.
- }
-}
-
-// Test UpdateWithRetries when no errors or retries.
-func testUpdateWithRetriesSimple(t *testing.T, db DB) {
- begin := time.Now()
-
- // Test no-op.
- tasks, err := UpdateWithRetries(db, func() ([]*Task, error) {
- return nil, nil
- })
- assert.NoError(t, err)
- assert.Equal(t, 0, len(tasks))
-
- // Create new task t1. (UpdateWithRetries isn't actually useful in this case.)
- tasks, err = UpdateWithRetries(db, func() ([]*Task, error) {
- t1 := makeTask(time.Time{}, []string{"a", "b", "c", "d"})
- assert.NoError(t, db.AssignId(t1))
- t1.Created = time.Now().Add(time.Nanosecond)
- return []*Task{t1}, nil
- })
- assert.NoError(t, err)
- assert.Equal(t, 1, len(tasks))
- t1 := tasks[0]
-
- // Update t1 and create t2.
- tasks, err = UpdateWithRetries(db, func() ([]*Task, error) {
- t1, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- t1.Status = TASK_STATUS_RUNNING
- t2 := makeTask(t1.Created.Add(time.Nanosecond), []string{"e", "f"})
- return []*Task{t1, t2}, nil
- })
- assert.NoError(t, err)
- assert.Equal(t, 2, len(tasks))
- assert.Equal(t, t1.Id, tasks[0].Id)
- assert.Equal(t, TASK_STATUS_RUNNING, tasks[0].Status)
- assert.Equal(t, []string{"e", "f"}, tasks[1].Commits)
-
- // Check that return value matches what's in the DB.
- t1, err = db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- t2, err := db.GetTaskById(tasks[1].Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, tasks[0], t1)
- testutils.AssertDeepEqual(t, tasks[1], t2)
-
- // Check no extra tasks in the DB.
- tasks, err = db.GetTasksFromDateRange(begin, time.Now().Add(3*time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 2, len(tasks))
- assert.Equal(t, t1.Id, tasks[0].Id)
- assert.Equal(t, t2.Id, tasks[1].Id)
-}
-
-// Test UpdateWithRetries when there are some retries, but eventual success.
-func testUpdateWithRetriesSuccess(t *testing.T, db DB) {
- begin := time.Now()
-
- // Create and cache.
- t1 := makeTask(begin.Add(time.Nanosecond), []string{"a", "b", "c", "d"})
- assert.NoError(t, db.PutTask(t1))
- t1Cached := t1.Copy()
-
- // Update original.
- t1.Status = TASK_STATUS_RUNNING
- assert.NoError(t, db.PutTask(t1))
-
- // Attempt update.
- callCount := 0
- tasks, err := UpdateWithRetries(db, func() ([]*Task, error) {
- callCount++
- if callCount >= 3 {
- if task, err := db.GetTaskById(t1.Id); err != nil {
- return nil, err
- } else {
- t1Cached = task
- }
- }
- t1Cached.Status = TASK_STATUS_SUCCESS
- t2 := makeTask(begin.Add(2*time.Nanosecond), []string{"e", "f"})
- return []*Task{t1Cached, t2}, nil
- })
- assert.NoError(t, err)
- assert.Equal(t, 3, callCount)
- assert.Equal(t, 2, len(tasks))
- assert.Equal(t, t1.Id, tasks[0].Id)
- assert.Equal(t, TASK_STATUS_SUCCESS, tasks[0].Status)
- assert.Equal(t, []string{"e", "f"}, tasks[1].Commits)
-
- // Check that return value matches what's in the DB.
- t1, err = db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- t2, err := db.GetTaskById(tasks[1].Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, tasks[0], t1)
- testutils.AssertDeepEqual(t, tasks[1], t2)
-
- // Check no extra tasks in the DB.
- tasks, err = db.GetTasksFromDateRange(begin, time.Now().Add(3*time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 2, len(tasks))
- assert.Equal(t, t1.Id, tasks[0].Id)
- assert.Equal(t, t2.Id, tasks[1].Id)
-}
-
-// Test UpdateWithRetries when f returns an error.
-func testUpdateWithRetriesErrorInFunc(t *testing.T, db DB) {
- begin := time.Now()
-
- myErr := fmt.Errorf("NO! Bad dog!")
- callCount := 0
- tasks, err := UpdateWithRetries(db, func() ([]*Task, error) {
- callCount++
- // Return a task just for fun.
- return []*Task{
- makeTask(begin.Add(time.Nanosecond), []string{"a", "b", "c", "d"}),
- }, myErr
- })
- assert.Error(t, err)
- assert.Equal(t, myErr, err)
- assert.Equal(t, 0, len(tasks))
- assert.Equal(t, 1, callCount)
-
- // Check no tasks in the DB.
- tasks, err = db.GetTasksFromDateRange(begin, time.Now().Add(2*time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 0, len(tasks))
-}
-
-// Test UpdateWithRetries when PutTasks returns an error.
-func testUpdateWithRetriesErrorInPutTasks(t *testing.T, db DB) {
- begin := time.Now()
-
- callCount := 0
- tasks, err := UpdateWithRetries(db, func() ([]*Task, error) {
- callCount++
- // Task has zero Created time.
- return []*Task{
- makeTask(time.Time{}, []string{"a", "b", "c", "d"}),
- }, nil
- })
- assert.Error(t, err)
- assert.Contains(t, err.Error(), "Created not set.")
- assert.Equal(t, 0, len(tasks))
- assert.Equal(t, 1, callCount)
-
- // Check no tasks in the DB.
- tasks, err = db.GetTasksFromDateRange(begin, time.Now().Add(time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 0, len(tasks))
-}
-
-// Test UpdateWithRetries when retries are exhausted.
-func testUpdateWithRetriesExhausted(t *testing.T, db DB) {
- begin := time.Now()
-
- // Create and cache.
- t1 := makeTask(begin.Add(time.Nanosecond), []string{"a", "b", "c", "d"})
- assert.NoError(t, db.PutTask(t1))
- t1Cached := t1.Copy()
-
- // Update original.
- t1.Status = TASK_STATUS_RUNNING
- assert.NoError(t, db.PutTask(t1))
-
- // Attempt update.
- callCount := 0
- tasks, err := UpdateWithRetries(db, func() ([]*Task, error) {
- callCount++
- t1Cached.Status = TASK_STATUS_SUCCESS
- t2 := makeTask(begin.Add(2*time.Nanosecond), []string{"e", "f"})
- return []*Task{t1Cached, t2}, nil
- })
- assert.True(t, IsConcurrentUpdate(err))
- assert.Equal(t, NUM_RETRIES, callCount)
- assert.Equal(t, 0, len(tasks))
-
- // Check no extra tasks in the DB.
- tasks, err = db.GetTasksFromDateRange(begin, time.Now().Add(3*time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 1, len(tasks))
- assert.Equal(t, t1.Id, tasks[0].Id)
- assert.Equal(t, TASK_STATUS_RUNNING, tasks[0].Status)
-}
-
-// Test UpdateTaskWithRetries when no errors or retries.
-func testUpdateTaskWithRetriesSimple(t *testing.T, db DB) {
- begin := time.Now()
-
- // Create new task t1.
- t1 := makeTask(time.Time{}, []string{"a", "b", "c", "d"})
- assert.NoError(t, db.AssignId(t1))
- t1.Created = time.Now().Add(time.Nanosecond)
- assert.NoError(t, db.PutTask(t1))
-
- // Update t1.
- t1Updated, err := UpdateTaskWithRetries(db, t1.Id, func(task *Task) error {
- task.Status = TASK_STATUS_RUNNING
- return nil
- })
- assert.NoError(t, err)
- assert.Equal(t, t1.Id, t1Updated.Id)
- assert.Equal(t, TASK_STATUS_RUNNING, t1Updated.Status)
- assert.NotEqual(t, t1.DbModified, t1Updated.DbModified)
-
- // Check that return value matches what's in the DB.
- t1Again, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, t1Again, t1Updated)
-
- // Check no extra tasks in the DB.
- tasks, err := db.GetTasksFromDateRange(begin, time.Now().Add(2*time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 1, len(tasks))
- assert.Equal(t, t1.Id, tasks[0].Id)
-}
-
-// Test UpdateTaskWithRetries when there are some retries, but eventual success.
-func testUpdateTaskWithRetriesSuccess(t *testing.T, db DB) {
- begin := time.Now()
-
- // Create new task t1.
- t1 := makeTask(begin.Add(time.Nanosecond), []string{"a", "b", "c", "d"})
- assert.NoError(t, db.PutTask(t1))
-
- // Attempt update.
- callCount := 0
- t1Updated, err := UpdateTaskWithRetries(db, t1.Id, func(task *Task) error {
- callCount++
- if callCount < 3 {
- // Sneakily make an update in the background.
- t1.Commits = append(t1.Commits, fmt.Sprintf("z%d", callCount))
- assert.NoError(t, db.PutTask(t1))
- }
- task.Status = TASK_STATUS_SUCCESS
- return nil
- })
- assert.NoError(t, err)
- assert.Equal(t, 3, callCount)
- assert.Equal(t, t1.Id, t1Updated.Id)
- assert.Equal(t, TASK_STATUS_SUCCESS, t1Updated.Status)
-
- // Check that return value matches what's in the DB.
- t1Again, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, t1Again, t1Updated)
-
- // Check no extra tasks in the DB.
- tasks, err := db.GetTasksFromDateRange(begin, time.Now().Add(2*time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 1, len(tasks))
- assert.Equal(t, t1.Id, tasks[0].Id)
-}
-
-// Test UpdateTaskWithRetries when f returns an error.
-func testUpdateTaskWithRetriesErrorInFunc(t *testing.T, db DB) {
- begin := time.Now()
-
- // Create new task t1.
- t1 := makeTask(begin.Add(time.Nanosecond), []string{"a", "b", "c", "d"})
- assert.NoError(t, db.PutTask(t1))
-
- // Update and return an error.
- myErr := fmt.Errorf("Um, actually, I didn't want to update that task.")
- callCount := 0
- noTask, err := UpdateTaskWithRetries(db, t1.Id, func(task *Task) error {
- callCount++
- // Update task to test nothing changes in DB.
- task.Status = TASK_STATUS_RUNNING
- return myErr
- })
- assert.Error(t, err)
- assert.Equal(t, myErr, err)
- assert.Nil(t, noTask)
- assert.Equal(t, 1, callCount)
-
- // Check task did not change in the DB.
- t1Again, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, t1, t1Again)
-
- // Check no extra tasks in the DB.
- tasks, err := db.GetTasksFromDateRange(begin, time.Now().Add(2*time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 1, len(tasks))
- assert.Equal(t, t1.Id, tasks[0].Id)
-}
-
-// Test UpdateTaskWithRetries when retries are exhausted.
-func testUpdateTaskWithRetriesExhausted(t *testing.T, db DB) {
- begin := time.Now()
-
- // Create new task t1.
- t1 := makeTask(begin.Add(time.Nanosecond), []string{"a", "b", "c", "d"})
- assert.NoError(t, db.PutTask(t1))
-
- // Update original.
- t1.Status = TASK_STATUS_RUNNING
- assert.NoError(t, db.PutTask(t1))
-
- // Attempt update.
- callCount := 0
- noTask, err := UpdateTaskWithRetries(db, t1.Id, func(task *Task) error {
- callCount++
- // Sneakily make an update in the background.
- t1.Commits = append(t1.Commits, fmt.Sprintf("z%d", callCount))
- assert.NoError(t, db.PutTask(t1))
-
- task.Status = TASK_STATUS_SUCCESS
- return nil
- })
- assert.True(t, IsConcurrentUpdate(err))
- assert.Equal(t, NUM_RETRIES, callCount)
- assert.Nil(t, noTask)
-
- // Check task did not change in the DB.
- t1Again, err := db.GetTaskById(t1.Id)
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, t1, t1Again)
-
- // Check no extra tasks in the DB.
- tasks, err := db.GetTasksFromDateRange(begin, time.Now().Add(2*time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 1, len(tasks))
- assert.Equal(t, t1.Id, tasks[0].Id)
-}
-
-// Test UpdateTaskWithRetries when the given ID is not found in the DB.
-func testUpdateTaskWithRetriesTaskNotFound(t *testing.T, db DB) {
- begin := time.Now()
-
- // Assign ID for a task, but don't put it in the DB.
- t1 := makeTask(begin.Add(time.Nanosecond), []string{"a", "b", "c", "d"})
- assert.NoError(t, db.AssignId(t1))
-
- // Attempt to update non-existent task. Function shouldn't be called.
- callCount := 0
- noTask, err := UpdateTaskWithRetries(db, t1.Id, func(task *Task) error {
- callCount++
- task.Status = TASK_STATUS_RUNNING
- return nil
- })
- assert.True(t, IsNotFound(err))
- assert.Nil(t, noTask)
- assert.Equal(t, 0, callCount)
-
- // Check no tasks in the DB.
- tasks, err := db.GetTasksFromDateRange(begin, time.Now().Add(2*time.Nanosecond))
- assert.NoError(t, err)
- assert.Equal(t, 0, len(tasks))
-}
-
-// Test UpdateWithRetries and UpdateTaskWithRetries.
-func TestUpdateWithRetries(t *testing.T, db DB) {
- testUpdateWithRetriesSimple(t, db)
- testUpdateWithRetriesSuccess(t, db)
- testUpdateWithRetriesErrorInFunc(t, db)
- testUpdateWithRetriesErrorInPutTasks(t, db)
- testUpdateWithRetriesExhausted(t, db)
- testUpdateTaskWithRetriesSimple(t, db)
- testUpdateTaskWithRetriesSuccess(t, db)
- testUpdateTaskWithRetriesErrorInFunc(t, db)
- testUpdateTaskWithRetriesExhausted(t, db)
- testUpdateTaskWithRetriesTaskNotFound(t, db)
-}
-
-// makeTaskComment creates a comment with its ID fields based on the given repo,
-// name, commit, and ts, and other fields based on n.
-func makeTaskComment(n int, repo int, name int, commit int, ts time.Time) *TaskComment {
- return &TaskComment{
- Repo: fmt.Sprintf("r%d", repo),
- Name: fmt.Sprintf("n%d", name),
- Commit: fmt.Sprintf("c%d", commit),
- Timestamp: ts,
- TaskId: fmt.Sprintf("id%d", n),
- User: fmt.Sprintf("u%d", n),
- Message: fmt.Sprintf("m%d", n),
- }
-}
-
-// makeTaskSpecComment creates a comment with its ID fields based on the given
-// repo, name, and ts, and other fields based on n.
-func makeTaskSpecComment(n int, repo int, name int, ts time.Time) *TaskSpecComment {
- return &TaskSpecComment{
- Repo: fmt.Sprintf("r%d", repo),
- Name: fmt.Sprintf("n%d", name),
- Timestamp: ts,
- User: fmt.Sprintf("u%d", n),
- Flaky: n%2 == 0,
- IgnoreFailure: n>>1%2 == 0,
- Message: fmt.Sprintf("m%d", n),
- }
-}
-
-// makeCommitComment creates a comment with its ID fields based on the given
-// repo, commit, and ts, and other fields based on n.
-func makeCommitComment(n int, repo int, commit int, ts time.Time) *CommitComment {
- return &CommitComment{
- Repo: fmt.Sprintf("r%d", repo),
- Commit: fmt.Sprintf("c%d", commit),
- Timestamp: ts,
- User: fmt.Sprintf("u%d", n),
- Message: fmt.Sprintf("m%d", n),
- }
-}
-
-// TestCommentDB validates that db correctly implements the CommentDB interface.
-func TestCommentDB(t *testing.T, db CommentDB) {
- now := time.Now()
-
- // Empty db.
- {
- actual, err := db.GetCommentsForRepos([]string{"r0", "r1", "r2"}, now.Add(-10000*time.Hour))
- assert.NoError(t, err)
- assert.Equal(t, 3, len(actual))
- assert.Equal(t, "r0", actual[0].Repo)
- assert.Equal(t, "r1", actual[1].Repo)
- assert.Equal(t, "r2", actual[2].Repo)
- for _, rc := range actual {
- assert.Equal(t, 0, len(rc.TaskComments))
- assert.Equal(t, 0, len(rc.TaskSpecComments))
- assert.Equal(t, 0, len(rc.CommitComments))
- }
- }
-
- // Add some comments.
- tc1 := makeTaskComment(1, 1, 1, 1, now)
- tc2 := makeTaskComment(2, 1, 1, 1, now.Add(2*time.Second))
- tc3 := makeTaskComment(3, 1, 1, 1, now.Add(time.Second))
- tc4 := makeTaskComment(4, 1, 1, 2, now)
- tc5 := makeTaskComment(5, 1, 2, 2, now)
- tc6 := makeTaskComment(6, 2, 3, 3, now)
- tc6copy := tc6.Copy() // Adding identical comment should be ignored.
- for _, c := range []*TaskComment{tc1, tc2, tc3, tc4, tc5, tc6, tc6copy} {
- assert.NoError(t, db.PutTaskComment(c))
- }
- tc6.Message = "modifying after Put shouldn't affect stored comment"
-
- sc1 := makeTaskSpecComment(1, 1, 1, now)
- sc2 := makeTaskSpecComment(2, 1, 1, now.Add(2*time.Second))
- sc3 := makeTaskSpecComment(3, 1, 1, now.Add(time.Second))
- sc4 := makeTaskSpecComment(4, 1, 2, now)
- sc5 := makeTaskSpecComment(5, 2, 3, now)
- sc5copy := sc5.Copy() // Adding identical comment should be ignored.
- for _, c := range []*TaskSpecComment{sc1, sc2, sc3, sc4, sc5, sc5copy} {
- assert.NoError(t, db.PutTaskSpecComment(c))
- }
- sc5.Message = "modifying after Put shouldn't affect stored comment"
-
- cc1 := makeCommitComment(1, 1, 1, now)
- cc2 := makeCommitComment(2, 1, 1, now.Add(2*time.Second))
- cc3 := makeCommitComment(3, 1, 1, now.Add(time.Second))
- cc4 := makeCommitComment(4, 1, 2, now)
- cc5 := makeCommitComment(5, 2, 3, now)
- cc5copy := cc5.Copy() // Adding identical comment should be ignored.
- for _, c := range []*CommitComment{cc1, cc2, cc3, cc4, cc5, cc5copy} {
- assert.NoError(t, db.PutCommitComment(c))
- }
- cc5.Message = "modifying after Put shouldn't affect stored comment"
-
- // Check that adding duplicate non-identical comment gives an error.
- tc1different := tc1.Copy()
- tc1different.Message = "not the same"
- assert.True(t, IsAlreadyExists(db.PutTaskComment(tc1different)))
- sc1different := sc1.Copy()
- sc1different.Message = "not the same"
- assert.True(t, IsAlreadyExists(db.PutTaskSpecComment(sc1different)))
- cc1different := cc1.Copy()
- cc1different.Message = "not the same"
- assert.True(t, IsAlreadyExists(db.PutCommitComment(cc1different)))
-
- expected := []*RepoComments{
- &RepoComments{Repo: "r0"},
- &RepoComments{
- Repo: "r1",
- TaskComments: map[string]map[string][]*TaskComment{
- "n1": {
- "c1": {tc1, tc3, tc2},
- "c2": {tc4},
- },
- "n2": {
- "c2": {tc5},
- },
- },
- TaskSpecComments: map[string][]*TaskSpecComment{
- "n1": {sc1, sc3, sc2},
- "n2": {sc4},
- },
- CommitComments: map[string][]*CommitComment{
- "c1": {cc1, cc3, cc2},
- "c2": {cc4},
- },
- },
- &RepoComments{
- Repo: "r2",
- TaskComments: map[string]map[string][]*TaskComment{
- "n3": {
- "c3": {tc6copy},
- },
- },
- TaskSpecComments: map[string][]*TaskSpecComment{
- "n3": {sc5copy},
- },
- CommitComments: map[string][]*CommitComment{
- "c3": {cc5copy},
- },
- },
- }
- {
- actual, err := db.GetCommentsForRepos([]string{"r0", "r1", "r2"}, now.Add(-10000*time.Hour))
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, expected, actual)
- }
-
- // Specifying a cutoff time shouldn't drop required comments.
- {
- actual, err := db.GetCommentsForRepos([]string{"r1"}, now.Add(time.Second))
- assert.NoError(t, err)
- assert.Equal(t, 1, len(actual))
- {
- tcs := actual[0].TaskComments["n1"]["c1"]
- assert.True(t, len(tcs) >= 2)
- offset := 0
- if !tcs[0].Timestamp.Equal(tc3.Timestamp) {
- offset = 1
- }
- testutils.AssertDeepEqual(t, tc3, tcs[offset])
- testutils.AssertDeepEqual(t, tc2, tcs[offset+1])
- }
- {
- scs := actual[0].TaskSpecComments["n1"]
- assert.True(t, len(scs) >= 2)
- offset := 0
- if !scs[0].Timestamp.Equal(sc3.Timestamp) {
- offset = 1
- }
- testutils.AssertDeepEqual(t, sc3, scs[offset])
- testutils.AssertDeepEqual(t, sc2, scs[offset+1])
- }
- {
- ccs := actual[0].CommitComments["c1"]
- assert.True(t, len(ccs) >= 2)
- offset := 0
- if !ccs[0].Timestamp.Equal(cc3.Timestamp) {
- offset = 1
- }
- testutils.AssertDeepEqual(t, cc3, ccs[offset])
- testutils.AssertDeepEqual(t, cc2, ccs[offset+1])
- }
- }
-
- // Delete some comments.
- assert.NoError(t, db.DeleteTaskComment(tc3))
- assert.NoError(t, db.DeleteTaskSpecComment(sc3))
- assert.NoError(t, db.DeleteCommitComment(cc3))
- // Delete should only look at the ID fields.
- assert.NoError(t, db.DeleteTaskComment(tc1different))
- assert.NoError(t, db.DeleteTaskSpecComment(sc1different))
- assert.NoError(t, db.DeleteCommitComment(cc1different))
- // Delete of nonexistent task should succeed.
- assert.NoError(t, db.DeleteTaskComment(makeTaskComment(99, 1, 1, 1, now.Add(99*time.Second))))
- assert.NoError(t, db.DeleteTaskComment(makeTaskComment(99, 1, 1, 99, now)))
- assert.NoError(t, db.DeleteTaskComment(makeTaskComment(99, 1, 99, 1, now)))
- assert.NoError(t, db.DeleteTaskComment(makeTaskComment(99, 99, 1, 1, now)))
- assert.NoError(t, db.DeleteTaskSpecComment(makeTaskSpecComment(99, 1, 1, now.Add(99*time.Second))))
- assert.NoError(t, db.DeleteTaskSpecComment(makeTaskSpecComment(99, 1, 99, now)))
- assert.NoError(t, db.DeleteTaskSpecComment(makeTaskSpecComment(99, 99, 1, now)))
- assert.NoError(t, db.DeleteCommitComment(makeCommitComment(99, 1, 1, now.Add(99*time.Second))))
- assert.NoError(t, db.DeleteCommitComment(makeCommitComment(99, 1, 99, now)))
- assert.NoError(t, db.DeleteCommitComment(makeCommitComment(99, 99, 1, now)))
-
- expected[1].TaskComments["n1"]["c1"] = []*TaskComment{tc2}
- expected[1].TaskSpecComments["n1"] = []*TaskSpecComment{sc2}
- expected[1].CommitComments["c1"] = []*CommitComment{cc2}
- {
- actual, err := db.GetCommentsForRepos([]string{"r0", "r1", "r2"}, now.Add(-10000*time.Hour))
- assert.NoError(t, err)
- testutils.AssertDeepEqual(t, expected, actual)
- }
-
- // Delete all the comments.
- for _, c := range []*TaskComment{tc2, tc4, tc5, tc6} {
- assert.NoError(t, db.DeleteTaskComment(c))
- }
- for _, c := range []*TaskSpecComment{sc2, sc4, sc5} {
- assert.NoError(t, db.DeleteTaskSpecComment(c))
- }
- for _, c := range []*CommitComment{cc2, cc4, cc5} {
- assert.NoError(t, db.DeleteCommitComment(c))
- }
- {
- actual, err := db.GetCommentsForRepos([]string{"r0", "r1", "r2"}, now.Add(-10000*time.Hour))
- assert.NoError(t, err)
- assert.Equal(t, 3, len(actual))
- assert.Equal(t, "r0", actual[0].Repo)
- assert.Equal(t, "r1", actual[1].Repo)
- assert.Equal(t, "r2", actual[2].Repo)
- for _, rc := range actual {
- assert.Equal(t, 0, len(rc.TaskComments))
- assert.Equal(t, 0, len(rc.TaskSpecComments))
- assert.Equal(t, 0, len(rc.CommitComments))
- }
- }
-}
« no previous file with comments | « build_scheduler/go/db/task_test.go ('k') | build_scheduler/go/parse_task_cfg/main.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698