blob: 43924d17ff7cdde2b9504ce62d6ada606bb6065b [file]
package handlers
import (
"infra/appengine/rotang"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/julienschmidt/httprouter"
"github.com/kylelemons/godebug/pretty"
"go.chromium.org/luci/common/clock"
"go.chromium.org/luci/common/clock/testclock"
"go.chromium.org/luci/server/router"
"golang.org/x/net/context"
)
func TestHandleLegacy(t *testing.T) {
ctx := newTestContext()
ctxCancel, cancel := context.WithCancel(ctx)
cancel()
var f trooperFake
tests := []struct {
name string
fail bool
ctx *router.Context
lm map[string]func(*router.Context, string) (string, error)
fakeFail bool
fakeReturn string
}{{
name: "Canceled Context",
fail: true,
ctx: &router.Context{
Context: ctxCancel,
Writer: httptest.NewRecorder(),
},
}, {
name: "Success",
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
Params: httprouter.Params{
{
Key: "name",
Value: "trooper.js",
},
},
},
lm: map[string]func(*router.Context, string) (string, error){
"trooper.js": f.troopers,
},
}, {
name: "Name not in the map",
fail: true,
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
Params: httprouter.Params{
{
Key: "name",
Value: "trooper.js",
},
},
},
lm: map[string]func(*router.Context, string) (string, error){
"not_trooper.js": f.troopers,
},
}, {
name: "Func fail",
fail: true,
fakeFail: true,
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
Params: httprouter.Params{
{
Key: "name",
Value: "trooper.js",
},
},
},
lm: map[string]func(*router.Context, string) (string, error){
"trooper.js": f.troopers,
},
},
}
h := testSetup(t)
for _, tst := range tests {
f.fail = tst.fakeFail
f.ret = tst.fakeReturn
h.legacyMap = tst.lm
h.HandleLegacy(tst.ctx)
recorder := tst.ctx.Writer.(*httptest.ResponseRecorder)
if got, want := (recorder.Code != http.StatusOK), tst.fail; got != want {
t.Errorf("%s: HandleLegacy(ctx) = %t want: %t, code: %v", tst.name, got, want, recorder.Code)
continue
}
}
}
func TestLegacySheriff(t *testing.T) {
ctx := newTestContext()
tests := []struct {
name string
fail bool
calFail bool
time time.Time
calShifts []rotang.ShiftEntry
ctx *router.Context
file string
memberPool []rotang.Member
cfgs []*rotang.Configuration
want string
}{{
name: "Success JS",
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
},
file: "sheriff.js",
time: midnight,
cfgs: []*rotang.Configuration{
{
Config: rotang.Config{
Name: "Build Sheriff",
},
},
},
calShifts: []rotang.ShiftEntry{
{
StartTime: midnight,
EndTime: midnight.Add(5 * fullDay),
OnCall: []rotang.ShiftMember{
{
Email: "test1@oncall.com",
}, {
Email: "test2@oncall.com",
},
},
}, {
StartTime: midnight.Add(5 * fullDay),
EndTime: midnight.Add(10 * fullDay),
OnCall: []rotang.ShiftMember{
{
Email: "test3@oncall.com",
}, {
Email: "test4@oncall.com",
},
},
},
},
want: "document.write('test1, test2');",
}, {
name: "Success JSON",
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
},
file: "sheriff.json",
time: midnight.Add(6 * fullDay),
cfgs: []*rotang.Configuration{
{
Config: rotang.Config{
Name: "Build Sheriff",
},
},
},
calShifts: []rotang.ShiftEntry{
{
StartTime: midnight,
EndTime: midnight.Add(5 * fullDay),
OnCall: []rotang.ShiftMember{
{
Email: "test1@oncall.com",
}, {
Email: "test2@oncall.com",
},
},
}, {
StartTime: midnight.Add(5 * fullDay),
EndTime: midnight.Add(10 * fullDay),
OnCall: []rotang.ShiftMember{
{
Email: "test3@oncall.com",
}, {
Email: "test4@oncall.com",
},
},
},
},
want: `{"updated_unix_timestamp":1144454400,"emails":["test3@oncall.com","test4@oncall.com"]}
`,
}, {
name: "File not supported",
fail: true,
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
},
file: "sheriff_not_supported.js",
time: midnight,
}, {
name: "Config not found",
fail: true,
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
},
file: "sheriff.js",
time: midnight,
}, {
name: "Calendar fail",
fail: true,
calFail: true,
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
},
file: "sheriff.json",
time: midnight.Add(6 * fullDay),
cfgs: []*rotang.Configuration{
{
Config: rotang.Config{
Name: "Build Sheriff",
},
},
},
},
}
h := testSetup(t)
for _, tst := range tests {
t.Run(tst.name, func(t *testing.T) {
for _, m := range tst.memberPool {
if err := h.memberStore(ctx).CreateMember(ctx, &m); err != nil {
t.Fatalf("%s: AddMember(ctx, _) failed: %v", tst.name, err)
}
defer h.memberStore(ctx).DeleteMember(ctx, m.Email)
}
for _, cfg := range tst.cfgs {
if err := h.configStore(ctx).CreateRotaConfig(ctx, cfg); err != nil {
t.Fatalf("%s: CreateRotaConfig(ctx, _) failed: %v", tst.name, err)
}
defer h.configStore(ctx).DeleteRotaConfig(ctx, cfg.Config.Name)
}
h.legacyCalendar.(*fakeCal).Set(tst.calShifts, tst.calFail, false, 0)
tst.ctx.Context = clock.Set(tst.ctx.Context, testclock.New(tst.time))
res, err := h.legacySheriff(tst.ctx, tst.file)
if got, want := (err != nil), tst.fail; got != want {
t.Fatalf("%s: h.legacySheriff(ctx, %q) = %t want: %t, err: %v", tst.name, tst.file, got, want, err)
}
if err != nil {
return
}
if diff := pretty.Compare(tst.want, res); diff != "" {
t.Fatalf("%s: h.legacySheriff(ctx, %q) differ -want +got, \n%s", tst.name, tst.file, diff)
}
})
}
}
func TestLegacyTroopers(t *testing.T) {
ctx := newTestContext()
tests := []struct {
name string
fail bool
calFail bool
ctx *router.Context
file string
oncallers []string
updateTime time.Time
want string
}{{
name: "Success JS",
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
Request: httptest.NewRequest("GET", "/legacy", nil),
},
file: "trooper.js",
oncallers: []string{"primary1", "secondary1", "secondary2"},
updateTime: midnight,
want: "document.write('primary1, secondary: secondary1, secondary2');",
}, {
name: "Success JSON",
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
Request: httptest.NewRequest("GET", "/legacy", nil),
},
file: "current_trooper.json",
oncallers: []string{"primary1", "secondary1", "secondary2"},
updateTime: midnight,
want: `{"primary":"primary1","secondary":["secondary1","secondary2"],"updated_unix_timestamp":1143936000}
`,
}, {
name: "Success txt",
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
Request: httptest.NewRequest("GET", "/legacy", nil),
},
file: "current_trooper.txt",
oncallers: []string{"primary1", "secondary1", "secondary2"},
updateTime: midnight,
want: "primary1,secondary1,secondary2",
}, {
name: "Calendar fail",
fail: true,
calFail: true,
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
Request: httptest.NewRequest("GET", "/legacy", nil),
},
file: "current_trooper.txt",
oncallers: []string{"primary1", "secondary1", "secondary2"},
updateTime: midnight,
}, {
name: "Unknown file",
fail: true,
ctx: &router.Context{
Context: ctx,
Writer: httptest.NewRecorder(),
Request: httptest.NewRequest("GET", "/legacy", nil),
},
file: "unknown_trooper.txt",
oncallers: []string{"primary1", "secondary1", "secondary2"},
updateTime: midnight,
},
}
h := testSetup(t)
for _, tst := range tests {
h.legacyCalendar.(*fakeCal).SetTroopers(tst.oncallers, tst.calFail)
tst.ctx.Context = clock.Set(tst.ctx.Context, testclock.New(tst.updateTime))
resStr, err := h.legacyTrooper(tst.ctx, tst.file)
if got, want := (err != nil), tst.fail; got != want {
t.Errorf("%s: legacyTrooper(ctx) = %t want: %t, err: %v", tst.name, got, want, err)
continue
}
if err != nil {
continue
}
if diff := pretty.Compare(tst.want, resStr); diff != "" {
t.Errorf("%s: legacyTrooper(ctx) differ -want +got,\n%s", tst.name, diff)
}
}
}