Added parallel tests
This commit is contained in:
parent
1ea24f80dc
commit
19900991a7
3 changed files with 207 additions and 27 deletions
7
cache/redis/redis.go
vendored
7
cache/redis/redis.go
vendored
|
@ -297,14 +297,17 @@ func (tx *Tx) getPeers(torrentID uint64, peerTypePrefix string) (peers map[strin
|
|||
setKey := tx.conf.Prefix + peerTypePrefix + strconv.FormatUint(torrentID, 36)
|
||||
peerStrings, err := redis.Strings(tx.Do("SMEMBERS", setKey))
|
||||
if err != nil {
|
||||
return peers, err
|
||||
return nil, err
|
||||
}
|
||||
// Keys map to peer objects stored in hashes
|
||||
for _, peerHashKey := range peerStrings {
|
||||
hashKey := tx.conf.Prefix + peerHashKey
|
||||
peerVals, err := redis.Strings(tx.Do("HVALS", hashKey))
|
||||
if err != nil {
|
||||
return peers, err
|
||||
return nil, err
|
||||
}
|
||||
if len(peerVals) == 0 {
|
||||
continue
|
||||
}
|
||||
peer, err := createPeer(peerVals)
|
||||
if err != nil {
|
||||
|
|
109
cache/redis/redis_test.go
vendored
109
cache/redis/redis_test.go
vendored
|
@ -19,24 +19,43 @@ import (
|
|||
)
|
||||
|
||||
var (
|
||||
testTorrentIDCounter uint64
|
||||
testUserIDCounter uint64
|
||||
testPeerIDCounter int
|
||||
testTorrentIDChannel chan uint64
|
||||
testUserIDChannel chan uint64
|
||||
testPeerIDChannel chan int
|
||||
)
|
||||
|
||||
func init() {
|
||||
testTorrentIDChannel = make(chan uint64, 100)
|
||||
testUserIDChannel = make(chan uint64, 100)
|
||||
testPeerIDChannel = make(chan int, 100)
|
||||
// Sync access to ID counter with buffered global channels
|
||||
go func() {
|
||||
for i := 0; ; i++ {
|
||||
testTorrentIDChannel <- uint64(i)
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
for i := 0; ; i++ {
|
||||
testUserIDChannel <- uint64(i)
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
for i := 0; ; i++ {
|
||||
testPeerIDChannel <- i
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
func createTestTorrentID() uint64 {
|
||||
testTorrentIDCounter++
|
||||
return testTorrentIDCounter
|
||||
return <-testTorrentIDChannel
|
||||
}
|
||||
|
||||
func createTestUserID() uint64 {
|
||||
testUserIDCounter++
|
||||
return testUserIDCounter
|
||||
return <-testUserIDChannel
|
||||
}
|
||||
|
||||
func createTestPeerID() string {
|
||||
testPeerIDCounter++
|
||||
return "-testPeerID-" + strconv.Itoa(testPeerIDCounter)
|
||||
return "-testPeerID-" + strconv.Itoa(<-testPeerIDChannel)
|
||||
}
|
||||
|
||||
func createTestInfohash() string {
|
||||
|
@ -57,14 +76,6 @@ func createTestPasskey() string {
|
|||
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 panicErrNil(err error) {
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
@ -72,7 +83,7 @@ func panicErrNil(err error) {
|
|||
}
|
||||
}
|
||||
|
||||
func createTestTxObj() *Tx {
|
||||
func createTestRedisTx() *Tx {
|
||||
testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH"))
|
||||
conf := &testConfig.Cache
|
||||
panicErrNil(err)
|
||||
|
@ -115,7 +126,7 @@ 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
|
||||
testPeers[models.PeerMapKey(tempPeer)] = *tempPeer
|
||||
}
|
||||
return testPeers
|
||||
}
|
||||
|
@ -133,9 +144,43 @@ func createTestTorrent() *models.Torrent {
|
|||
return &testTorrent
|
||||
}
|
||||
|
||||
func TestPeersAlone(t *testing.T) {
|
||||
func comparePeers(lhPeers map[string]models.Peer, rhPeers map[string]models.Peer) bool {
|
||||
if len(lhPeers) != len(rhPeers) {
|
||||
return false
|
||||
}
|
||||
for rhKey, rhValue := range rhPeers {
|
||||
lhValue, lhExists := lhPeers[rhKey]
|
||||
if !lhExists || lhValue != rhValue {
|
||||
return false
|
||||
}
|
||||
}
|
||||
for lhKey, lhValue := range lhPeers {
|
||||
rhValue, rhExists := rhPeers[lhKey]
|
||||
if !rhExists || rhValue != lhValue {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
testTx := createTestTxObj()
|
||||
func torrentsEqual(lhTorrent *models.Torrent, rhTorrent *models.Torrent) bool {
|
||||
fieldsEqual := lhTorrent.Infohash == rhTorrent.Infohash &&
|
||||
lhTorrent.ID == rhTorrent.ID &&
|
||||
lhTorrent.Active == rhTorrent.Active &&
|
||||
lhTorrent.Snatches == rhTorrent.Snatches &&
|
||||
lhTorrent.UpMultiplier == rhTorrent.UpMultiplier &&
|
||||
lhTorrent.DownMultiplier == rhTorrent.DownMultiplier &&
|
||||
lhTorrent.LastAction == rhTorrent.LastAction
|
||||
|
||||
if !fieldsEqual {
|
||||
return false
|
||||
}
|
||||
|
||||
return comparePeers(lhTorrent.Seeders, rhTorrent.Seeders) && comparePeers(lhTorrent.Leechers, rhTorrent.Leechers)
|
||||
}
|
||||
|
||||
func TestValidPeers(t *testing.T) {
|
||||
testTx := createTestRedisTx()
|
||||
testTorrentID := createTestTorrentID()
|
||||
testPeers := createTestPeers(testTorrentID, 3)
|
||||
|
||||
|
@ -147,3 +192,25 @@ func TestPeersAlone(t *testing.T) {
|
|||
}
|
||||
panicErrNil(testTx.removePeers(testTorrentID, testPeers, "test:"))
|
||||
}
|
||||
|
||||
func TestInvalidPeers(t *testing.T) {
|
||||
testTx := createTestRedisTx()
|
||||
testTorrentID := createTestTorrentID()
|
||||
testPeers := createTestPeers(testTorrentID, 3)
|
||||
tempPeer := createTestPeer(createTestUserID(), testTorrentID)
|
||||
testPeers[models.PeerMapKey(tempPeer)] = *tempPeer
|
||||
|
||||
panicErrNil(testTx.addPeers(testPeers, "test:"))
|
||||
// Imitate a peer being removed during get
|
||||
hashKey := testTx.conf.Prefix + getPeerHashKey(tempPeer)
|
||||
_, err := testTx.Do("DEL", hashKey)
|
||||
panicErrNil(err)
|
||||
|
||||
peerMap, err := testTx.getPeers(testTorrentID, "test:")
|
||||
panicErrNil(err)
|
||||
// Expect 1 less peer due to delete
|
||||
if len(peerMap) != len(testPeers)-1 {
|
||||
t.Error("Num Peers not equal ", len(peerMap), len(testPeers))
|
||||
}
|
||||
panicErrNil(testTx.removePeers(testTorrentID, testPeers, "test:"))
|
||||
}
|
||||
|
|
118
cache/redis/tx_test.go
vendored
118
cache/redis/tx_test.go
vendored
|
@ -69,18 +69,17 @@ func TestRemoveUser(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestFindTorrent(t *testing.T) {
|
||||
func TestFindTorrentSuccess(t *testing.T) {
|
||||
tx := createTestTx()
|
||||
testTorrent := createTestTorrent()
|
||||
|
||||
panicErrNil(tx.AddTorrent(testTorrent))
|
||||
|
||||
foundTorrent, found, err := tx.FindTorrent(testTorrent.Infohash)
|
||||
panicErrNil(err)
|
||||
if !found {
|
||||
t.Error("torrent not found", testTorrent)
|
||||
}
|
||||
// Incomplete comparison as maps make struct not nativly comparable
|
||||
if foundTorrent.Infohash != testTorrent.Infohash {
|
||||
if !torrentsEqual(foundTorrent, testTorrent) {
|
||||
t.Error("found torrent mismatch", foundTorrent, testTorrent)
|
||||
}
|
||||
}
|
||||
|
@ -409,3 +408,114 @@ func TestUpdatePeer(t *testing.T) {
|
|||
t.Error("seeder not removed from local", seeder)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParallelFindUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
tx := createTestTx()
|
||||
testUserSuccess := createTestUser()
|
||||
testUserFail := createTestUser()
|
||||
panicErrNil(tx.AddUser(testUserSuccess))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
foundUser, found, err := tx.FindUser(testUserFail.Passkey)
|
||||
panicErrNil(err)
|
||||
if found {
|
||||
t.Error("user found", foundUser)
|
||||
}
|
||||
foundUser, found, err = tx.FindUser(testUserSuccess.Passkey)
|
||||
panicErrNil(err)
|
||||
if !found {
|
||||
t.Error("user not found", testUserSuccess)
|
||||
}
|
||||
if *foundUser != *testUserSuccess {
|
||||
t.Error("found user mismatch", *foundUser, testUserSuccess)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParallelFindTorrent(t *testing.T) {
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
tx := createTestTx()
|
||||
testTorrentSuccess := createTestTorrent()
|
||||
testTorrentFail := createTestTorrent()
|
||||
panicErrNil(tx.AddTorrent(testTorrentSuccess))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
foundTorrent, found, err := tx.FindTorrent(testTorrentSuccess.Infohash)
|
||||
panicErrNil(err)
|
||||
if !found {
|
||||
t.Error("torrent not found", testTorrentSuccess)
|
||||
}
|
||||
if !torrentsEqual(foundTorrent, testTorrentSuccess) {
|
||||
t.Error("found torrent mismatch", foundTorrent, testTorrentSuccess)
|
||||
}
|
||||
foundTorrent, found, err = tx.FindTorrent(testTorrentFail.Infohash)
|
||||
panicErrNil(err)
|
||||
if found {
|
||||
t.Error("torrent found", foundTorrent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParallelSetSeeder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
tx := createTestTx()
|
||||
testTorrent := createTestTorrent()
|
||||
panicErrNil(tx.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicErrNil(tx.AddSeeder(testTorrent, testSeeder))
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
testSeeder.Uploaded += uint64(r.Int63())
|
||||
|
||||
panicErrNil(tx.SetSeeder(testTorrent, testSeeder))
|
||||
|
||||
foundTorrent, _, err := tx.FindTorrent(testTorrent.Infohash)
|
||||
panicErrNil(err)
|
||||
foundSeeder, _ := foundTorrent.Seeders[models.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in cache", foundSeeder, *testSeeder)
|
||||
}
|
||||
foundSeeder, _ = testTorrent.Seeders[models.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in local", foundSeeder, *testSeeder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParallelAddLeecher(t *testing.T) {
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
tx := createTestTx()
|
||||
testTorrent := createTestTorrent()
|
||||
panicErrNil(tx.AddTorrent(testTorrent))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
|
||||
panicErrNil(tx.AddLeecher(testTorrent, testLeecher))
|
||||
|
||||
foundTorrent, found, err := tx.FindTorrent(testTorrent.Infohash)
|
||||
panicErrNil(err)
|
||||
foundLeecher, found := foundTorrent.Leechers[models.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to cache", testLeecher)
|
||||
}
|
||||
foundLeecher, found = testTorrent.Leechers[models.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to local", testLeecher)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue