2020-01-03 10:13:16 +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.
2019-11-30 12:53:29 +08:00
package asynq
import (
2020-05-11 07:47:46 +08:00
"flag"
2019-11-30 12:53:29 +08:00
"sort"
2020-08-29 21:54:08 +08:00
"strings"
2019-11-30 12:53:29 +08:00
"testing"
2021-09-02 20:56:02 +08:00
"github.com/go-redis/redis/v8"
2019-11-30 12:53:29 +08:00
"github.com/google/go-cmp/cmp"
2019-12-30 01:41:00 +08:00
h "github.com/hibiken/asynq/internal/asynqtest"
2020-03-09 22:11:16 +08:00
"github.com/hibiken/asynq/internal/log"
2019-11-30 12:53:29 +08:00
)
2020-05-11 07:47:46 +08:00
//============================================================================
// This file defines helper functions and variables used in other test files.
//============================================================================
2019-11-30 12:53:29 +08:00
2020-05-11 07:47:46 +08:00
// variables used for package testing.
var (
redisAddr string
redisDB int
2020-08-29 21:54:08 +08:00
useRedisCluster bool
redisClusterAddrs string // comma-separated list of host:port
2020-05-11 07:47:46 +08:00
testLogLevel = FatalLevel
2020-01-19 02:17:39 +08:00
)
2020-05-11 07:47:46 +08:00
var testLogger * log . Logger
func init ( ) {
flag . StringVar ( & redisAddr , "redis_addr" , "localhost:6379" , "redis address to use in testing" )
flag . IntVar ( & redisDB , "redis_db" , 14 , "redis db number to use in testing" )
2020-08-29 21:54:08 +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" )
2020-05-11 07:47:46 +08:00
flag . Var ( & testLogLevel , "loglevel" , "log level to use in testing" )
testLogger = log . NewLogger ( nil )
2020-05-11 22:02:26 +08:00
testLogger . SetLevel ( toInternalLogLevel ( testLogLevel ) )
2020-05-11 07:47:46 +08:00
}
2020-03-09 22:11:16 +08:00
2020-08-29 21:54:08 +08:00
func setup ( tb testing . TB ) ( r redis . UniversalClient ) {
2020-01-01 04:36:46 +08:00
tb . Helper ( )
2020-08-29 21:54:08 +08:00
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 ,
} )
}
2019-12-04 13:01:26 +08:00
// Start each test with a clean slate.
2020-01-01 04:36:46 +08:00
h . FlushDB ( tb , r )
2019-12-04 13:01:26 +08:00
return r
}
2019-11-30 12:53:29 +08:00
2020-08-29 21:54:08 +08:00
func getRedisConnOpt ( tb testing . TB ) 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 RedisClusterClientOpt {
Addrs : addrs ,
}
}
return RedisClientOpt {
Addr : redisAddr ,
DB : redisDB ,
}
}
2019-11-30 12:53:29 +08:00
var sortTaskOpt = cmp . Transformer ( "SortMsg" , func ( in [ ] * Task ) [ ] * Task {
out := append ( [ ] * Task ( nil ) , in ... ) // Copy input to avoid mutating it
sort . Slice ( out , func ( i , j int ) bool {
2021-03-21 04:42:13 +08:00
return out [ i ] . Type ( ) < out [ j ] . Type ( )
2019-11-30 12:53:29 +08:00
} )
return out
} )
2020-03-26 22:31:08 +08:00
func TestParseRedisURI ( t * testing . T ) {
tests := [ ] struct {
uri string
want RedisConnOpt
} {
{
"redis://localhost:6379" ,
RedisClientOpt { Addr : "localhost:6379" } ,
} ,
{
"redis://localhost:6379/3" ,
RedisClientOpt { Addr : "localhost:6379" , DB : 3 } ,
} ,
{
"redis://:mypassword@localhost:6379" ,
RedisClientOpt { Addr : "localhost:6379" , Password : "mypassword" } ,
} ,
{
"redis://:mypassword@127.0.0.1:6379/11" ,
RedisClientOpt { Addr : "127.0.0.1:6379" , Password : "mypassword" , DB : 11 } ,
} ,
{
"redis-socket:///var/run/redis/redis.sock" ,
RedisClientOpt { Network : "unix" , Addr : "/var/run/redis/redis.sock" } ,
} ,
{
"redis-socket://:mypassword@/var/run/redis/redis.sock" ,
RedisClientOpt { Network : "unix" , Addr : "/var/run/redis/redis.sock" , Password : "mypassword" } ,
} ,
{
"redis-socket:///var/run/redis/redis.sock?db=7" ,
RedisClientOpt { Network : "unix" , Addr : "/var/run/redis/redis.sock" , DB : 7 } ,
} ,
{
"redis-socket://:mypassword@/var/run/redis/redis.sock?db=12" ,
RedisClientOpt { Network : "unix" , Addr : "/var/run/redis/redis.sock" , Password : "mypassword" , DB : 12 } ,
} ,
{
"redis-sentinel://localhost:5000,localhost:5001,localhost:5002?master=mymaster" ,
RedisFailoverClientOpt {
MasterName : "mymaster" ,
SentinelAddrs : [ ] string { "localhost:5000" , "localhost:5001" , "localhost:5002" } ,
} ,
} ,
{
"redis-sentinel://:mypassword@localhost:5000,localhost:5001,localhost:5002?master=mymaster" ,
RedisFailoverClientOpt {
MasterName : "mymaster" ,
SentinelAddrs : [ ] string { "localhost:5000" , "localhost:5001" , "localhost:5002" } ,
Password : "mypassword" ,
} ,
} ,
}
for _ , tc := range tests {
got , err := ParseRedisURI ( tc . uri )
if err != nil {
t . Errorf ( "ParseRedisURI(%q) returned an error: %v" , tc . uri , err )
continue
}
if diff := cmp . Diff ( tc . want , got ) ; diff != "" {
t . Errorf ( "ParseRedisURI(%q) = %+v, want %+v\n(-want,+got)\n%s" , tc . uri , got , tc . want , diff )
}
}
}
func TestParseRedisURIErrors ( t * testing . T ) {
tests := [ ] struct {
desc string
uri string
} {
{
"unsupported scheme" ,
"rdb://localhost:6379" ,
} ,
{
"missing scheme" ,
"localhost:6379" ,
} ,
{
"multiple db numbers" ,
"redis://localhost:6379/1,2,3" ,
} ,
{
"missing path for socket connection" ,
"redis-socket://?db=one" ,
} ,
{
"non integer for db numbers for socket" ,
"redis-socket:///some/path/to/redis?db=one" ,
} ,
}
for _ , tc := range tests {
_ , err := ParseRedisURI ( tc . uri )
if err == nil {
t . Errorf ( "%s: ParseRedisURI(%q) succeeded for malformed input, want error" ,
tc . desc , tc . uri )
}
}
}