blob: 55e15a5a203b9dbe2792521550b24f5e0ce6273b [file] [log] [blame]
// Copyright 2022 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package relui
import (
"context"
"database/sql"
"testing"
"time"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"golang.org/x/build/internal/relui/db"
)
func TestSchedulerCreate(t *testing.T) {
now := time.Now()
cases := []struct {
desc string
sched Schedule
workflowName string
params map[string]any
want db.Schedule
wantEntries []ScheduleEntry
wantErr bool
}{
{
desc: "success: once",
sched: Schedule{Once: now.AddDate(1, 0, 0)},
workflowName: "echo",
params: map[string]any{"greeting": "hello", "farewell": "bye"},
want: db.Schedule{
WorkflowName: "echo",
WorkflowParams: sql.NullString{
String: `{"farewell": "bye", "greeting": "hello"}`,
Valid: true,
},
Once: now.AddDate(1, 0, 0),
CreatedAt: now,
UpdatedAt: now,
},
wantEntries: []ScheduleEntry{
{
Schedule: &RunOnce{next: now.UTC().AddDate(1, 0, 0)},
Next: now.UTC().AddDate(1, 0, 0),
Job: &WorkflowSchedule{
Schedule: db.Schedule{
WorkflowName: "echo",
WorkflowParams: sql.NullString{
String: `{"farewell": "bye", "greeting": "hello"}`,
Valid: true,
},
Once: now.UTC().AddDate(1, 0, 0),
CreatedAt: now,
UpdatedAt: now,
},
Params: map[string]any{"greeting": "hello", "farewell": "bye"},
},
},
},
},
}
for _, c := range cases {
t.Run(c.desc, func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
p := testDB(ctx, t)
s := NewScheduler(p, NewWorker(NewDefinitionHolder(), p, &PGListener{p}))
row, err := s.Create(ctx, c.sched, c.workflowName, c.params)
if err != nil {
t.Fatalf("s.Create(_, %v, %q, %v) = %v, %v, wanted no error", c.sched, c.workflowName, c.params, row, err)
}
if diff := cmp.Diff(c.want, row, cmpopts.EquateApproxTime(time.Minute), cmpopts.IgnoreFields(db.Schedule{}, "ID")); diff != "" {
t.Fatalf("s.Create() mismatch (-want +got):\n%s", diff)
}
got := s.Entries()
diffOpts := []cmp.Option{
cmpopts.EquateApproxTime(time.Minute),
cmpopts.IgnoreFields(db.Schedule{}, "ID"),
cmpopts.IgnoreUnexported(RunOnce{}, WorkflowSchedule{}),
cmpopts.IgnoreFields(ScheduleEntry{}, "ID", "WrappedJob"),
}
if diff := cmp.Diff(c.wantEntries, got, diffOpts...); diff != "" {
t.Fatalf("s.Entries() mismatch (-want +got):\n%s", diff)
}
})
}
}
func TestSchedulerResume(t *testing.T) {
now := time.Now()
cases := []struct {
desc string
scheds []db.CreateScheduleParams
want []ScheduleEntry
wantParams map[string]any
wantErr bool
}{
{
desc: "success: once",
scheds: []db.CreateScheduleParams{
{
WorkflowName: "echo",
WorkflowParams: sql.NullString{
String: `{"farewell": "bye", "greeting": "hello"}`,
Valid: true,
},
Once: now.UTC().AddDate(1, 0, 0),
CreatedAt: now,
UpdatedAt: now,
},
},
want: []ScheduleEntry{
{
Schedule: &RunOnce{next: now.UTC().AddDate(1, 0, 0)},
Next: now.UTC().AddDate(1, 0, 0),
Job: &WorkflowSchedule{
Schedule: db.Schedule{
WorkflowName: "echo",
WorkflowParams: sql.NullString{
String: `{"farewell": "bye", "greeting": "hello"}`,
Valid: true,
},
Once: now.UTC().AddDate(1, 0, 0),
CreatedAt: now,
UpdatedAt: now,
},
Params: map[string]any{"greeting": "hello", "farewell": "bye"},
},
},
},
},
}
for _, c := range cases {
t.Run(c.desc, func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
p := testDB(ctx, t)
q := db.New(p)
s := NewScheduler(p, NewWorker(NewDefinitionHolder(), p, &PGListener{p}))
for _, csp := range c.scheds {
if _, err := q.CreateSchedule(ctx, csp); err != nil {
t.Fatalf("q.CreateSchedule(_, %#v) = _, %v, wanted no error", csp, err)
}
}
if err := s.Resume(ctx); err != nil {
t.Errorf("s.Resume() = %v, wanted no error", err)
}
got := s.Entries()
diffOpts := []cmp.Option{
cmpopts.EquateApproxTime(time.Minute),
cmpopts.IgnoreFields(db.Schedule{}, "ID"),
cmpopts.IgnoreUnexported(RunOnce{}, WorkflowSchedule{}),
cmpopts.IgnoreFields(ScheduleEntry{}, "ID", "WrappedJob"),
}
if diff := cmp.Diff(c.want, got, diffOpts...); diff != "" {
t.Fatalf("s.Entries() mismatch (-want +got):\n%s", diff)
}
})
}
}