2020-02-13 09:12:09 +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.
|
|
|
|
|
|
|
|
package asynq
|
|
|
|
|
|
|
|
import (
|
2020-02-16 15:14:30 +08:00
|
|
|
"sync"
|
2020-02-13 09:12:09 +08:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/hibiken/asynq/internal/base"
|
|
|
|
"github.com/hibiken/asynq/internal/rdb"
|
2020-04-17 22:52:12 +08:00
|
|
|
"github.com/hibiken/asynq/internal/testbroker"
|
2020-02-13 09:12:09 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestSubscriber(t *testing.T) {
|
|
|
|
r := setup(t)
|
|
|
|
rdbClient := rdb.NewRDB(r)
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
registeredID string // ID for which cancel func is registered
|
|
|
|
publishID string // ID to be published
|
|
|
|
wantCalled bool // whether cancel func should be called
|
|
|
|
}{
|
|
|
|
{"abc123", "abc123", true},
|
|
|
|
{"abc456", "abc123", false},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range tests {
|
2020-02-17 06:42:21 +08:00
|
|
|
var mu sync.Mutex
|
2020-02-13 09:12:09 +08:00
|
|
|
called := false
|
|
|
|
fakeCancelFunc := func() {
|
2020-02-17 06:42:21 +08:00
|
|
|
mu.Lock()
|
|
|
|
defer mu.Unlock()
|
2020-02-13 09:12:09 +08:00
|
|
|
called = true
|
|
|
|
}
|
|
|
|
cancelations := base.NewCancelations()
|
|
|
|
cancelations.Add(tc.registeredID, fakeCancelFunc)
|
|
|
|
|
2020-03-09 22:11:16 +08:00
|
|
|
subscriber := newSubscriber(testLogger, rdbClient, cancelations)
|
2020-02-16 15:14:30 +08:00
|
|
|
var wg sync.WaitGroup
|
|
|
|
subscriber.start(&wg)
|
2020-04-17 22:52:12 +08:00
|
|
|
defer subscriber.terminate()
|
2020-02-13 09:12:09 +08:00
|
|
|
|
2020-04-16 23:58:44 +08:00
|
|
|
// wait for subscriber to establish connection to pubsub channel
|
|
|
|
time.Sleep(time.Second)
|
|
|
|
|
2020-02-13 09:12:09 +08:00
|
|
|
if err := rdbClient.PublishCancelation(tc.publishID); err != nil {
|
|
|
|
t.Fatalf("could not publish cancelation message: %v", err)
|
|
|
|
}
|
|
|
|
|
2020-04-16 23:58:44 +08:00
|
|
|
// wait for redis to publish message
|
2020-02-13 09:12:09 +08:00
|
|
|
time.Sleep(time.Second)
|
|
|
|
|
2020-02-17 06:42:21 +08:00
|
|
|
mu.Lock()
|
2020-02-13 09:12:09 +08:00
|
|
|
if called != tc.wantCalled {
|
|
|
|
if tc.wantCalled {
|
|
|
|
t.Errorf("fakeCancelFunc was not called, want the function to be called")
|
|
|
|
} else {
|
|
|
|
t.Errorf("fakeCancelFunc was called, want the function to not be called")
|
|
|
|
}
|
|
|
|
}
|
2020-02-17 06:42:21 +08:00
|
|
|
mu.Unlock()
|
2020-04-17 22:52:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSubscriberWithRedisDown(t *testing.T) {
|
|
|
|
defer func() {
|
|
|
|
if r := recover(); r != nil {
|
|
|
|
t.Errorf("panic occurred: %v", r)
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
r := rdb.NewRDB(setup(t))
|
|
|
|
testBroker := testbroker.NewTestBroker(r)
|
|
|
|
|
|
|
|
cancelations := base.NewCancelations()
|
|
|
|
subscriber := newSubscriber(testLogger, testBroker, cancelations)
|
|
|
|
subscriber.retryTimeout = 1 * time.Second // set shorter retry timeout for testing purpose.
|
|
|
|
|
|
|
|
testBroker.Sleep() // simulate a situation where subscriber cannot connect to redis.
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
subscriber.start(&wg)
|
|
|
|
defer subscriber.terminate()
|
|
|
|
|
|
|
|
time.Sleep(2 * time.Second) // subscriber should wait and retry connecting to redis.
|
|
|
|
|
|
|
|
testBroker.Wakeup() // simulate a situation where redis server is back online.
|
|
|
|
|
|
|
|
time.Sleep(2 * time.Second) // allow subscriber to establish pubsub channel.
|
|
|
|
|
|
|
|
const id = "test"
|
|
|
|
var (
|
|
|
|
mu sync.Mutex
|
|
|
|
called bool
|
|
|
|
)
|
|
|
|
cancelations.Add(id, func() {
|
|
|
|
mu.Lock()
|
|
|
|
defer mu.Unlock()
|
|
|
|
called = true
|
|
|
|
})
|
|
|
|
|
|
|
|
if err := r.PublishCancelation(id); err != nil {
|
|
|
|
t.Fatalf("could not publish cancelation message: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
time.Sleep(time.Second) // wait for redis to publish message.
|
2020-02-13 09:12:09 +08:00
|
|
|
|
2020-04-17 22:52:12 +08:00
|
|
|
mu.Lock()
|
|
|
|
if !called {
|
|
|
|
t.Errorf("cancel function was not called")
|
2020-02-13 09:12:09 +08:00
|
|
|
}
|
2020-04-17 22:52:12 +08:00
|
|
|
mu.Unlock()
|
2020-02-13 09:12:09 +08:00
|
|
|
}
|