2020-07-13 21:29:41 +08:00
// Copyright 2020 Kentaro Hibino. All rights reserved.
// Use of this source code is governed by a MIT license
// that can be found in the LICENSE file.
2021-01-29 00:59:13 +08:00
package inspeq
2020-07-13 21:29:41 +08:00
import (
2021-01-29 00:59:13 +08:00
"flag"
2020-07-13 21:29:41 +08:00
"fmt"
2020-07-27 04:16:13 +08:00
"math"
2020-12-01 23:37:09 +08:00
"sort"
2021-01-29 00:59:13 +08:00
"strings"
2020-07-13 21:29:41 +08:00
"testing"
"time"
2021-01-29 00:59:13 +08:00
"github.com/go-redis/redis/v7"
2020-07-13 21:29:41 +08:00
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
2021-01-29 00:59:13 +08:00
"github.com/hibiken/asynq"
2020-07-13 21:29:41 +08:00
h "github.com/hibiken/asynq/internal/asynqtest"
"github.com/hibiken/asynq/internal/base"
2021-01-29 00:59:13 +08:00
"github.com/hibiken/asynq/internal/log"
2020-12-01 23:37:09 +08:00
"github.com/hibiken/asynq/internal/rdb"
2020-07-13 21:29:41 +08:00
)
2021-01-29 00:59:13 +08:00
// variables used for package testing.
var (
redisAddr string
redisDB int
useRedisCluster bool
redisClusterAddrs string // comma-separated list of host:port
testLogLevel = asynq . FatalLevel
)
var testLogger * log . Logger
func init ( ) {
flag . StringVar ( & redisAddr , "redis_addr" , "localhost:6379" , "redis address to use in testing" )
2021-01-31 02:43:57 +08:00
flag . IntVar ( & redisDB , "redis_db" , 13 , "redis db number to use in testing" )
2021-01-29 00:59:13 +08:00
flag . BoolVar ( & useRedisCluster , "redis_cluster" , false , "use redis cluster as a broker in testing" )
flag . StringVar ( & redisClusterAddrs , "redis_cluster_addrs" , "localhost:7000,localhost:7001,localhost:7002" , "comma separated list of redis server addresses" )
flag . Var ( & testLogLevel , "loglevel" , "log level to use in testing" )
testLogger = log . NewLogger ( nil )
testLogger . SetLevel ( toInternalLogLevel ( testLogLevel ) )
}
func toInternalLogLevel ( l asynq . LogLevel ) log . Level {
switch l {
case asynq . DebugLevel :
return log . DebugLevel
case asynq . InfoLevel :
return log . InfoLevel
case asynq . WarnLevel :
return log . WarnLevel
case asynq . ErrorLevel :
return log . ErrorLevel
case asynq . FatalLevel :
return log . FatalLevel
}
panic ( fmt . Sprintf ( "inspeq: unexpected log level: %v" , l ) )
}
func setup ( tb testing . TB ) ( r redis . UniversalClient ) {
tb . Helper ( )
if useRedisCluster {
addrs := strings . Split ( redisClusterAddrs , "," )
if len ( addrs ) == 0 {
tb . Fatal ( "No redis cluster addresses provided. Please set addresses using --redis_cluster_addrs flag." )
}
r = redis . NewClusterClient ( & redis . ClusterOptions {
Addrs : addrs ,
} )
} else {
r = redis . NewClient ( & redis . Options {
Addr : redisAddr ,
DB : redisDB ,
} )
}
// Start each test with a clean slate.
h . FlushDB ( tb , r )
return r
}
func getRedisConnOpt ( tb testing . TB ) asynq . RedisConnOpt {
tb . Helper ( )
if useRedisCluster {
addrs := strings . Split ( redisClusterAddrs , "," )
if len ( addrs ) == 0 {
tb . Fatal ( "No redis cluster addresses provided. Please set addresses using --redis_cluster_addrs flag." )
}
return asynq . RedisClusterClientOpt {
Addrs : addrs ,
}
}
return asynq . RedisClientOpt {
Addr : redisAddr ,
DB : redisDB ,
}
}
2020-08-21 12:17:44 +08:00
func TestInspectorQueues ( t * testing . T ) {
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-08-21 12:17:44 +08:00
tests := [ ] struct {
queues [ ] string
} {
{ queues : [ ] string { "default" } } ,
{ queues : [ ] string { "custom1" , "custom2" } } ,
{ queues : [ ] string { "default" , "custom1" , "custom2" } } ,
{ queues : [ ] string { } } ,
}
for _ , tc := range tests {
h . FlushDB ( t , r )
for _ , qname := range tc . queues {
if err := r . SAdd ( base . AllQueues , qname ) . Err ( ) ; err != nil {
t . Fatalf ( "could not initialize all queue set: %v" , err )
}
}
got , err := inspector . Queues ( )
if err != nil {
t . Errorf ( "Queues() returned an error: %v" , err )
continue
}
if diff := cmp . Diff ( tc . queues , got , h . SortStringSliceOpt ) ; diff != "" {
t . Errorf ( "Queues() = %v, want %v; (-want, +got)\n%s" , got , tc . queues , diff )
}
}
}
2020-11-28 14:27:54 +08:00
func TestInspectorDeleteQueue ( t * testing . T ) {
r := setup ( t )
defer r . Close ( )
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-11-28 14:27:54 +08:00
defer inspector . Close ( )
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
tests := [ ] struct {
pending map [ string ] [ ] * base . TaskMessage
active map [ string ] [ ] * base . TaskMessage
scheduled map [ string ] [ ] base . Z
retry map [ string ] [ ] base . Z
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
2020-11-28 14:27:54 +08:00
qname string // queue to remove
force bool
} {
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 } ,
"custom" : { } ,
} ,
active : map [ string ] [ ] * base . TaskMessage {
"default" : { } ,
"custom" : { } ,
} ,
scheduled : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { } ,
} ,
retry : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-11-28 14:27:54 +08:00
"default" : { } ,
"custom" : { } ,
} ,
qname : "custom" ,
force : false ,
} ,
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 } ,
"custom" : { m3 } ,
} ,
active : map [ string ] [ ] * base . TaskMessage {
"default" : { } ,
"custom" : { } ,
} ,
scheduled : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { { Message : m4 , Score : time . Now ( ) . Unix ( ) } } ,
} ,
retry : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-11-28 14:27:54 +08:00
"default" : { } ,
"custom" : { } ,
} ,
qname : "custom" ,
force : true , // allow removing non-empty queue
} ,
}
for _ , tc := range tests {
h . FlushDB ( t , r )
h . SeedAllPendingQueues ( t , r , tc . pending )
h . SeedAllActiveQueues ( t , r , tc . active )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
h . SeedAllRetryQueues ( t , r , tc . retry )
2021-01-13 03:01:21 +08:00
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-11-28 14:27:54 +08:00
err := inspector . DeleteQueue ( tc . qname , tc . force )
if err != nil {
t . Errorf ( "DeleteQueue(%q, %t) = %v, want nil" ,
tc . qname , tc . force , err )
continue
}
if r . SIsMember ( base . AllQueues , tc . qname ) . Val ( ) {
t . Errorf ( "%q is a member of %q" , tc . qname , base . AllQueues )
}
}
}
func TestInspectorDeleteQueueErrorQueueNotEmpty ( t * testing . T ) {
r := setup ( t )
defer r . Close ( )
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-11-28 14:27:54 +08:00
defer inspector . Close ( )
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
tests := [ ] struct {
pending map [ string ] [ ] * base . TaskMessage
active map [ string ] [ ] * base . TaskMessage
scheduled map [ string ] [ ] base . Z
retry map [ string ] [ ] base . Z
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
2020-11-28 14:27:54 +08:00
qname string // queue to remove
force bool
} {
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 } ,
} ,
active : map [ string ] [ ] * base . TaskMessage {
"default" : { m3 , m4 } ,
} ,
scheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
retry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-11-28 14:27:54 +08:00
"default" : { } ,
} ,
qname : "default" ,
force : false ,
} ,
}
for _ , tc := range tests {
h . FlushDB ( t , r )
h . SeedAllPendingQueues ( t , r , tc . pending )
h . SeedAllActiveQueues ( t , r , tc . active )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
h . SeedAllRetryQueues ( t , r , tc . retry )
2021-01-13 03:01:21 +08:00
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-11-28 14:27:54 +08:00
err := inspector . DeleteQueue ( tc . qname , tc . force )
if _ , ok := err . ( * ErrQueueNotEmpty ) ; ! ok {
t . Errorf ( "DeleteQueue(%v, %t) did not return ErrQueueNotEmpty" ,
tc . qname , tc . force )
}
}
}
func TestInspectorDeleteQueueErrorQueueNotFound ( t * testing . T ) {
r := setup ( t )
defer r . Close ( )
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-11-28 14:27:54 +08:00
defer inspector . Close ( )
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
tests := [ ] struct {
pending map [ string ] [ ] * base . TaskMessage
active map [ string ] [ ] * base . TaskMessage
scheduled map [ string ] [ ] base . Z
retry map [ string ] [ ] base . Z
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
2020-11-28 14:27:54 +08:00
qname string // queue to remove
force bool
} {
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 } ,
} ,
active : map [ string ] [ ] * base . TaskMessage {
"default" : { m3 , m4 } ,
} ,
scheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
retry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-11-28 14:27:54 +08:00
"default" : { } ,
} ,
qname : "nonexistent" ,
force : false ,
} ,
}
for _ , tc := range tests {
h . FlushDB ( t , r )
h . SeedAllPendingQueues ( t , r , tc . pending )
h . SeedAllActiveQueues ( t , r , tc . active )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
h . SeedAllRetryQueues ( t , r , tc . retry )
2021-01-13 03:01:21 +08:00
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-11-28 14:27:54 +08:00
err := inspector . DeleteQueue ( tc . qname , tc . force )
if _ , ok := err . ( * ErrQueueNotFound ) ; ! ok {
t . Errorf ( "DeleteQueue(%v, %t) did not return ErrQueueNotFound" ,
tc . qname , tc . force )
}
}
}
2020-07-13 21:29:41 +08:00
func TestInspectorCurrentStats ( t * testing . T ) {
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessage ( "task4" , nil )
m5 := h . NewTaskMessageWithQueue ( "task5" , nil , "critical" )
2020-07-13 21:29:41 +08:00
m6 := h . NewTaskMessageWithQueue ( "task6" , nil , "low" )
now := time . Now ( )
timeCmpOpt := cmpopts . EquateApproxTime ( time . Second )
2021-01-27 10:36:45 +08:00
ignoreMemUsg := cmpopts . IgnoreFields ( QueueStats { } , "MemoryUsage" )
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-11-28 14:27:54 +08:00
pending map [ string ] [ ] * base . TaskMessage
active map [ string ] [ ] * base . TaskMessage
scheduled map [ string ] [ ] base . Z
retry map [ string ] [ ] base . Z
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
2020-11-28 14:27:54 +08:00
processed map [ string ] int
failed map [ string ] int
qname string
want * QueueStats
2020-07-13 21:29:41 +08:00
} {
{
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { m1 } ,
"critical" : { m5 } ,
"low" : { m6 } ,
} ,
2020-11-28 14:27:54 +08:00
active : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { m2 } ,
"critical" : { } ,
"low" : { } ,
} ,
scheduled : map [ string ] [ ] base . Z {
"default" : {
{ Message : m3 , Score : now . Add ( time . Hour ) . Unix ( ) } ,
{ Message : m4 , Score : now . Unix ( ) } ,
} ,
"critical" : { } ,
"low" : { } ,
} ,
2020-08-18 21:01:38 +08:00
retry : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"critical" : { } ,
"low" : { } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"critical" : { } ,
"low" : { } ,
} ,
processed : map [ string ] int {
"default" : 120 ,
"critical" : 100 ,
"low" : 42 ,
} ,
failed : map [ string ] int {
"default" : 2 ,
"critical" : 0 ,
"low" : 5 ,
} ,
qname : "default" ,
2020-08-21 21:00:49 +08:00
want : & QueueStats {
2020-09-06 03:43:15 +08:00
Queue : "default" ,
Size : 4 ,
Pending : 1 ,
Active : 1 ,
Scheduled : 2 ,
Retry : 0 ,
2021-01-13 03:01:21 +08:00
Archived : 0 ,
2020-09-06 03:43:15 +08:00
Processed : 120 ,
Failed : 2 ,
Paused : false ,
Timestamp : now ,
2020-07-13 21:29:41 +08:00
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllPendingQueues ( t , r , tc . pending )
h . SeedAllActiveQueues ( t , r , tc . active )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
h . SeedAllRetryQueues ( t , r , tc . retry )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-08-17 05:51:56 +08:00
for qname , n := range tc . processed {
processedKey := base . ProcessedKey ( qname , now )
2020-08-18 21:01:38 +08:00
r . Set ( processedKey , n , 0 )
2020-08-17 05:51:56 +08:00
}
for qname , n := range tc . failed {
failedKey := base . FailedKey ( qname , now )
2020-08-18 21:01:38 +08:00
r . Set ( failedKey , n , 0 )
2020-08-17 05:51:56 +08:00
}
got , err := inspector . CurrentStats ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-08-17 05:51:56 +08:00
t . Errorf ( "r.CurrentStats(%q) = %v, %v, want %v, nil" ,
tc . qname , got , err , tc . want )
2020-07-13 21:29:41 +08:00
continue
}
2021-01-27 10:36:45 +08:00
if diff := cmp . Diff ( tc . want , got , timeCmpOpt , ignoreMemUsg ) ; diff != "" {
2020-08-17 05:51:56 +08:00
t . Errorf ( "r.CurrentStats(%q) = %v, %v, want %v, nil; (-want, +got)\n%s" ,
tc . qname , got , err , tc . want , diff )
2020-07-13 21:29:41 +08:00
continue
}
}
}
func TestInspectorHistory ( t * testing . T ) {
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2020-07-13 21:29:41 +08:00
now := time . Now ( ) . UTC ( )
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-08-17 05:51:56 +08:00
qname string // queue of interest
n int // number of days
2020-07-13 21:29:41 +08:00
} {
2020-08-17 05:51:56 +08:00
{ "default" , 90 } ,
{ "custom" , 7 } ,
2020-08-21 21:00:49 +08:00
{ "default" , 1 } ,
2020-07-13 21:29:41 +08:00
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
2020-07-13 21:29:41 +08:00
2020-08-21 21:00:49 +08:00
r . SAdd ( base . AllQueues , tc . qname )
2020-07-13 21:29:41 +08:00
// populate last n days data
for i := 0 ; i < tc . n ; i ++ {
ts := now . Add ( - time . Duration ( i ) * 24 * time . Hour )
2020-08-17 05:51:56 +08:00
processedKey := base . ProcessedKey ( tc . qname , ts )
failedKey := base . FailedKey ( tc . qname , ts )
2020-07-13 21:29:41 +08:00
r . Set ( processedKey , ( i + 1 ) * 1000 , 0 )
r . Set ( failedKey , ( i + 1 ) * 10 , 0 )
}
2020-08-17 05:51:56 +08:00
got , err := inspector . History ( tc . qname , tc . n )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-08-17 05:51:56 +08:00
t . Errorf ( "Inspector.History(%q, %d) returned error: %v" , tc . qname , tc . n , err )
2020-07-13 21:29:41 +08:00
continue
}
if len ( got ) != tc . n {
2020-08-17 05:51:56 +08:00
t . Errorf ( "Inspector.History(%q, %d) returned %d daily stats, want %d" ,
tc . qname , tc . n , len ( got ) , tc . n )
2020-07-13 21:29:41 +08:00
continue
}
for i := 0 ; i < tc . n ; i ++ {
want := & DailyStats {
2020-08-17 05:51:56 +08:00
Queue : tc . qname ,
2020-07-13 21:29:41 +08:00
Processed : ( i + 1 ) * 1000 ,
Failed : ( i + 1 ) * 10 ,
Date : now . Add ( - time . Duration ( i ) * 24 * time . Hour ) ,
}
2020-09-10 10:17:56 +08:00
// Allow 2 seconds difference in timestamp.
timeCmpOpt := cmpopts . EquateApproxTime ( 2 * time . Second )
2020-07-13 21:29:41 +08:00
if diff := cmp . Diff ( want , got [ i ] , timeCmpOpt ) ; diff != "" {
t . Errorf ( "Inspector.History %d days ago data; got %+v, want %+v; (-want,+got):\n%s" ,
i , got [ i ] , want , diff )
}
}
}
}
2020-09-05 22:03:43 +08:00
func createPendingTask ( msg * base . TaskMessage ) * PendingTask {
return & PendingTask {
2021-01-29 00:59:13 +08:00
Task : asynq . NewTask ( msg . Type , msg . Payload ) ,
2021-01-27 22:59:32 +08:00
ID : msg . ID . String ( ) ,
Queue : msg . Queue ,
MaxRetry : msg . Retry ,
Retried : msg . Retried ,
LastError : msg . ErrorMsg ,
2020-07-13 21:29:41 +08:00
}
}
2020-09-05 22:03:43 +08:00
func TestInspectorListPendingTasks ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
2021-03-13 08:23:08 +08:00
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "critical" )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "low" )
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-09-05 22:03:43 +08:00
desc string
pending map [ string ] [ ] * base . TaskMessage
qname string
want [ ] * PendingTask
2020-07-13 21:29:41 +08:00
} {
{
desc : "with default queue" ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m1 , m2 } ,
} ,
qname : "default" ,
2020-09-05 22:03:43 +08:00
want : [ ] * PendingTask {
createPendingTask ( m1 ) ,
createPendingTask ( m2 ) ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
desc : "with named queue" ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m1 , m2 } ,
"critical" : { m3 } ,
"low" : { m4 } ,
} ,
qname : "critical" ,
2020-09-05 22:03:43 +08:00
want : [ ] * PendingTask {
createPendingTask ( m3 ) ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
desc : "with empty queue" ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { } ,
} ,
qname : "default" ,
2020-09-05 22:03:43 +08:00
want : [ ] * PendingTask ( nil ) ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
2020-09-05 22:03:43 +08:00
for q , msgs := range tc . pending {
2021-01-29 00:59:13 +08:00
h . SeedPendingQueue ( t , r , msgs , q )
2020-07-13 21:29:41 +08:00
}
2020-09-05 22:03:43 +08:00
got , err := inspector . ListPendingTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-09-05 22:03:43 +08:00
t . Errorf ( "%s; ListPendingTasks(%q) returned error: %v" ,
2020-07-13 21:29:41 +08:00
tc . desc , tc . qname , err )
continue
}
2021-01-29 00:59:13 +08:00
ignoreOpt := cmpopts . IgnoreUnexported ( asynq . Payload { } )
2020-07-13 21:29:41 +08:00
if diff := cmp . Diff ( tc . want , got , ignoreOpt ) ; diff != "" {
2020-09-05 22:03:43 +08:00
t . Errorf ( "%s; ListPendingTasks(%q) = %v, want %v; (-want,+got)\n%s" ,
2020-07-13 21:29:41 +08:00
tc . desc , tc . qname , got , tc . want , diff )
}
}
}
2020-09-06 03:43:15 +08:00
func TestInspectorListActiveTasks ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
2021-03-13 08:23:08 +08:00
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
2020-09-06 03:43:15 +08:00
createActiveTask := func ( msg * base . TaskMessage ) * ActiveTask {
return & ActiveTask {
2021-01-29 00:59:13 +08:00
Task : asynq . NewTask ( msg . Type , msg . Payload ) ,
2021-01-27 22:59:32 +08:00
ID : msg . ID . String ( ) ,
Queue : msg . Queue ,
MaxRetry : msg . Retry ,
Retried : msg . Retried ,
LastError : msg . ErrorMsg ,
2020-07-13 21:29:41 +08:00
}
}
tests := [ ] struct {
2020-11-28 14:27:54 +08:00
desc string
active map [ string ] [ ] * base . TaskMessage
qname string
want [ ] * ActiveTask
2020-07-13 21:29:41 +08:00
} {
{
2020-09-06 03:43:15 +08:00
desc : "with a few active tasks" ,
2020-11-28 14:27:54 +08:00
active : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { m1 , m2 } ,
"custom" : { m3 , m4 } ,
} ,
qname : "default" ,
2020-09-06 03:43:15 +08:00
want : [ ] * ActiveTask {
createActiveTask ( m1 ) ,
createActiveTask ( m2 ) ,
2020-07-13 21:29:41 +08:00
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllActiveQueues ( t , r , tc . active )
2020-07-13 21:29:41 +08:00
2020-09-06 03:43:15 +08:00
got , err := inspector . ListActiveTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-09-06 03:43:15 +08:00
t . Errorf ( "%s; ListActiveTasks(%q) returned error: %v" , tc . qname , tc . desc , err )
2020-07-13 21:29:41 +08:00
continue
}
2021-01-29 00:59:13 +08:00
ignoreOpt := cmpopts . IgnoreUnexported ( asynq . Payload { } )
2020-07-13 21:29:41 +08:00
if diff := cmp . Diff ( tc . want , got , ignoreOpt ) ; diff != "" {
2020-09-06 03:43:15 +08:00
t . Errorf ( "%s; ListActiveTask(%q) = %v, want %v; (-want,+got)\n%s" ,
2020-08-17 05:51:56 +08:00
tc . desc , tc . qname , got , tc . want , diff )
2020-07-13 21:29:41 +08:00
}
}
}
2020-08-17 05:51:56 +08:00
func createScheduledTask ( z base . Z ) * ScheduledTask {
msg := z . Message
return & ScheduledTask {
2021-01-29 00:59:13 +08:00
Task : asynq . NewTask ( msg . Type , msg . Payload ) ,
2020-08-17 05:51:56 +08:00
ID : msg . ID . String ( ) ,
Queue : msg . Queue ,
2021-01-27 22:59:32 +08:00
MaxRetry : msg . Retry ,
Retried : msg . Retried ,
LastError : msg . ErrorMsg ,
2020-09-05 22:11:55 +08:00
NextProcessAt : time . Unix ( z . Score , 0 ) ,
2020-08-19 20:45:02 +08:00
score : z . Score ,
2020-08-17 05:51:56 +08:00
}
}
2020-07-13 21:29:41 +08:00
func TestInspectorListScheduledTasks ( t * testing . T ) {
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
desc string
2020-08-17 05:51:56 +08:00
scheduled map [ string ] [ ] base . Z
qname string
2020-07-13 21:29:41 +08:00
want [ ] * ScheduledTask
} {
{
2020-08-17 05:51:56 +08:00
desc : "with a few scheduled tasks" ,
scheduled : map [ string ] [ ] base . Z {
"default" : { z1 , z2 , z3 } ,
"custom" : { z4 } ,
} ,
qname : "default" ,
2020-09-05 22:11:55 +08:00
// Should be sorted by NextProcessAt.
2020-07-13 21:29:41 +08:00
want : [ ] * ScheduledTask {
createScheduledTask ( z3 ) ,
createScheduledTask ( z1 ) ,
createScheduledTask ( z2 ) ,
} ,
} ,
{
2020-08-17 05:51:56 +08:00
desc : "with empty scheduled queue" ,
scheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
qname : "default" ,
want : [ ] * ScheduledTask ( nil ) ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
2020-07-13 21:29:41 +08:00
2020-08-18 21:01:38 +08:00
got , err := inspector . ListScheduledTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-08-17 05:51:56 +08:00
t . Errorf ( "%s; ListScheduledTasks(%q) returned error: %v" , tc . desc , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
2021-01-29 00:59:13 +08:00
ignoreOpt := cmpopts . IgnoreUnexported ( asynq . Payload { } , ScheduledTask { } )
2020-07-13 21:29:41 +08:00
if diff := cmp . Diff ( tc . want , got , ignoreOpt ) ; diff != "" {
2020-08-17 05:51:56 +08:00
t . Errorf ( "%s; ListScheduledTask(%q) = %v, want %v; (-want,+got)\n%s" ,
tc . desc , tc . qname , got , tc . want , diff )
2020-07-13 21:29:41 +08:00
}
}
}
2020-08-17 05:51:56 +08:00
func createRetryTask ( z base . Z ) * RetryTask {
msg := z . Message
return & RetryTask {
2021-01-29 00:59:13 +08:00
Task : asynq . NewTask ( msg . Type , msg . Payload ) ,
2020-08-17 05:51:56 +08:00
ID : msg . ID . String ( ) ,
Queue : msg . Queue ,
2020-09-05 22:11:55 +08:00
NextProcessAt : time . Unix ( z . Score , 0 ) ,
2020-08-17 05:51:56 +08:00
MaxRetry : msg . Retry ,
Retried : msg . Retried ,
2021-01-27 22:59:32 +08:00
LastError : msg . ErrorMsg ,
2020-08-19 20:45:02 +08:00
score : z . Score ,
2020-08-17 05:51:56 +08:00
}
}
2020-07-13 21:29:41 +08:00
func TestInspectorListRetryTasks ( t * testing . T ) {
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
desc string
2020-08-17 05:51:56 +08:00
retry map [ string ] [ ] base . Z
qname string
2020-07-13 21:29:41 +08:00
want [ ] * RetryTask
} {
{
2020-08-17 05:51:56 +08:00
desc : "with a few retry tasks" ,
retry : map [ string ] [ ] base . Z {
"default" : { z1 , z2 , z3 } ,
"custom" : { z4 } ,
} ,
qname : "default" ,
2020-09-05 22:11:55 +08:00
// Should be sorted by NextProcessAt.
2020-07-13 21:29:41 +08:00
want : [ ] * RetryTask {
createRetryTask ( z3 ) ,
createRetryTask ( z1 ) ,
createRetryTask ( z2 ) ,
} ,
} ,
{
2020-08-17 05:51:56 +08:00
desc : "with empty retry queue" ,
retry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
qname : "default" ,
2020-07-13 21:29:41 +08:00
want : [ ] * RetryTask ( nil ) ,
} ,
2020-08-17 05:51:56 +08:00
// TODO(hibiken): ErrQueueNotFound when queue doesn't exist
2020-07-13 21:29:41 +08:00
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllRetryQueues ( t , r , tc . retry )
2020-07-13 21:29:41 +08:00
2020-08-18 21:01:38 +08:00
got , err := inspector . ListRetryTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-08-17 05:51:56 +08:00
t . Errorf ( "%s; ListRetryTasks(%q) returned error: %v" , tc . desc , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
2021-01-29 00:59:13 +08:00
ignoreOpt := cmpopts . IgnoreUnexported ( asynq . Payload { } , RetryTask { } )
2020-07-13 21:29:41 +08:00
if diff := cmp . Diff ( tc . want , got , ignoreOpt ) ; diff != "" {
2020-08-17 05:51:56 +08:00
t . Errorf ( "%s; ListRetryTask(%q) = %v, want %v; (-want,+got)\n%s" ,
tc . desc , tc . qname , got , tc . want , diff )
2020-07-13 21:29:41 +08:00
}
}
}
2021-01-13 03:01:21 +08:00
func createArchivedTask ( z base . Z ) * ArchivedTask {
2020-08-17 05:51:56 +08:00
msg := z . Message
2021-01-13 03:01:21 +08:00
return & ArchivedTask {
2021-01-29 00:59:13 +08:00
Task : asynq . NewTask ( msg . Type , msg . Payload ) ,
2020-08-17 05:51:56 +08:00
ID : msg . ID . String ( ) ,
Queue : msg . Queue ,
MaxRetry : msg . Retry ,
Retried : msg . Retried ,
LastFailedAt : time . Unix ( z . Score , 0 ) ,
2021-01-27 22:59:32 +08:00
LastError : msg . ErrorMsg ,
2020-08-19 20:45:02 +08:00
score : z . Score ,
2020-08-17 05:51:56 +08:00
}
}
2021-01-13 03:01:21 +08:00
func TestInspectorListArchivedTasks ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( - 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( - 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( - 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( - 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2021-01-13 03:01:21 +08:00
desc string
archived map [ string ] [ ] base . Z
qname string
want [ ] * ArchivedTask
2020-07-13 21:29:41 +08:00
} {
{
2021-01-13 03:01:21 +08:00
desc : "with a few archived tasks" ,
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 , z2 , z3 } ,
"custom" : { z4 } ,
} ,
qname : "default" ,
2020-07-13 21:29:41 +08:00
// Should be sorted by LastFailedAt.
2021-01-13 03:01:21 +08:00
want : [ ] * ArchivedTask {
createArchivedTask ( z2 ) ,
createArchivedTask ( z1 ) ,
createArchivedTask ( z3 ) ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2021-01-13 03:01:21 +08:00
desc : "with empty archived queue" ,
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
} ,
qname : "default" ,
2021-01-13 03:01:21 +08:00
want : [ ] * ArchivedTask ( nil ) ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-07-13 21:29:41 +08:00
2021-01-13 03:01:21 +08:00
got , err := inspector . ListArchivedTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2021-01-13 03:01:21 +08:00
t . Errorf ( "%s; ListArchivedTasks(%q) returned error: %v" , tc . desc , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
2021-01-29 00:59:13 +08:00
ignoreOpt := cmpopts . IgnoreUnexported ( asynq . Payload { } , ArchivedTask { } )
2020-07-13 21:29:41 +08:00
if diff := cmp . Diff ( tc . want , got , ignoreOpt ) ; diff != "" {
2021-01-13 03:01:21 +08:00
t . Errorf ( "%s; ListArchivedTask(%q) = %v, want %v; (-want,+got)\n%s" ,
2020-08-17 05:51:56 +08:00
tc . desc , tc . qname , got , tc . want , diff )
2020-07-13 21:29:41 +08:00
}
}
}
func TestInspectorListPagination ( t * testing . T ) {
// Create 100 tasks.
var msgs [ ] * base . TaskMessage
for i := 0 ; i <= 99 ; i ++ {
msgs = append ( msgs ,
2021-01-29 00:59:13 +08:00
h . NewTaskMessage ( fmt . Sprintf ( "task%d" , i ) , nil ) )
2020-07-13 21:29:41 +08:00
}
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
h . SeedPendingQueue ( t , r , msgs , base . DefaultQueueName )
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
page int
pageSize int
2020-09-05 22:03:43 +08:00
want [ ] * PendingTask
2020-07-13 21:29:41 +08:00
} {
{
page : 1 ,
pageSize : 5 ,
2020-09-05 22:03:43 +08:00
want : [ ] * PendingTask {
createPendingTask ( msgs [ 0 ] ) ,
createPendingTask ( msgs [ 1 ] ) ,
createPendingTask ( msgs [ 2 ] ) ,
createPendingTask ( msgs [ 3 ] ) ,
createPendingTask ( msgs [ 4 ] ) ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
page : 3 ,
pageSize : 10 ,
2020-09-05 22:03:43 +08:00
want : [ ] * PendingTask {
createPendingTask ( msgs [ 20 ] ) ,
createPendingTask ( msgs [ 21 ] ) ,
createPendingTask ( msgs [ 22 ] ) ,
createPendingTask ( msgs [ 23 ] ) ,
createPendingTask ( msgs [ 24 ] ) ,
createPendingTask ( msgs [ 25 ] ) ,
createPendingTask ( msgs [ 26 ] ) ,
createPendingTask ( msgs [ 27 ] ) ,
createPendingTask ( msgs [ 28 ] ) ,
createPendingTask ( msgs [ 29 ] ) ,
2020-07-13 21:29:41 +08:00
} ,
} ,
}
for _ , tc := range tests {
2020-09-05 22:03:43 +08:00
got , err := inspector . ListPendingTasks ( "default" , Page ( tc . page ) , PageSize ( tc . pageSize ) )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-09-05 22:03:43 +08:00
t . Errorf ( "ListPendingTask('default') returned error: %v" , err )
2020-07-13 21:29:41 +08:00
continue
}
2021-01-29 00:59:13 +08:00
ignoreOpt := cmpopts . IgnoreUnexported ( asynq . Payload { } )
2020-07-13 21:29:41 +08:00
if diff := cmp . Diff ( tc . want , got , ignoreOpt ) ; diff != "" {
2020-09-05 22:03:43 +08:00
t . Errorf ( "ListPendingTask('default') = %v, want %v; (-want,+got)\n%s" ,
2020-07-13 21:29:41 +08:00
got , tc . want , diff )
}
}
}
2021-01-21 07:03:34 +08:00
func TestInspectorDeleteAllPendingTasks ( t * testing . T ) {
r := setup ( t )
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
2021-01-21 07:03:34 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2021-01-21 07:03:34 +08:00
tests := [ ] struct {
pending map [ string ] [ ] * base . TaskMessage
qname string
want int
wantPending map [ string ] [ ] * base . TaskMessage
} {
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 , m3 } ,
"custom" : { m4 } ,
} ,
qname : "default" ,
want : 3 ,
wantPending : map [ string ] [ ] * base . TaskMessage {
"default" : { } ,
"custom" : { m4 } ,
} ,
} ,
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 , m3 } ,
"custom" : { m4 } ,
} ,
qname : "custom" ,
want : 1 ,
wantPending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 , m3 } ,
"custom" : { } ,
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllPendingQueues ( t , r , tc . pending )
2021-01-21 07:03:34 +08:00
got , err := inspector . DeleteAllPendingTasks ( tc . qname )
if err != nil {
t . Errorf ( "DeleteAllPendingTasks(%q) returned error: %v" , tc . qname , err )
continue
}
if got != tc . want {
t . Errorf ( "DeleteAllPendingTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
}
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
gotPending := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , gotPending , h . SortMsgOpt ) ; diff != "" {
2021-01-21 07:03:34 +08:00
t . Errorf ( "unexpected pending tasks in queue %q: (-want, +got)\n%s" , qname , diff )
}
}
}
}
2020-07-13 21:29:41 +08:00
func TestInspectorDeleteAllScheduledTasks ( t * testing . T ) {
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-08-18 21:46:19 +08:00
scheduled map [ string ] [ ] base . Z
qname string
want int
wantScheduled map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { z1 , z2 , z3 } ,
"custom" : { z4 } ,
} ,
qname : "default" ,
want : 3 ,
2020-08-18 21:46:19 +08:00
wantScheduled : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { z4 } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
{
2020-08-17 05:51:56 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
qname : "default" ,
want : 0 ,
2020-08-18 21:46:19 +08:00
wantScheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
2020-07-13 21:29:41 +08:00
2020-08-17 05:51:56 +08:00
got , err := inspector . DeleteAllScheduledTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-08-17 05:51:56 +08:00
t . Errorf ( "DeleteAllScheduledTasks(%q) returned error: %v" , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
if got != tc . want {
2020-08-17 05:51:56 +08:00
t . Errorf ( "DeleteAllScheduledTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
2020-07-13 21:29:41 +08:00
}
2020-08-18 21:46:19 +08:00
for qname , want := range tc . wantScheduled {
2021-01-29 00:59:13 +08:00
gotScheduled := h . GetScheduledEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotScheduled , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-18 21:46:19 +08:00
t . Errorf ( "unexpected scheduled tasks in queue %q: (-want, +got)\n%s" , qname , diff )
}
2020-07-13 21:29:41 +08:00
}
}
}
func TestInspectorDeleteAllRetryTasks ( t * testing . T ) {
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-08-18 21:46:19 +08:00
retry map [ string ] [ ] base . Z
qname string
want int
wantRetry map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { z1 , z2 , z3 } ,
"custom" : { z4 } ,
} ,
qname : "default" ,
2020-07-13 21:29:41 +08:00
want : 3 ,
2020-08-18 21:46:19 +08:00
wantRetry : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { z4 } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
qname : "default" ,
2020-07-13 21:29:41 +08:00
want : 0 ,
2020-08-18 21:46:19 +08:00
wantRetry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllRetryQueues ( t , r , tc . retry )
2020-07-13 21:29:41 +08:00
2020-08-17 05:51:56 +08:00
got , err := inspector . DeleteAllRetryTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-08-17 05:51:56 +08:00
t . Errorf ( "DeleteAllRetryTasks(%q) returned error: %v" , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
if got != tc . want {
2020-08-17 05:51:56 +08:00
t . Errorf ( "DeleteAllRetryTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
2020-07-13 21:29:41 +08:00
}
2020-08-18 21:46:19 +08:00
for qname , want := range tc . wantRetry {
2021-01-29 00:59:13 +08:00
gotRetry := h . GetRetryEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotRetry , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-18 21:46:19 +08:00
t . Errorf ( "unexpected retry tasks in queue %q: (-want, +got)\n%s" , qname , diff )
}
2020-07-13 21:29:41 +08:00
}
}
}
2021-01-13 03:01:21 +08:00
func TestInspectorDeleteAllArchivedTasks ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
qname string
want int
wantArchived map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 , z2 , z3 } ,
"custom" : { z4 } ,
} ,
qname : "default" ,
want : 3 ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-18 21:46:19 +08:00
"default" : { } ,
"custom" : { z4 } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
{
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
} ,
qname : "default" ,
want : 0 ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-18 21:46:19 +08:00
"default" : { } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-07-13 21:29:41 +08:00
2021-01-13 03:01:21 +08:00
got , err := inspector . DeleteAllArchivedTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2021-01-13 03:01:21 +08:00
t . Errorf ( "DeleteAllArchivedTasks(%q) returned error: %v" , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
if got != tc . want {
2021-01-13 03:01:21 +08:00
t . Errorf ( "DeleteAllArchivedTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
2020-07-13 21:29:41 +08:00
}
2021-01-13 03:01:21 +08:00
for qname , want := range tc . wantArchived {
2021-01-29 00:59:13 +08:00
gotArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotArchived , h . SortZSetEntryOpt ) ; diff != "" {
2021-01-13 03:01:21 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-08-18 21:46:19 +08:00
}
2020-07-13 21:29:41 +08:00
}
}
}
2021-01-21 07:03:34 +08:00
func TestInspectorArchiveAllPendingTasks ( t * testing . T ) {
r := setup ( t )
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
2021-01-21 07:03:34 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2021-01-21 07:03:34 +08:00
tests := [ ] struct {
pending map [ string ] [ ] * base . TaskMessage
archived map [ string ] [ ] base . Z
qname string
want int
wantPending map [ string ] [ ] * base . TaskMessage
wantArchived map [ string ] [ ] base . Z
} {
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 , m3 } ,
"custom" : { m4 } ,
} ,
archived : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { } ,
} ,
qname : "default" ,
want : 3 ,
wantPending : map [ string ] [ ] * base . TaskMessage {
"default" : { } ,
"custom" : { m4 } ,
} ,
wantArchived : map [ string ] [ ] base . Z {
"default" : {
base . Z { Message : m1 , Score : now . Unix ( ) } ,
base . Z { Message : m2 , Score : now . Unix ( ) } ,
base . Z { Message : m3 , Score : now . Unix ( ) } ,
} ,
"custom" : { } ,
} ,
} ,
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { } ,
} ,
archived : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
qname : "default" ,
want : 0 ,
wantPending : map [ string ] [ ] * base . TaskMessage {
"default" : { } ,
} ,
wantArchived : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
} ,
{
pending : map [ string ] [ ] * base . TaskMessage {
2021-03-13 08:23:08 +08:00
"default" : { m3 } ,
2021-01-21 07:03:34 +08:00
} ,
archived : map [ string ] [ ] base . Z {
"default" : { z1 , z2 } ,
} ,
qname : "default" ,
2021-03-13 08:23:08 +08:00
want : 1 ,
2021-01-21 07:03:34 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
"default" : { } ,
} ,
wantArchived : map [ string ] [ ] base . Z {
"default" : {
z1 ,
z2 ,
base . Z { Message : m3 , Score : now . Unix ( ) } ,
} ,
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllPendingQueues ( t , r , tc . pending )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2021-01-21 07:03:34 +08:00
got , err := inspector . ArchiveAllPendingTasks ( tc . qname )
if err != nil {
t . Errorf ( "ArchiveAllPendingTasks(%q) returned error: %v" , tc . qname , err )
continue
}
if got != tc . want {
t . Errorf ( "ArchiveAllPendingTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
}
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
gotPending := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , gotPending , h . SortMsgOpt ) ; diff != "" {
2021-01-21 07:03:34 +08:00
t . Errorf ( "unexpected pending tasks in queue %q: (-want, +got)\n%s" , qname , diff )
}
}
for qname , want := range tc . wantArchived {
// Allow Z.Score to differ by up to 2.
approxOpt := cmp . Comparer ( func ( a , b int64 ) bool {
return math . Abs ( float64 ( a - b ) ) < 2
} )
2021-01-29 00:59:13 +08:00
gotArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotArchived , h . SortZSetEntryOpt , approxOpt ) ; diff != "" {
2021-01-21 07:03:34 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want, +got)\n%s" , qname , diff )
}
}
}
}
func TestInspectorArchiveAllScheduledTasks ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-08-17 05:51:56 +08:00
scheduled map [ string ] [ ] base . Z
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
2020-08-17 05:51:56 +08:00
qname string
want int
wantScheduled map [ string ] [ ] base . Z
2021-01-13 03:01:21 +08:00
wantArchived map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { z1 , z2 , z3 } ,
"custom" : { z4 } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"custom" : { } ,
} ,
qname : "default" ,
want : 3 ,
wantScheduled : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { z4 } ,
} ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : {
base . Z { Message : m1 , Score : now . Unix ( ) } ,
base . Z { Message : m2 , Score : now . Unix ( ) } ,
base . Z { Message : m3 , Score : now . Unix ( ) } ,
} ,
"custom" : { } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2020-08-18 21:01:38 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { z1 , z2 } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-18 21:01:38 +08:00
"default" : { z3 } ,
} ,
qname : "default" ,
want : 2 ,
wantScheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-18 21:01:38 +08:00
"default" : {
z3 ,
base . Z { Message : m1 , Score : now . Unix ( ) } ,
base . Z { Message : m2 , Score : now . Unix ( ) } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2020-08-18 21:01:38 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-18 21:01:38 +08:00
"default" : { } ,
} ,
qname : "default" ,
want : 0 ,
wantScheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-18 21:01:38 +08:00
"default" : { } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
{
2020-08-18 21:01:38 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-18 21:01:38 +08:00
"default" : { z1 , z2 } ,
} ,
qname : "default" ,
want : 0 ,
wantScheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-18 21:01:38 +08:00
"default" : { z1 , z2 } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-07-13 21:29:41 +08:00
2021-01-13 03:01:21 +08:00
got , err := inspector . ArchiveAllScheduledTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2021-01-21 07:03:34 +08:00
t . Errorf ( "ArchiveAllScheduledTasks(%q) returned error: %v" , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
if got != tc . want {
2021-01-21 07:03:34 +08:00
t . Errorf ( "ArchiveAllScheduledTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
2020-07-13 21:29:41 +08:00
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantScheduled {
2021-01-29 00:59:13 +08:00
gotScheduled := h . GetScheduledEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotScheduled , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-18 21:46:19 +08:00
t . Errorf ( "unexpected scheduled tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-08-17 05:51:56 +08:00
}
2020-07-13 21:29:41 +08:00
}
2021-01-13 03:01:21 +08:00
for qname , want := range tc . wantArchived {
2020-08-17 05:51:56 +08:00
// Allow Z.Score to differ by up to 2.
approxOpt := cmp . Comparer ( func ( a , b int64 ) bool {
return math . Abs ( float64 ( a - b ) ) < 2
} )
2021-01-29 00:59:13 +08:00
gotArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotArchived , h . SortZSetEntryOpt , approxOpt ) ; diff != "" {
2021-01-13 03:01:21 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-08-17 05:51:56 +08:00
}
2020-07-13 21:29:41 +08:00
}
}
}
2021-01-21 07:03:34 +08:00
func TestInspectorArchiveAllRetryTasks ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessage ( "task3" , nil )
m4 := h . NewTaskMessageWithQueue ( "task4" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2021-01-13 03:01:21 +08:00
retry map [ string ] [ ] base . Z
archived map [ string ] [ ] base . Z
qname string
want int
wantRetry map [ string ] [ ] base . Z
wantArchived map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { z1 , z2 , z3 } ,
"custom" : { z4 } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"custom" : { } ,
} ,
qname : "default" ,
2020-07-13 21:29:41 +08:00
want : 3 ,
2020-08-17 05:51:56 +08:00
wantRetry : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { z4 } ,
} ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : {
base . Z { Message : m1 , Score : now . Unix ( ) } ,
base . Z { Message : m2 , Score : now . Unix ( ) } ,
base . Z { Message : m3 , Score : now . Unix ( ) } ,
} ,
"custom" : { } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { z1 , z2 } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z3 } ,
} ,
qname : "default" ,
2020-07-13 21:29:41 +08:00
want : 2 ,
2020-08-17 05:51:56 +08:00
wantRetry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : {
z3 ,
base . Z { Message : m1 , Score : now . Unix ( ) } ,
base . Z { Message : m2 , Score : now . Unix ( ) } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 , z2 } ,
} ,
2020-08-29 21:54:08 +08:00
qname : "default" ,
want : 0 ,
2020-08-17 05:51:56 +08:00
wantRetry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 , z2 } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllRetryQueues ( t , r , tc . retry )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-07-13 21:29:41 +08:00
2021-01-13 03:01:21 +08:00
got , err := inspector . ArchiveAllRetryTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2021-01-21 07:03:34 +08:00
t . Errorf ( "ArchiveAllRetryTasks(%q) returned error: %v" , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
if got != tc . want {
2021-01-21 07:03:34 +08:00
t . Errorf ( "ArchiveAllRetryTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
2020-07-13 21:29:41 +08:00
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantRetry {
2021-01-29 00:59:13 +08:00
gotRetry := h . GetRetryEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotRetry , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-18 21:46:19 +08:00
t . Errorf ( "unexpected retry tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-08-17 05:51:56 +08:00
}
2020-07-13 21:29:41 +08:00
}
2021-01-29 00:59:13 +08:00
cmpOpt := h . EquateInt64Approx ( 2 ) // allow for 2 seconds difference in Z.Score
2021-01-13 03:01:21 +08:00
for qname , want := range tc . wantArchived {
2021-01-29 00:59:13 +08:00
wantArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , wantArchived , h . SortZSetEntryOpt , cmpOpt ) ; diff != "" {
2021-01-13 03:01:21 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-08-17 05:51:56 +08:00
}
2020-07-13 21:29:41 +08:00
}
}
}
2020-09-06 04:35:52 +08:00
func TestInspectorRunAllScheduledTasks ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessageWithQueue ( "task2" , nil , "critical" )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "low" )
m4 := h . NewTaskMessage ( "task4" , nil )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-08-17 05:51:56 +08:00
scheduled map [ string ] [ ] base . Z
2020-09-05 22:03:43 +08:00
pending map [ string ] [ ] * base . TaskMessage
2020-08-17 05:51:56 +08:00
qname string
want int
wantScheduled map [ string ] [ ] base . Z
2020-09-05 22:03:43 +08:00
wantPending map [ string ] [ ] * base . TaskMessage
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { z1 , z4 } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { } ,
"critical" : { } ,
"low" : { } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "default" ,
want : 2 ,
wantScheduled : map [ string ] [ ] base . Z {
"default" : { } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { m1 , m4 } ,
"critical" : { } ,
"low" : { } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2020-08-17 05:51:56 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m4 } ,
"critical" : { } ,
"low" : { } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "default" ,
want : 1 ,
wantScheduled : map [ string ] [ ] base . Z {
"default" : { } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m4 , m1 } ,
2020-08-17 05:51:56 +08:00
"critical" : { } ,
"low" : { } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2020-08-17 05:51:56 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m1 , m4 } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "default" ,
want : 0 ,
wantScheduled : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m1 , m4 } ,
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
h . SeedAllPendingQueues ( t , r , tc . pending )
2020-07-13 21:29:41 +08:00
2020-09-06 04:35:52 +08:00
got , err := inspector . RunAllScheduledTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-09-06 04:35:52 +08:00
t . Errorf ( "RunAllScheduledTasks(%q) returned error: %v" , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
if got != tc . want {
2020-09-06 04:35:52 +08:00
t . Errorf ( "RunAllScheduledTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
2020-07-13 21:29:41 +08:00
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantScheduled {
2021-01-29 00:59:13 +08:00
gotScheduled := h . GetScheduledEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotScheduled , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-18 21:46:19 +08:00
t . Errorf ( "unexpected scheduled tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-08-17 05:51:56 +08:00
}
2020-07-13 21:29:41 +08:00
}
2020-09-05 22:03:43 +08:00
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
gotPending := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , gotPending , h . SortMsgOpt ) ; diff != "" {
2020-09-05 22:03:43 +08:00
t . Errorf ( "unexpected pending tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-07-13 21:29:41 +08:00
}
}
}
}
2020-09-06 04:35:52 +08:00
func TestInspectorRunAllRetryTasks ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessageWithQueue ( "task2" , nil , "critical" )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "low" )
m4 := h . NewTaskMessage ( "task2" , nil )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-09-05 22:03:43 +08:00
retry map [ string ] [ ] base . Z
pending map [ string ] [ ] * base . TaskMessage
qname string
want int
wantRetry map [ string ] [ ] base . Z
wantPending map [ string ] [ ] * base . TaskMessage
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { z1 , z4 } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { } ,
"critical" : { } ,
"low" : { } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "default" ,
want : 2 ,
wantRetry : map [ string ] [ ] base . Z {
"default" : { } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { m1 , m4 } ,
"critical" : { } ,
"low" : { } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m4 } ,
"critical" : { } ,
"low" : { } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "default" ,
want : 1 ,
wantRetry : map [ string ] [ ] base . Z {
"default" : { } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m4 , m1 } ,
2020-08-19 20:45:02 +08:00
"critical" : { } ,
"low" : { } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m1 , m4 } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "default" ,
want : 0 ,
wantRetry : map [ string ] [ ] base . Z {
"default" : { } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m1 , m4 } ,
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllRetryQueues ( t , r , tc . retry )
h . SeedAllPendingQueues ( t , r , tc . pending )
2020-07-13 21:29:41 +08:00
2020-09-06 04:35:52 +08:00
got , err := inspector . RunAllRetryTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2020-09-06 04:35:52 +08:00
t . Errorf ( "RunAllRetryTasks(%q) returned error: %v" , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
if got != tc . want {
2020-09-06 04:35:52 +08:00
t . Errorf ( "RunAllRetryTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
2020-07-13 21:29:41 +08:00
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantRetry {
2021-01-29 00:59:13 +08:00
gotRetry := h . GetRetryEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotRetry , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-18 21:46:19 +08:00
t . Errorf ( "unexpected retry tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-08-17 05:51:56 +08:00
}
2020-07-13 21:29:41 +08:00
}
2020-09-05 22:03:43 +08:00
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
gotPending := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , gotPending , h . SortMsgOpt ) ; diff != "" {
2020-09-05 22:03:43 +08:00
t . Errorf ( "unexpected pending tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-07-13 21:29:41 +08:00
}
}
}
}
2020-08-17 05:51:56 +08:00
2021-01-13 03:01:21 +08:00
func TestInspectorRunAllArchivedTasks ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessageWithQueue ( "task2" , nil , "critical" )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "low" )
m4 := h . NewTaskMessage ( "task2" , nil )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( - 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( - 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( - 2 * time . Minute ) . Unix ( ) }
2020-08-17 05:51:56 +08:00
z4 := base . Z { Message : m4 , Score : now . Add ( - 2 * time . Minute ) . Unix ( ) }
2020-07-13 21:29:41 +08:00
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
pending map [ string ] [ ] * base . TaskMessage
qname string
want int
wantArchived map [ string ] [ ] base . Z
wantPending map [ string ] [ ] * base . TaskMessage
2020-07-13 21:29:41 +08:00
} {
{
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 , z4 } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { } ,
"critical" : { } ,
"low" : { } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "default" ,
want : 2 ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { m1 , m4 } ,
"critical" : { } ,
"low" : { } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 } ,
"critical" : { z2 } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m4 } ,
"critical" : { } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "default" ,
want : 1 ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"critical" : { z2 } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m4 , m1 } ,
2020-08-17 05:51:56 +08:00
"critical" : { } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
{
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m1 , m4 } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "default" ,
want : 0 ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { m1 , m4 } ,
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllArchivedQueues ( t , r , tc . archived )
h . SeedAllPendingQueues ( t , r , tc . pending )
2020-07-13 21:29:41 +08:00
2021-01-13 03:01:21 +08:00
got , err := inspector . RunAllArchivedTasks ( tc . qname )
2020-07-13 21:29:41 +08:00
if err != nil {
2021-01-13 03:01:21 +08:00
t . Errorf ( "RunAllArchivedTasks(%q) returned error: %v" , tc . qname , err )
2020-07-13 21:29:41 +08:00
continue
}
if got != tc . want {
2021-01-13 03:01:21 +08:00
t . Errorf ( "RunAllArchivedTasks(%q) = %d, want %d" , tc . qname , got , tc . want )
2020-07-13 21:29:41 +08:00
}
2021-01-13 03:01:21 +08:00
for qname , want := range tc . wantArchived {
2021-01-29 00:59:13 +08:00
wantArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , wantArchived , h . SortZSetEntryOpt ) ; diff != "" {
2021-01-13 03:01:21 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-08-17 05:51:56 +08:00
}
2020-07-13 21:29:41 +08:00
}
2020-09-05 22:03:43 +08:00
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
gotPending := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , gotPending , h . SortMsgOpt ) ; diff != "" {
2020-09-05 22:03:43 +08:00
t . Errorf ( "unexpected pending tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-07-13 21:29:41 +08:00
}
}
}
}
2021-01-21 07:03:34 +08:00
func TestInspectorDeleteTaskByKeyDeletesPendingTask ( t * testing . T ) {
r := setup ( t )
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
inspector := New ( getRedisConnOpt ( t ) )
2021-01-21 07:03:34 +08:00
tests := [ ] struct {
pending map [ string ] [ ] * base . TaskMessage
qname string
key string
wantPending map [ string ] [ ] * base . TaskMessage
} {
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 } ,
"custom" : { m3 } ,
} ,
qname : "default" ,
key : createPendingTask ( m2 ) . Key ( ) ,
wantPending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 } ,
"custom" : { m3 } ,
} ,
} ,
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 } ,
"custom" : { m3 } ,
} ,
qname : "custom" ,
key : createPendingTask ( m3 ) . Key ( ) ,
wantPending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 , m2 } ,
"custom" : { } ,
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllPendingQueues ( t , r , tc . pending )
2021-01-21 07:03:34 +08:00
if err := inspector . DeleteTaskByKey ( tc . qname , tc . key ) ; err != nil {
t . Errorf ( "DeleteTaskByKey(%q, %q) returned error: %v" ,
tc . qname , tc . key , err )
continue
}
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
got := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , got , h . SortMsgOpt ) ; diff != "" {
2021-01-21 07:03:34 +08:00
t . Errorf ( "unspected pending tasks in queue %q: (-want,+got):\n%s" ,
qname , diff )
continue
}
}
}
}
2020-07-13 21:29:41 +08:00
func TestInspectorDeleteTaskByKeyDeletesScheduledTask ( t * testing . T ) {
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-08-17 05:51:56 +08:00
scheduled map [ string ] [ ] base . Z
qname string
key string
wantScheduled map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { z1 , z2 } ,
"custom" : { z3 } ,
} ,
qname : "default" ,
key : createScheduledTask ( z2 ) . Key ( ) ,
wantScheduled : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"custom" : { z3 } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
2020-07-13 21:29:41 +08:00
2020-08-17 05:51:56 +08:00
if err := inspector . DeleteTaskByKey ( tc . qname , tc . key ) ; err != nil {
t . Errorf ( "DeleteTaskByKey(%q, %q) returned error: %v" , tc . qname , tc . key , err )
2020-07-13 21:29:41 +08:00
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantScheduled {
2021-01-29 00:59:13 +08:00
gotScheduled := h . GetScheduledEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotScheduled , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-18 21:46:19 +08:00
t . Errorf ( "unexpected scheduled tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-07-13 21:29:41 +08:00
}
2020-08-17 05:51:56 +08:00
2020-07-13 21:29:41 +08:00
}
}
}
func TestInspectorDeleteTaskByKeyDeletesRetryTask ( t * testing . T ) {
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-08-17 05:51:56 +08:00
retry map [ string ] [ ] base . Z
qname string
key string
wantRetry map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { z1 , z2 } ,
"custom" : { z3 } ,
} ,
qname : "default" ,
key : createRetryTask ( z2 ) . Key ( ) ,
wantRetry : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"custom" : { z3 } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllRetryQueues ( t , r , tc . retry )
2020-07-13 21:29:41 +08:00
2020-08-17 05:51:56 +08:00
if err := inspector . DeleteTaskByKey ( tc . qname , tc . key ) ; err != nil {
t . Errorf ( "DeleteTaskByKey(%q, %q) returned error: %v" , tc . qname , tc . key , err )
2020-07-13 21:29:41 +08:00
continue
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantRetry {
2021-01-29 00:59:13 +08:00
gotRetry := h . GetRetryEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotRetry , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-18 21:46:19 +08:00
t . Errorf ( "unexpected retry tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-07-13 21:29:41 +08:00
}
}
}
}
2021-01-13 03:01:21 +08:00
func TestInspectorDeleteTaskByKeyDeletesArchivedTask ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( - 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( - 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( - 2 * time . Minute ) . Unix ( ) }
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
qname string
key string
wantArchived map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 , z2 } ,
"custom" : { z3 } ,
} ,
qname : "default" ,
2021-01-13 03:01:21 +08:00
key : createArchivedTask ( z2 ) . Key ( ) ,
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 } ,
"custom" : { z3 } ,
} ,
2020-07-13 21:29:41 +08:00
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-07-13 21:29:41 +08:00
2020-08-17 05:51:56 +08:00
if err := inspector . DeleteTaskByKey ( tc . qname , tc . key ) ; err != nil {
t . Errorf ( "DeleteTaskByKey(%q, %q) returned error: %v" , tc . qname , tc . key , err )
2020-07-13 21:29:41 +08:00
continue
}
2021-01-13 03:01:21 +08:00
for qname , want := range tc . wantArchived {
2021-01-29 00:59:13 +08:00
wantArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , wantArchived , h . SortZSetEntryOpt ) ; diff != "" {
2021-01-13 03:01:21 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want, +got)\n%s" , qname , diff )
2020-07-13 21:29:41 +08:00
}
}
}
}
2020-09-06 04:35:52 +08:00
func TestInspectorRunTaskByKeyRunsScheduledTask ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessage ( "task2" , nil )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-08-17 05:51:56 +08:00
scheduled map [ string ] [ ] base . Z
2020-09-05 22:03:43 +08:00
pending map [ string ] [ ] * base . TaskMessage
2020-08-17 05:51:56 +08:00
qname string
key string
wantScheduled map [ string ] [ ] base . Z
2020-09-05 22:03:43 +08:00
wantPending map [ string ] [ ] * base . TaskMessage
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { z1 , z2 } ,
"custom" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"custom" : { } ,
} ,
qname : "default" ,
key : createScheduledTask ( z2 ) . Key ( ) ,
wantScheduled : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"custom" : { z3 } ,
2020-07-13 21:29:41 +08:00
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { m2 } ,
"custom" : { } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
h . SeedAllPendingQueues ( t , r , tc . pending )
2020-07-13 21:29:41 +08:00
2020-09-06 04:35:52 +08:00
if err := inspector . RunTaskByKey ( tc . qname , tc . key ) ; err != nil {
t . Errorf ( "RunTaskByKey(%q, %q) returned error: %v" , tc . qname , tc . key , err )
2020-07-13 21:29:41 +08:00
continue
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantScheduled {
2021-01-29 00:59:13 +08:00
gotScheduled := h . GetScheduledEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotScheduled , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-17 05:51:56 +08:00
t . Errorf ( "unexpected scheduled tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-07-13 21:29:41 +08:00
}
2020-08-17 05:51:56 +08:00
2020-07-13 21:29:41 +08:00
}
2020-09-05 22:03:43 +08:00
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
gotPending := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , gotPending , h . SortMsgOpt ) ; diff != "" {
2020-09-05 22:03:43 +08:00
t . Errorf ( "unexpected pending tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-07-13 21:29:41 +08:00
}
}
}
}
2020-09-06 04:35:52 +08:00
func TestInspectorRunTaskByKeyRunsRetryTask ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessageWithQueue ( "task2" , nil , "custom" )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-09-05 22:03:43 +08:00
retry map [ string ] [ ] base . Z
pending map [ string ] [ ] * base . TaskMessage
qname string
key string
wantRetry map [ string ] [ ] base . Z
wantPending map [ string ] [ ] * base . TaskMessage
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"custom" : { z2 , z3 } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"custom" : { } ,
} ,
qname : "custom" ,
key : createRetryTask ( z2 ) . Key ( ) ,
wantRetry : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"custom" : { z3 } ,
2020-07-13 21:29:41 +08:00
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"custom" : { m2 } ,
2020-07-13 21:29:41 +08:00
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllRetryQueues ( t , r , tc . retry )
h . SeedAllPendingQueues ( t , r , tc . pending )
2020-07-13 21:29:41 +08:00
2020-09-06 04:35:52 +08:00
if err := inspector . RunTaskByKey ( tc . qname , tc . key ) ; err != nil {
t . Errorf ( "RunTaskByKey(%q, %q) returned error: %v" , tc . qname , tc . key , err )
2020-07-13 21:29:41 +08:00
continue
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantRetry {
2021-01-29 00:59:13 +08:00
gotRetry := h . GetRetryEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotRetry , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-17 05:51:56 +08:00
t . Errorf ( "unexpected retry tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-07-13 21:29:41 +08:00
}
}
2020-09-05 22:03:43 +08:00
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
gotPending := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , gotPending , h . SortMsgOpt ) ; diff != "" {
2020-09-05 22:03:43 +08:00
t . Errorf ( "unexpected pending tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-07-13 21:29:41 +08:00
}
}
}
}
2021-01-13 03:01:21 +08:00
func TestInspectorRunTaskByKeyRunsArchivedTask ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessageWithQueue ( "task2" , nil , "critical" )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "low" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( - 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( - 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( - 2 * time . Minute ) . Unix ( ) }
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
pending map [ string ] [ ] * base . TaskMessage
qname string
key string
wantArchived map [ string ] [ ] base . Z
wantPending map [ string ] [ ] * base . TaskMessage
2020-07-13 21:29:41 +08:00
} {
{
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 } ,
"critical" : { z2 } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
pending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { } ,
"critical" : { } ,
"low" : { } ,
} ,
2020-08-17 05:51:56 +08:00
qname : "critical" ,
2021-01-13 03:01:21 +08:00
key : createArchivedTask ( z2 ) . Key ( ) ,
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 } ,
"critical" : { } ,
"low" : { z3 } ,
} ,
2020-09-05 22:03:43 +08:00
wantPending : map [ string ] [ ] * base . TaskMessage {
2020-07-13 21:29:41 +08:00
"default" : { } ,
"critical" : { m2 } ,
"low" : { } ,
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllArchivedQueues ( t , r , tc . archived )
h . SeedAllPendingQueues ( t , r , tc . pending )
2020-07-13 21:29:41 +08:00
2020-09-06 04:35:52 +08:00
if err := inspector . RunTaskByKey ( tc . qname , tc . key ) ; err != nil {
t . Errorf ( "RunTaskByKey(%q, %q) returned error: %v" , tc . qname , tc . key , err )
2020-07-13 21:29:41 +08:00
continue
}
2021-01-13 03:01:21 +08:00
for qname , want := range tc . wantArchived {
2021-01-29 00:59:13 +08:00
wantArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , wantArchived , h . SortZSetEntryOpt ) ; diff != "" {
2021-01-13 03:01:21 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-07-13 21:29:41 +08:00
}
}
2020-09-05 22:03:43 +08:00
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
gotPending := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , gotPending , h . SortMsgOpt ) ; diff != "" {
2020-09-05 22:03:43 +08:00
t . Errorf ( "unexpected pending tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-07-13 21:29:41 +08:00
}
}
}
}
2021-01-21 07:03:34 +08:00
func TestInspectorArchiveTaskByKeyArchivesPendingTask ( t * testing . T ) {
r := setup ( t )
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessageWithQueue ( "task2" , nil , "custom" )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
inspector := New ( getRedisConnOpt ( t ) )
2021-01-21 07:03:34 +08:00
now := time . Now ( )
tests := [ ] struct {
pending map [ string ] [ ] * base . TaskMessage
archived map [ string ] [ ] base . Z
qname string
key string
wantPending map [ string ] [ ] * base . TaskMessage
wantArchived map [ string ] [ ] base . Z
} {
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 } ,
"custom" : { m2 , m3 } ,
} ,
archived : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { } ,
} ,
qname : "default" ,
key : createPendingTask ( m1 ) . Key ( ) ,
wantPending : map [ string ] [ ] * base . TaskMessage {
"default" : { } ,
"custom" : { m2 , m3 } ,
} ,
wantArchived : map [ string ] [ ] base . Z {
"default" : {
{ Message : m1 , Score : now . Unix ( ) } ,
} ,
"custom" : { } ,
} ,
} ,
{
pending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 } ,
"custom" : { m2 , m3 } ,
} ,
archived : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : { } ,
} ,
qname : "custom" ,
key : createPendingTask ( m2 ) . Key ( ) ,
wantPending : map [ string ] [ ] * base . TaskMessage {
"default" : { m1 } ,
"custom" : { m3 } ,
} ,
wantArchived : map [ string ] [ ] base . Z {
"default" : { } ,
"custom" : {
{ Message : m2 , Score : now . Unix ( ) } ,
} ,
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllPendingQueues ( t , r , tc . pending )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2021-01-21 07:03:34 +08:00
if err := inspector . ArchiveTaskByKey ( tc . qname , tc . key ) ; err != nil {
t . Errorf ( "ArchiveTaskByKey(%q, %q) returned error: %v" ,
tc . qname , tc . key , err )
continue
}
for qname , want := range tc . wantPending {
2021-01-29 00:59:13 +08:00
gotPending := h . GetPendingMessages ( t , r , qname )
if diff := cmp . Diff ( want , gotPending , h . SortMsgOpt ) ; diff != "" {
2021-01-21 07:03:34 +08:00
t . Errorf ( "unexpected pending tasks in queue %q: (-want,+got)\n%s" ,
qname , diff )
}
}
for qname , want := range tc . wantArchived {
2021-01-29 00:59:13 +08:00
wantArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , wantArchived , h . SortZSetEntryOpt ) ; diff != "" {
2021-01-21 07:03:34 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want,+got)\n%s" ,
qname , diff )
}
}
}
}
func TestInspectorArchiveTaskByKeyArchivesScheduledTask ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessageWithQueue ( "task2" , nil , "custom" )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2020-08-17 05:51:56 +08:00
scheduled map [ string ] [ ] base . Z
2021-01-13 03:01:21 +08:00
archived map [ string ] [ ] base . Z
2020-08-17 05:51:56 +08:00
qname string
2020-08-18 21:01:38 +08:00
key string
2020-08-17 05:51:56 +08:00
want string
wantScheduled map [ string ] [ ] base . Z
2021-01-13 03:01:21 +08:00
wantArchived map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
scheduled : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"custom" : { z2 , z3 } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"custom" : { } ,
} ,
qname : "custom" ,
key : createScheduledTask ( z2 ) . Key ( ) ,
2020-08-18 21:01:38 +08:00
wantScheduled : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { z1 } ,
"custom" : { z3 } ,
} ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
2020-12-20 22:09:51 +08:00
"custom" : {
{
Message : m2 ,
Score : now . Unix ( ) ,
} ,
} ,
2020-07-13 21:29:41 +08:00
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllScheduledQueues ( t , r , tc . scheduled )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-07-13 21:29:41 +08:00
2021-01-13 03:01:21 +08:00
if err := inspector . ArchiveTaskByKey ( tc . qname , tc . key ) ; err != nil {
2021-01-21 07:03:34 +08:00
t . Errorf ( "ArchiveTaskByKey(%q, %q) returned error: %v" , tc . qname , tc . key , err )
2020-07-13 21:29:41 +08:00
continue
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantScheduled {
2021-01-29 00:59:13 +08:00
gotScheduled := h . GetScheduledEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotScheduled , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-17 05:51:56 +08:00
t . Errorf ( "unexpected scheduled tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-07-13 21:29:41 +08:00
}
2020-08-17 05:51:56 +08:00
2020-07-13 21:29:41 +08:00
}
2021-01-13 03:01:21 +08:00
for qname , want := range tc . wantArchived {
2021-01-29 00:59:13 +08:00
wantArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , wantArchived , h . SortZSetEntryOpt ) ; diff != "" {
2021-01-13 03:01:21 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-08-17 05:51:56 +08:00
}
2020-07-13 21:29:41 +08:00
}
}
}
2021-01-21 07:03:34 +08:00
func TestInspectorArchiveTaskByKeyArchivesRetryTask ( t * testing . T ) {
2020-07-13 21:29:41 +08:00
r := setup ( t )
2020-09-08 21:51:01 +08:00
defer r . Close ( )
2021-01-29 00:59:13 +08:00
m1 := h . NewTaskMessage ( "task1" , nil )
m2 := h . NewTaskMessageWithQueue ( "task2" , nil , "custom" )
m3 := h . NewTaskMessageWithQueue ( "task3" , nil , "custom" )
2020-07-13 21:29:41 +08:00
now := time . Now ( )
z1 := base . Z { Message : m1 , Score : now . Add ( 5 * time . Minute ) . Unix ( ) }
z2 := base . Z { Message : m2 , Score : now . Add ( 15 * time . Minute ) . Unix ( ) }
z3 := base . Z { Message : m3 , Score : now . Add ( 2 * time . Minute ) . Unix ( ) }
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-07-13 21:29:41 +08:00
tests := [ ] struct {
2021-01-13 03:01:21 +08:00
retry map [ string ] [ ] base . Z
archived map [ string ] [ ] base . Z
qname string
key string
wantRetry map [ string ] [ ] base . Z
wantArchived map [ string ] [ ] base . Z
2020-07-13 21:29:41 +08:00
} {
{
2020-08-17 05:51:56 +08:00
retry : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"custom" : { z2 , z3 } ,
} ,
2021-01-13 03:01:21 +08:00
archived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
"custom" : { } ,
} ,
qname : "custom" ,
key : createRetryTask ( z2 ) . Key ( ) ,
wantRetry : map [ string ] [ ] base . Z {
"default" : { z1 } ,
"custom" : { z3 } ,
} ,
2021-01-13 03:01:21 +08:00
wantArchived : map [ string ] [ ] base . Z {
2020-08-17 05:51:56 +08:00
"default" : { } ,
2020-12-20 22:09:51 +08:00
"custom" : {
{
Message : m2 ,
Score : now . Unix ( ) ,
} ,
} ,
2020-07-13 21:29:41 +08:00
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
h . SeedAllRetryQueues ( t , r , tc . retry )
h . SeedAllArchivedQueues ( t , r , tc . archived )
2020-07-13 21:29:41 +08:00
2021-01-13 03:01:21 +08:00
if err := inspector . ArchiveTaskByKey ( tc . qname , tc . key ) ; err != nil {
2021-01-21 07:03:34 +08:00
t . Errorf ( "ArchiveTaskByKey(%q, %q) returned error: %v" , tc . qname , tc . key , err )
2020-07-13 21:29:41 +08:00
continue
}
2020-08-17 05:51:56 +08:00
for qname , want := range tc . wantRetry {
2021-01-29 00:59:13 +08:00
gotRetry := h . GetRetryEntries ( t , r , qname )
if diff := cmp . Diff ( want , gotRetry , h . SortZSetEntryOpt ) ; diff != "" {
2020-08-17 05:51:56 +08:00
t . Errorf ( "unexpected retry tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-07-13 21:29:41 +08:00
}
}
2021-01-13 03:01:21 +08:00
for qname , want := range tc . wantArchived {
2021-01-29 00:59:13 +08:00
wantArchived := h . GetArchivedEntries ( t , r , qname )
if diff := cmp . Diff ( want , wantArchived , h . SortZSetEntryOpt ) ; diff != "" {
2021-01-13 03:01:21 +08:00
t . Errorf ( "unexpected archived tasks in queue %q: (-want, +got)\n%s" ,
2020-08-18 21:46:19 +08:00
qname , diff )
2020-08-17 05:51:56 +08:00
}
2020-07-13 21:29:41 +08:00
}
}
}
2020-12-01 23:37:09 +08:00
var sortSchedulerEntry = cmp . Transformer ( "SortSchedulerEntry" , func ( in [ ] * SchedulerEntry ) [ ] * SchedulerEntry {
out := append ( [ ] * SchedulerEntry ( nil ) , in ... )
sort . Slice ( out , func ( i , j int ) bool {
return out [ i ] . Spec < out [ j ] . Spec
} )
return out
} )
func TestInspectorSchedulerEntries ( t * testing . T ) {
r := setup ( t )
rdbClient := rdb . NewRDB ( r )
2021-01-29 00:59:13 +08:00
inspector := New ( getRedisConnOpt ( t ) )
2020-12-01 23:37:09 +08:00
now := time . Now ( ) . UTC ( )
schedulerID := "127.0.0.1:9876:abc123"
tests := [ ] struct {
data [ ] * base . SchedulerEntry // data to seed redis
want [ ] * SchedulerEntry
} {
{
data : [ ] * base . SchedulerEntry {
2021-01-29 00:59:13 +08:00
{
2020-12-01 23:37:09 +08:00
Spec : "* * * * *" ,
Type : "foo" ,
Payload : nil ,
Opts : nil ,
Next : now . Add ( 5 * time . Hour ) ,
Prev : now . Add ( - 2 * time . Hour ) ,
} ,
2021-01-29 00:59:13 +08:00
{
2020-12-01 23:37:09 +08:00
Spec : "@every 20m" ,
Type : "bar" ,
Payload : map [ string ] interface { } { "fiz" : "baz" } ,
Opts : [ ] string { ` Queue("bar") ` , ` MaxRetry(20) ` } ,
Next : now . Add ( 1 * time . Minute ) ,
Prev : now . Add ( - 19 * time . Minute ) ,
} ,
} ,
want : [ ] * SchedulerEntry {
2021-01-29 00:59:13 +08:00
{
2020-12-01 23:37:09 +08:00
Spec : "* * * * *" ,
2021-01-29 00:59:13 +08:00
Task : asynq . NewTask ( "foo" , nil ) ,
2020-12-01 23:37:09 +08:00
Opts : nil ,
Next : now . Add ( 5 * time . Hour ) ,
Prev : now . Add ( - 2 * time . Hour ) ,
} ,
2021-01-29 00:59:13 +08:00
{
2020-12-01 23:37:09 +08:00
Spec : "@every 20m" ,
2021-01-29 00:59:13 +08:00
Task : asynq . NewTask ( "bar" , map [ string ] interface { } { "fiz" : "baz" } ) ,
Opts : [ ] asynq . Option { asynq . Queue ( "bar" ) , asynq . MaxRetry ( 20 ) } ,
2020-12-01 23:37:09 +08:00
Next : now . Add ( 1 * time . Minute ) ,
Prev : now . Add ( - 19 * time . Minute ) ,
} ,
} ,
} ,
}
for _ , tc := range tests {
2021-01-29 00:59:13 +08:00
h . FlushDB ( t , r )
2020-12-01 23:37:09 +08:00
err := rdbClient . WriteSchedulerEntries ( schedulerID , tc . data , time . Minute )
if err != nil {
t . Fatalf ( "could not write data: %v" , err )
}
got , err := inspector . SchedulerEntries ( )
if err != nil {
t . Errorf ( "SchedulerEntries() returned error: %v" , err )
continue
}
2021-01-29 00:59:13 +08:00
ignoreOpt := cmpopts . IgnoreUnexported ( asynq . Payload { } )
2020-12-01 23:37:09 +08:00
if diff := cmp . Diff ( tc . want , got , sortSchedulerEntry , ignoreOpt ) ; diff != "" {
t . Errorf ( "SchedulerEntries() = %v, want %v; (-want,+got)\n%s" ,
got , tc . want , diff )
}
}
}
2021-01-29 00:59:13 +08:00
func TestParseOption ( t * testing . T ) {
oneHourFromNow := time . Now ( ) . Add ( 1 * time . Hour )
tests := [ ] struct {
s string
wantType asynq . OptionType
wantVal interface { }
} {
{ ` MaxRetry(10) ` , asynq . MaxRetryOpt , 10 } ,
{ ` Queue("email") ` , asynq . QueueOpt , "email" } ,
{ ` Timeout(3m) ` , asynq . TimeoutOpt , 3 * time . Minute } ,
{ asynq . Deadline ( oneHourFromNow ) . String ( ) , asynq . DeadlineOpt , oneHourFromNow } ,
{ ` Unique(1h) ` , asynq . UniqueOpt , 1 * time . Hour } ,
{ asynq . ProcessAt ( oneHourFromNow ) . String ( ) , asynq . ProcessAtOpt , oneHourFromNow } ,
{ ` ProcessIn(10m) ` , asynq . ProcessInOpt , 10 * time . Minute } ,
}
for _ , tc := range tests {
t . Run ( tc . s , func ( t * testing . T ) {
got , err := parseOption ( tc . s )
if err != nil {
t . Fatalf ( "returned error: %v" , err )
}
if got == nil {
t . Fatal ( "returned nil" )
}
if got . Type ( ) != tc . wantType {
t . Fatalf ( "got type %v, want type %v " , got . Type ( ) , tc . wantType )
}
switch tc . wantType {
case asynq . QueueOpt :
gotVal , ok := got . Value ( ) . ( string )
if ! ok {
t . Fatal ( "returned Option with non-string value" )
}
if gotVal != tc . wantVal . ( string ) {
t . Fatalf ( "got value %v, want %v" , gotVal , tc . wantVal )
}
case asynq . MaxRetryOpt :
gotVal , ok := got . Value ( ) . ( int )
if ! ok {
t . Fatal ( "returned Option with non-int value" )
}
if gotVal != tc . wantVal . ( int ) {
t . Fatalf ( "got value %v, want %v" , gotVal , tc . wantVal )
}
case asynq . TimeoutOpt , asynq . UniqueOpt , asynq . ProcessInOpt :
gotVal , ok := got . Value ( ) . ( time . Duration )
if ! ok {
t . Fatal ( "returned Option with non duration value" )
}
if gotVal != tc . wantVal . ( time . Duration ) {
t . Fatalf ( "got value %v, want %v" , gotVal , tc . wantVal )
}
case asynq . DeadlineOpt , asynq . ProcessAtOpt :
gotVal , ok := got . Value ( ) . ( time . Time )
if ! ok {
t . Fatal ( "returned Option with non time value" )
}
if cmp . Equal ( gotVal , tc . wantVal . ( time . Time ) ) {
t . Fatalf ( "got value %v, want %v" , gotVal , tc . wantVal )
}
default :
t . Fatalf ( "returned Option with unexpected type: %v" , got . Type ( ) )
}
} )
}
2021-01-31 02:43:57 +08:00
}