tracker/cache/redis/redis_test.go

202 lines
4.5 KiB
Go

// Copyright 2013 The Chihaya Authors. All rights reserved.
// Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file.
package redis
import (
"crypto/rand"
"io"
"os"
"strconv"
"testing"
"github.com/garyburd/redigo/redis"
"github.com/pushrax/chihaya/config"
"github.com/pushrax/chihaya/models"
)
var (
testTorrentIDCounter uint64
testUserIDCounter uint64
testPeerIDCounter int
)
func createTestTorrentID() uint64 {
testTorrentIDCounter++
return testTorrentIDCounter
}
func createTestUserID() uint64 {
testUserIDCounter++
return testUserIDCounter
}
func createTestPeerID() string {
testPeerIDCounter++
return "-testPeerID-" + strconv.Itoa(testPeerIDCounter)
}
func createTestInfohash() string {
uuid := make([]byte, 40)
n, err := io.ReadFull(rand.Reader, uuid)
if n != len(uuid) || err != nil {
panic(err)
}
return string(uuid)
}
func createTestPasskey() string {
uuid := make([]byte, 40)
n, err := io.ReadFull(rand.Reader, uuid)
if n != len(uuid) || err != nil {
panic(err)
}
return string(uuid)
}
// Common interface for benchmarks and test error reporting
type TestReporter interface {
Error(args ...interface{})
Errorf(format string, args ...interface{})
Log(args ...interface{})
Logf(format string, args ...interface{})
}
func verifyErrNil(err error, t TestReporter) {
if err != nil {
t.Error(err)
}
}
func createTestTxObj(t TestReporter) *Tx {
testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH"))
conf := &testConfig.Cache
verifyErrNil(err, t)
testPool := &Pool{
conf: conf,
pool: redis.Pool{
MaxIdle: conf.MaxIdleConns,
IdleTimeout: conf.IdleTimeout.Duration,
Dial: makeDialFunc(conf),
TestOnBorrow: testOnBorrow,
},
}
txObj := &Tx{
conf: testPool.conf,
done: false,
multi: false,
Conn: testPool.pool.Get(),
}
verifyErrNil(err, t)
// Test connection before returning
_, err = txObj.Do("PING")
verifyErrNil(err, t)
return txObj
}
func createTestUser() models.User {
testUser := models.User{createTestUserID(), createTestPasskey(), 1.01, 1.0, 4, 2, 7}
return testUser
}
func createTestPeer(userID uint64, torrentID uint64) models.Peer {
return models.Peer{createTestPeerID(), userID, torrentID, "127.0.0.1", 6889, 1024, 3000, 4200, 11}
}
func createTestPeers(torrentID uint64, num int) map[string]models.Peer {
testPeers := make(map[string]models.Peer)
for i := 0; i < num; i++ {
tempPeer := createTestPeer(createTestUserID(), torrentID)
testPeers[tempPeer.ID] = tempPeer
}
return testPeers
}
func createTestTorrent() models.Torrent {
torrentInfohash := createTestInfohash()
torrentID := createTestTorrentID()
testSeeders := createTestPeers(torrentID, 4)
testLeechers := createTestPeers(torrentID, 2)
testTorrent := models.Torrent{torrentID, torrentInfohash, true, testSeeders, testLeechers, 11, 0.0, 0.0, 0}
return testTorrent
}
func TestFindUserSuccess(t *testing.T) {
testUser := createTestUser()
testTx := createTestTxObj(t)
hashkey := testTx.conf.Prefix + UserPrefix + testUser.Passkey
_, err := testTx.Do("DEL", hashkey)
verifyErrNil(err, t)
err = testTx.AddUser(&testUser)
verifyErrNil(err, t)
compareUser, exists := ExampleRedisTypesSchemaFindUser(testUser.Passkey, t)
if !exists {
t.Error("User not found!")
}
if testUser != *compareUser {
t.Errorf("user mismatch: %v vs. %v", compareUser, testUser)
}
}
func TestFindUserFail(t *testing.T) {
compareUser, exists := ExampleRedisTypesSchemaFindUser("not_a_user_passkey", t)
if exists {
t.Errorf("User %v found when none should exist!", compareUser)
}
}
func TestAddGetPeers(t *testing.T) {
testTx := createTestTxObj(t)
testTorrent := createTestTorrent()
setkey := testTx.conf.Prefix + SeederPrefix + strconv.FormatUint(testTorrent.ID, 36)
testTx.Do("DEL", setkey)
testTx.addPeers(testTorrent.Seeders, SeederPrefix)
peerMap, err := testTx.getPeers(testTorrent.ID, SeederPrefix)
if err != nil {
t.Error(err)
} else if len(peerMap) != len(testTorrent.Seeders) {
t.Error("Num Peers not equal")
}
}
// Legacy tests
func TestReadAfterWrite(t *testing.T) {
// Test requires panic
defer func() {
if err := recover(); err == nil {
t.Error("Read after write did not panic")
}
}()
testTx := createTestTxObj(t)
verifyErrNil(testTx.initiateWrite(), t)
verifyErrNil(testTx.initiateRead(), t)
}
func TestCloseClosedTransaction(t *testing.T) {
//require panic
defer func() {
if err := recover(); err == nil {
t.Error("Closing a closed transaction did not panic")
}
}()
testTx := createTestTxObj(t)
testTx.close()
testTx.close()
}