gofmt, style improvements

This commit is contained in:
Jimmy Zelinskie 2013-08-31 15:06:42 -04:00
parent 49674de1c8
commit 24eff112f3
3 changed files with 81 additions and 120 deletions

View file

@ -145,7 +145,7 @@ func (tx *Tx) Rollback() error {
return cache.ErrTxDone return cache.ErrTxDone
} }
// Undoes watches and multi // Undoes watches and multi
if _, err := tx.Do("DISCARD") ; err != nil { if _, err := tx.Do("DISCARD"); err != nil {
return err return err
} }
tx.multi = false tx.multi = false

View file

@ -2,29 +2,25 @@
// Use of this source code is governed by the BSD 2-Clause license, // Use of this source code is governed by the BSD 2-Clause license,
// which can be found in the LICENSE file. // which can be found in the LICENSE file.
// Package redis implements the storage interface for a BitTorrent tracker.
// Benchmarks are at the top of the file, tests are at the bottom
package redis package redis
import ( import (
"github.com/garyburd/redigo/redis" "math/rand"
"github.com/pushrax/chihaya/cache"
"github.com/pushrax/chihaya/config"
"os" "os"
"strconv"
"testing" "testing"
"time" "time"
"math/rand"
"strconv" "github.com/garyburd/redigo/redis"
"github.com/pushrax/chihaya/cache"
"github.com/pushrax/chihaya/config"
) )
var( // Maximum number of parallel retries; depends on system latency
//maximum number of parallel retries, will depends on system latency const MAX_RETRIES = 9000
MAX_RETRIES = 9000
)
func CreateTestTxObj(t *testing.T) Tx { func CreateTestTxObj(t *testing.T) Tx {
//assumes TESTCONFIGPATH has been defined
testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH")) testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH"))
if err != nil { if err != nil {
t.Error(err) t.Error(err)
@ -36,32 +32,28 @@ func CreateTestTxObj(t *testing.T) Tx {
t.Fail() t.Fail()
} }
return Tx{&testConfig.Cache, false, false, testConn} return Tx{&testConfig.Cache, false, false, testConn}
} }
func SampleTransaction( testTx Tx, retries int, t *testing.T){ func SampleTransaction(testTx Tx, retries int, t *testing.T) {
defer func() { defer func() {
if rawError := recover(); rawError != nil { if err := recover(); err != nil {
t.Errorf("initiate read failed") t.Errorf("initiateRead() failed: %s", err)
t.Fail()
} }
} () }()
err := testTx.initiateRead() err := testTx.initiateRead()
if err != nil { if err != nil {
t.Fail() t.Error(err)
} }
_, err = testTx.Do("WATCH", "testKeyA") _, err = testTx.Do("WATCH", "testKeyA")
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
} }
_, err = redis.String(testTx.Do("GET", "testKeyA")) _, err = redis.String(testTx.Do("GET", "testKeyA"))
if err != nil { if err != nil {
if err == redis.ErrNil { if err == redis.ErrNil {
t.Log("redis.ErrNil") t.Log("redis.ErrNil")
} else { } else {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
} }
_, err = testTx.Do("WATCH", "testKeyB") _, err = testTx.Do("WATCH", "testKeyB")
@ -69,8 +61,7 @@ func SampleTransaction( testTx Tx, retries int, t *testing.T){
if err == redis.ErrNil { if err == redis.ErrNil {
t.Log("redis.ErrNil") t.Log("redis.ErrNil")
} else { } else {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
} }
_, err = redis.String(testTx.Do("GET", "testKeyB")) _, err = redis.String(testTx.Do("GET", "testKeyB"))
@ -78,143 +69,123 @@ func SampleTransaction( testTx Tx, retries int, t *testing.T){
if err == redis.ErrNil { if err == redis.ErrNil {
t.Log("redis.ErrNil") t.Log("redis.ErrNil")
} else { } else {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
} }
err = testTx.initiateWrite() err = testTx.initiateWrite()
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
//generate random data to set // Generate random data to set
randGen := rand.New(rand.NewSource(time.Now().UnixNano())) randGen := rand.New(rand.NewSource(time.Now().UnixNano()))
err = testTx.Send("SET", "testKeyA", strconv.Itoa(randGen.Int())) err = testTx.Send("SET", "testKeyA", strconv.Itoa(randGen.Int()))
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
err = testTx.Send("SET", "testKeyB", strconv.Itoa(randGen.Int())) err = testTx.Send("SET", "testKeyB", strconv.Itoa(randGen.Int()))
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
err = testTx.Commit() err = testTx.Commit()
//for parallel runs, there may be conflicts, retry until successful switch {
if err == cache.ErrTxConflict && retries > 0 { // For parallel runs, there may be conflicts, retry until successful
//t.Logf("Conflict, %d retries left",retries) case err == cache.ErrTxConflict && retries > 0:
SampleTransaction(testTx,retries-1,t) // t.Logf("Conflict, %d retries left",retries)
//clear TxConflict, if retries max out, errors are already recorded SampleTransaction(testTx, retries-1, t)
// Clear TxConflict, if retries max out, errors are already recorded
err = nil err = nil
}else if err == cache.ErrTxConflict { case err == cache.ErrTxConflict:
t.Error("Conflict encountered, max retries reached") t.Errorf("Conflict encountered, max retries reached: %s", err)
t.Errorf("error=%s", err) case err != nil:
t.Error(err)
default:
} }
if err != nil {
t.Errorf("error=%s", err)
t.Fail()
}
} }
func TestRedisTransaction(t *testing.T) { func TestRedisTransaction(t *testing.T) {
for i := 0; i < 10; i++ {
for i:=0; i < 10; i++ { // No retries for serial transactions
//No retries for serial transactions SampleTransaction(CreateTestTxObj(t), 0, t)
SampleTransaction(CreateTestTxObj(t),0,t)
} }
} }
func TestReadAfterWrite(t *testing.T) { func TestReadAfterWrite(t *testing.T) {
defer func() {
if err := recover(); err == nil {
t.Error("Read after write did not panic")
}
}()
testTx := CreateTestTxObj(t) testTx := CreateTestTxObj(t)
err := testTx.initiateWrite() err := testTx.initiateWrite()
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
// test requires panic
defer func() {
if rawError := recover(); rawError == nil {
t.Errorf("Read after write did not panic")
t.Fail()
}
} ()
err = testTx.initiateRead() err = testTx.initiateRead()
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
} }
func TestDoubleClose(t *testing.T){ func TestCloseClosedTransaction(t *testing.T) {
defer func() {
if err := recover(); err == nil {
t.Error("Closing a closed transaction did not panic")
}
}()
testTx := CreateTestTxObj(t) testTx := CreateTestTxObj(t)
testTx.close() testTx.close()
//require panic
defer func() {
if rawError := recover(); rawError == nil {
t.Errorf("double close did not panic")
t.Fail()
}
} ()
testTx.close() testTx.close()
} }
func TestParallelTx0(t *testing.T) { func TestParallelTx0(t *testing.T) {
t.Parallel() t.Parallel()
for i := 0; i < 20; i++ {
for i:=0; i< 20; i++ { go SampleTransaction(CreateTestTxObj(t), MAX_RETRIES, t)
go SampleTransaction(CreateTestTxObj(t),MAX_RETRIES,t)
time.Sleep(1 * time.Millisecond) time.Sleep(1 * time.Millisecond)
} }
} }
func TestParallelTx1(t *testing.T) { func TestParallelTx1(t *testing.T) {
t.Parallel() t.Parallel()
SampleTransaction(CreateTestTxObj(t),MAX_RETRIES,t) SampleTransaction(CreateTestTxObj(t), MAX_RETRIES, t)
for i:=0; i< 100; i++ { for i := 0; i < 100; i++ {
go SampleTransaction(CreateTestTxObj(t),MAX_RETRIES,t) go SampleTransaction(CreateTestTxObj(t), MAX_RETRIES, t)
} }
} }
func TestParallelTx2(t *testing.T) { func TestParallelTx2(t *testing.T) {
t.Parallel() t.Parallel()
for i:=0; i< 100; i++ { for i := 0; i < 100; i++ {
go SampleTransaction(CreateTestTxObj(t),MAX_RETRIES,t) go SampleTransaction(CreateTestTxObj(t), MAX_RETRIES, t)
} }
SampleTransaction(CreateTestTxObj(t),MAX_RETRIES,t) SampleTransaction(CreateTestTxObj(t), MAX_RETRIES, t)
} }
//just in case the above parallel tests didn't fail, force a failure here // Just in case the above parallel tests didn't fail, force a failure here
func TestParallelInterrupted(t *testing.T) { func TestParallelInterrupted(t *testing.T) {
t.Parallel() t.Parallel()
testTx := CreateTestTxObj(t)
defer func() { defer func() {
if rawError := recover(); rawError != nil { if err := recover(); err != nil {
t.Errorf("initiate read failed in parallelInterrupted") t.Errorf("initiateRead() failed in parallel: %s", err)
t.Fail()
} }
} () }()
testTx := CreateTestTxObj(t)
err := testTx.initiateRead() err := testTx.initiateRead()
if err != nil { if err != nil {
t.Fail() t.Error(err)
} }
_, err = testTx.Do("WATCH", "testKeyA") _, err = testTx.Do("WATCH", "testKeyA")
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
} }
testValueA, err := redis.String(testTx.Do("GET", "testKeyA")) testValueA, err := redis.String(testTx.Do("GET", "testKeyA"))
@ -222,8 +193,7 @@ func TestParallelInterrupted(t *testing.T) {
if err == redis.ErrNil { if err == redis.ErrNil {
t.Log("redis.ErrNil") t.Log("redis.ErrNil")
} else { } else {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
} }
@ -232,8 +202,7 @@ func TestParallelInterrupted(t *testing.T) {
if err == redis.ErrNil { if err == redis.ErrNil {
t.Log("redis.ErrNil") t.Log("redis.ErrNil")
} else { } else {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
} }
@ -242,43 +211,38 @@ func TestParallelInterrupted(t *testing.T) {
if err == redis.ErrNil { if err == redis.ErrNil {
t.Log("redis.ErrNil") t.Log("redis.ErrNil")
} else { } else {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
} }
//stand in for what real updates would do
// Stand in for what real updates would do
testValueB = testValueB + "+updates" testValueB = testValueB + "+updates"
testValueA = testValueA + "+updates" testValueA = testValueA + "+updates"
// simulating another client interrupts transaction, causing exec to fail // Simulating another client interrupts transaction, causing exec to fail
SampleTransaction(CreateTestTxObj(t),MAX_RETRIES,t) SampleTransaction(CreateTestTxObj(t), MAX_RETRIES, t)
err = testTx.initiateWrite() err = testTx.initiateWrite()
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
err = testTx.Send("SET", "testKeyA", testValueA) err = testTx.Send("SET", "testKeyA", testValueA)
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
err = testTx.Send("SET", "testKeyB", testValueB) err = testTx.Send("SET", "testKeyB", testValueB)
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
keys, err := (testTx.Do("EXEC")) keys, err := (testTx.Do("EXEC"))
//expect error
if keys != nil { if keys != nil {
t.Errorf("keys not nil, exec should have been interrupted") t.Error("Keys not nil; exec should have been interrupted")
} }
testTx.close() testTx.close()
if err != nil { if err != nil {
t.Errorf("error=%s", err) t.Error(err)
t.Fail()
} }
} }

View file

@ -5,6 +5,7 @@
"cache": { "cache": {
"driver": "redis", "driver": "redis",
"network": "tcp",
"host": "127.0.0.1", "host": "127.0.0.1",
"port": "6379", "port": "6379",
"user": "root", "user": "root",
@ -12,11 +13,7 @@
"prefix": "test:", "prefix": "test:",
"max_idle_conn": 3, "max_idle_conn": 3,
"idle_timeout": "240s", "idle_timeout": "240s"
"network": "tcp",
"schema": "schema",
"encoding": "encoding"
}, },
"storage": { "storage": {