Updated tests, added LeecherFinished to cache.Tx
This commit is contained in:
parent
42f9427c01
commit
3caa06b5f6
5 changed files with 313 additions and 174 deletions
3
cache/cache.go
vendored
3
cache/cache.go
vendored
|
@ -73,6 +73,9 @@ type Tx interface {
|
||||||
SetSeeder(t *models.Torrent, p *models.Peer) error
|
SetSeeder(t *models.Torrent, p *models.Peer) error
|
||||||
IncrementSlots(u *models.User) error
|
IncrementSlots(u *models.User) error
|
||||||
DecrementSlots(u *models.User) error
|
DecrementSlots(u *models.User) error
|
||||||
|
LeecherFinished(t *models.Torrent, p *models.Peer) error
|
||||||
|
|
||||||
|
// Priming / Testing
|
||||||
AddTorrent(t *models.Torrent) error
|
AddTorrent(t *models.Torrent) error
|
||||||
RemoveTorrent(t *models.Torrent) error
|
RemoveTorrent(t *models.Torrent) error
|
||||||
AddUser(u *models.User) error
|
AddUser(u *models.User) error
|
||||||
|
|
77
cache/redis/redis.go
vendored
77
cache/redis/redis.go
vendored
|
@ -136,6 +136,7 @@ func createUser(userVals []string) (*models.User, error) {
|
||||||
return &models.User{ID, Passkey, UpMultiplier, DownMultiplier, Slots, SlotsUsed, uint(Snatches)}, nil
|
return &models.User{ID, Passkey, UpMultiplier, DownMultiplier, Slots, SlotsUsed, uint(Snatches)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a mulple action command, it's not internally atomic
|
||||||
func (tx *Tx) createTorrent(torrentVals []string) (*models.Torrent, error) {
|
func (tx *Tx) createTorrent(torrentVals []string) (*models.Torrent, error) {
|
||||||
if len(torrentVals) != 7 {
|
if len(torrentVals) != 7 {
|
||||||
return nil, ErrCreateTorrent
|
return nil, ErrCreateTorrent
|
||||||
|
@ -177,9 +178,9 @@ func (tx *Tx) createTorrent(torrentVals []string) (*models.Torrent, error) {
|
||||||
return &models.Torrent{ID, Infohash, Active, seeders, leechers, uint(Snatches), UpMultiplier, DownMultiplier, LastAction}, nil
|
return &models.Torrent{ID, Infohash, Active, seeders, leechers, uint(Snatches), UpMultiplier, DownMultiplier, LastAction}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// hashkey relies on combination of peerID, userID, and torrentID being unique
|
// The peer hashkey relies on the combination of peerID, userID, and torrentID being unique
|
||||||
func (tx *Tx) setPeer(peer *models.Peer, peerTypePrefix string) error {
|
func (tx *Tx) setPeer(peer *models.Peer) error {
|
||||||
hashKey := tx.conf.Prefix + peerTypePrefix + getPeerHashKey(peer)
|
hashKey := tx.conf.Prefix + getPeerHashKey(peer)
|
||||||
_, err := tx.Do("HMSET", hashKey,
|
_, err := tx.Do("HMSET", hashKey,
|
||||||
"id", peer.ID,
|
"id", peer.ID,
|
||||||
"user_id", peer.UserID,
|
"user_id", peer.UserID,
|
||||||
|
@ -199,17 +200,20 @@ func (tx *Tx) setPeer(peer *models.Peer, peerTypePrefix string) error {
|
||||||
|
|
||||||
// Will not return an error if the peer doesn't exist
|
// Will not return an error if the peer doesn't exist
|
||||||
func (tx *Tx) removePeer(peer *models.Peer, peerTypePrefix string) error {
|
func (tx *Tx) removePeer(peer *models.Peer, peerTypePrefix string) error {
|
||||||
setKey := tx.conf.Prefix + peerTypePrefix + strconv.FormatUint(peer.TorrentID, 36)
|
setKey := tx.conf.Prefix + getPeerSetKey(peerTypePrefix, peer)
|
||||||
_, err := tx.Do("SREM", setKey, *peer)
|
_, err := tx.Do("SREM", setKey, getPeerHashKey(peer))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
hashKey := tx.conf.Prefix + getPeerHashKey(peer)
|
||||||
|
_, err = tx.Do("DEL", hashKey)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a mulple action command, it's not internally atomic
|
||||||
func (tx *Tx) removePeers(torrentID uint64, peers map[string]models.Peer, peerTypePrefix string) error {
|
func (tx *Tx) removePeers(torrentID uint64, peers map[string]models.Peer, peerTypePrefix string) error {
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
hashKey := tx.conf.Prefix + peerTypePrefix + getPeerHashKey(&peer)
|
hashKey := tx.conf.Prefix + getPeerHashKey(&peer)
|
||||||
_, err := tx.Do("DEL", hashKey)
|
_, err := tx.Do("DEL", hashKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -230,14 +234,19 @@ func getPeerHashKey(peer *models.Peer) string {
|
||||||
return peer.ID + ":" + strconv.FormatUint(peer.UserID, 36) + ":" + strconv.FormatUint(peer.TorrentID, 36)
|
return peer.ID + ":" + strconv.FormatUint(peer.UserID, 36) + ":" + strconv.FormatUint(peer.TorrentID, 36)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getPeerSetKey(prefix string, peer *models.Peer) string {
|
||||||
|
return prefix + strconv.FormatUint(peer.TorrentID, 36)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a mulple action command, it's not internally atomic
|
||||||
func (tx *Tx) addPeers(peers map[string]models.Peer, peerTypePrefix string) error {
|
func (tx *Tx) addPeers(peers map[string]models.Peer, peerTypePrefix string) error {
|
||||||
for _, peer := range peers {
|
for _, peer := range peers {
|
||||||
setKey := tx.conf.Prefix + peerTypePrefix + strconv.FormatUint(peer.TorrentID, 36)
|
setKey := tx.conf.Prefix + getPeerSetKey(peerTypePrefix, &peer)
|
||||||
_, err := tx.Do("SADD", setKey, getPeerHashKey(&peer))
|
_, err := tx.Do("SADD", setKey, getPeerHashKey(&peer))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
tx.setPeer(&peer, peerTypePrefix)
|
tx.setPeer(&peer)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -281,6 +290,7 @@ func createPeer(peerVals []string) (*models.Peer, error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a mulple action command, it's not internally atomic
|
||||||
func (tx *Tx) getPeers(torrentID uint64, peerTypePrefix string) (peers map[string]models.Peer, err error) {
|
func (tx *Tx) getPeers(torrentID uint64, peerTypePrefix string) (peers map[string]models.Peer, err error) {
|
||||||
peers = make(map[string]models.Peer)
|
peers = make(map[string]models.Peer)
|
||||||
setKey := tx.conf.Prefix + peerTypePrefix + strconv.FormatUint(torrentID, 36)
|
setKey := tx.conf.Prefix + peerTypePrefix + strconv.FormatUint(torrentID, 36)
|
||||||
|
@ -290,7 +300,7 @@ func (tx *Tx) getPeers(torrentID uint64, peerTypePrefix string) (peers map[strin
|
||||||
}
|
}
|
||||||
// Keys map to peer objects stored in hashes
|
// Keys map to peer objects stored in hashes
|
||||||
for _, peerHashKey := range peerStrings {
|
for _, peerHashKey := range peerStrings {
|
||||||
hashKey := tx.conf.Prefix + peerTypePrefix + peerHashKey
|
hashKey := tx.conf.Prefix + peerHashKey
|
||||||
peerVals, err := redis.Strings(tx.Do("HVALS", hashKey))
|
peerVals, err := redis.Strings(tx.Do("HVALS", hashKey))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return peers, err
|
return peers, err
|
||||||
|
@ -304,6 +314,7 @@ func (tx *Tx) getPeers(torrentID uint64, peerTypePrefix string) (peers map[strin
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a mulple action command, it's not internally atomic
|
||||||
func (tx *Tx) AddTorrent(t *models.Torrent) error {
|
func (tx *Tx) AddTorrent(t *models.Torrent) error {
|
||||||
hashkey := tx.conf.Prefix + TorrentPrefix + t.Infohash
|
hashkey := tx.conf.Prefix + TorrentPrefix + t.Infohash
|
||||||
_, err := tx.Do("HMSET", hashkey,
|
_, err := tx.Do("HMSET", hashkey,
|
||||||
|
@ -318,12 +329,18 @@ func (tx *Tx) AddTorrent(t *models.Torrent) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
tx.addPeers(t.Seeders, SeederPrefix)
|
err = tx.addPeers(t.Seeders, SeederPrefix)
|
||||||
tx.addPeers(t.Leechers, LeecherPrefix)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
err = tx.addPeers(t.Leechers, LeecherPrefix)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a mulple action command, it's not internally atomic
|
||||||
func (tx *Tx) RemoveTorrent(t *models.Torrent) error {
|
func (tx *Tx) RemoveTorrent(t *models.Torrent) error {
|
||||||
hashkey := tx.conf.Prefix + TorrentPrefix + t.Infohash
|
hashkey := tx.conf.Prefix + TorrentPrefix + t.Infohash
|
||||||
_, err := tx.Do("DEL", hashkey)
|
_, err := tx.Do("DEL", hashkey)
|
||||||
|
@ -449,13 +466,14 @@ func (tx *Tx) MarkActive(torrent *models.Torrent) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a mulple action command, it's not internally atomic
|
||||||
func (tx *Tx) AddLeecher(torrent *models.Torrent, peer *models.Peer) error {
|
func (tx *Tx) AddLeecher(torrent *models.Torrent, peer *models.Peer) error {
|
||||||
setKey := tx.conf.Prefix + LeecherPrefix + strconv.FormatUint(torrent.ID, 36)
|
setKey := tx.conf.Prefix + LeecherPrefix + strconv.FormatUint(torrent.ID, 36)
|
||||||
_, err := tx.Do("SADD", setKey, getPeerHashKey(peer))
|
_, err := tx.Do("SADD", setKey, getPeerHashKey(peer))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = tx.setPeer(peer, LeecherPrefix)
|
err = tx.setPeer(peer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -469,7 +487,12 @@ func (tx *Tx) AddLeecher(torrent *models.Torrent, peer *models.Peer) error {
|
||||||
// Setting assumes it is already a leecher, and just needs to be updated
|
// Setting assumes it is already a leecher, and just needs to be updated
|
||||||
// Maybe eventually there will be a move from leecher to seeder method
|
// Maybe eventually there will be a move from leecher to seeder method
|
||||||
func (tx *Tx) SetLeecher(t *models.Torrent, p *models.Peer) error {
|
func (tx *Tx) SetLeecher(t *models.Torrent, p *models.Peer) error {
|
||||||
return tx.setPeer(p, LeecherPrefix)
|
err := tx.setPeer(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.Leechers[p.ID] = *p
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Tx) RemoveLeecher(t *models.Torrent, p *models.Peer) error {
|
func (tx *Tx) RemoveLeecher(t *models.Torrent, p *models.Peer) error {
|
||||||
|
@ -481,13 +504,30 @@ func (tx *Tx) RemoveLeecher(t *models.Torrent, p *models.Peer) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) LeecherFinished(torrent *models.Torrent, peer *models.Peer) error {
|
||||||
|
torrentIdKey := strconv.FormatUint(torrent.ID, 36)
|
||||||
|
seederSetKey := tx.conf.Prefix + SeederPrefix + torrentIdKey
|
||||||
|
leecherSetKey := tx.conf.Prefix + LeecherPrefix + torrentIdKey
|
||||||
|
|
||||||
|
_, err := tx.Do("SMOVE", leecherSetKey, seederSetKey, getPeerHashKey(peer))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
torrent.Seeders[peer.ID] = *peer
|
||||||
|
delete(torrent.Leechers, peer.ID)
|
||||||
|
|
||||||
|
err = tx.setPeer(peer)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a mulple action command, it's not internally atomic
|
||||||
func (tx *Tx) AddSeeder(torrent *models.Torrent, peer *models.Peer) error {
|
func (tx *Tx) AddSeeder(torrent *models.Torrent, peer *models.Peer) error {
|
||||||
setKey := tx.conf.Prefix + SeederPrefix + strconv.FormatUint(torrent.ID, 36)
|
setKey := tx.conf.Prefix + SeederPrefix + strconv.FormatUint(torrent.ID, 36)
|
||||||
_, err := tx.Do("SADD", setKey, getPeerHashKey(peer))
|
_, err := tx.Do("SADD", setKey, getPeerHashKey(peer))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = tx.setPeer(peer, SeederPrefix)
|
err = tx.setPeer(peer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -499,7 +539,12 @@ func (tx *Tx) AddSeeder(torrent *models.Torrent, peer *models.Peer) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Tx) SetSeeder(t *models.Torrent, p *models.Peer) error {
|
func (tx *Tx) SetSeeder(t *models.Torrent, p *models.Peer) error {
|
||||||
return tx.setPeer(p, SeederPrefix)
|
err := tx.setPeer(p)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
t.Seeders[p.ID] = *p
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tx *Tx) RemoveSeeder(t *models.Torrent, p *models.Peer) error {
|
func (tx *Tx) RemoveSeeder(t *models.Torrent, p *models.Peer) error {
|
||||||
|
|
51
cache/redis/redis_test.go
vendored
51
cache/redis/redis_test.go
vendored
|
@ -104,21 +104,21 @@ func createTestUser() models.User {
|
||||||
return testUser
|
return testUser
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestPeer(userID uint64, torrentID uint64) models.Peer {
|
func createTestPeer(userID uint64, torrentID uint64) *models.Peer {
|
||||||
|
|
||||||
return models.Peer{createTestPeerID(), userID, torrentID, "127.0.0.1", 6889, 1024, 3000, 4200, 11}
|
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 {
|
func createTestPeers(torrentID uint64, num int) map[string]models.Peer {
|
||||||
testPeers := make(map[string]models.Peer)
|
testPeers := make(map[string]models.Peer)
|
||||||
for i := 0; i < num; i++ {
|
for i := 0; i < num; i++ {
|
||||||
tempPeer := createTestPeer(createTestUserID(), torrentID)
|
tempPeer := createTestPeer(createTestUserID(), torrentID)
|
||||||
testPeers[tempPeer.ID] = tempPeer
|
testPeers[tempPeer.ID] = *tempPeer
|
||||||
}
|
}
|
||||||
return testPeers
|
return testPeers
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestTorrent() models.Torrent {
|
func createTestTorrent() *models.Torrent {
|
||||||
|
|
||||||
torrentInfohash := createTestInfohash()
|
torrentInfohash := createTestInfohash()
|
||||||
torrentID := createTestTorrentID()
|
torrentID := createTestTorrentID()
|
||||||
|
@ -127,34 +127,7 @@ func createTestTorrent() models.Torrent {
|
||||||
testLeechers := createTestPeers(torrentID, 2)
|
testLeechers := createTestPeers(torrentID, 2)
|
||||||
|
|
||||||
testTorrent := models.Torrent{torrentID, torrentInfohash, true, testSeeders, testLeechers, 11, 0.0, 0.0, 0}
|
testTorrent := models.Torrent{torrentID, torrentInfohash, true, testSeeders, testLeechers, 11, 0.0, 0.0, 0}
|
||||||
return testTorrent
|
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) {
|
func TestAddGetPeers(t *testing.T) {
|
||||||
|
@ -174,20 +147,6 @@ func TestAddGetPeers(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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) {
|
func TestCloseClosedTransaction(t *testing.T) {
|
||||||
//require panic
|
//require panic
|
||||||
defer func() {
|
defer func() {
|
||||||
|
|
344
cache/redis/tx_test.go
vendored
344
cache/redis/tx_test.go
vendored
|
@ -36,155 +36,295 @@ func createTestTx() cache.Tx {
|
||||||
return txObj
|
return txObj
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUser(t *testing.T) {
|
func TestFindUserSuccess(t *testing.T) {
|
||||||
tx := createTestTx()
|
tx := createTestTx()
|
||||||
testUser1 := createTestUser()
|
testUser1 := createTestUser()
|
||||||
testUser2 := createTestUser()
|
|
||||||
|
|
||||||
panicErrNil(tx.AddUser(&testUser1))
|
panicErrNil(tx.AddUser(&testUser1))
|
||||||
foundUser, found, err := tx.FindUser(testUser1.Passkey)
|
foundUser, found, err := tx.FindUser(testUser1.Passkey)
|
||||||
panicErrNil(err)
|
panicErrNil(err)
|
||||||
if !found {
|
if !found {
|
||||||
t.Error("user not found")
|
t.Error("user not found", testUser1)
|
||||||
}
|
}
|
||||||
if *foundUser != testUser1 {
|
if *foundUser != testUser1 {
|
||||||
t.Error("found user mismatch")
|
t.Error("found user mismatch", *foundUser, testUser1)
|
||||||
}
|
|
||||||
|
|
||||||
foundUser, found, err = tx.FindUser(testUser2.Passkey)
|
|
||||||
panicErrNil(err)
|
|
||||||
if found {
|
|
||||||
t.Error("user found")
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tx.RemoveUser(&testUser1)
|
|
||||||
panicErrNil(err)
|
|
||||||
foundUser, found, err = tx.FindUser(testUser1.Passkey)
|
|
||||||
panicErrNil(err)
|
|
||||||
if found {
|
|
||||||
t.Error("removed user found")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTorrent(t *testing.T) {
|
func TestFindUserFail(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testUser2 := createTestUser()
|
||||||
|
|
||||||
|
foundUser, found, err := tx.FindUser(testUser2.Passkey)
|
||||||
|
panicErrNil(err)
|
||||||
|
if found {
|
||||||
|
t.Error("user found", foundUser)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoveUser(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testUser1 := createTestUser()
|
||||||
|
|
||||||
|
panicErrNil(tx.AddUser(&testUser1))
|
||||||
|
err := tx.RemoveUser(&testUser1)
|
||||||
|
panicErrNil(err)
|
||||||
|
foundUser, found, err := tx.FindUser(testUser1.Passkey)
|
||||||
|
panicErrNil(err)
|
||||||
|
if found {
|
||||||
|
t.Error("removed user found", foundUser)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestFindTorrent(t *testing.T) {
|
||||||
tx := createTestTx()
|
tx := createTestTx()
|
||||||
testTorrent1 := createTestTorrent()
|
testTorrent1 := createTestTorrent()
|
||||||
testTorrent2 := createTestTorrent()
|
|
||||||
|
|
||||||
panicErrNil(tx.AddTorrent(&testTorrent1))
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
foundTorrent, found, err := tx.FindTorrent(testTorrent1.Infohash)
|
foundTorrent, found, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
panicErrNil(err)
|
panicErrNil(err)
|
||||||
if !found {
|
if !found {
|
||||||
t.Error("torrent not found")
|
t.Error("torrent not found", testTorrent1)
|
||||||
}
|
}
|
||||||
// Incomplete comparison as maps cannot be compared
|
// Incomplete comparison as maps make struct not nativly comparable
|
||||||
if foundTorrent.Infohash != testTorrent1.Infohash {
|
if foundTorrent.Infohash != testTorrent1.Infohash {
|
||||||
t.Error("found torrent mismatch")
|
t.Error("found torrent mismatch", foundTorrent, testTorrent1)
|
||||||
}
|
|
||||||
foundTorrent, found, err = tx.FindTorrent(testTorrent2.Infohash)
|
|
||||||
panicErrNil(err)
|
|
||||||
if found {
|
|
||||||
t.Error("torrent found")
|
|
||||||
}
|
|
||||||
|
|
||||||
panicErrNil(tx.RemoveTorrent(&testTorrent1))
|
|
||||||
foundTorrent, found, err = tx.FindTorrent(testTorrent1.Infohash)
|
|
||||||
panicErrNil(err)
|
|
||||||
if found {
|
|
||||||
t.Error("removed torrent found")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func TestClient(t *testing.T) {
|
|
||||||
|
func TestFindTorrentFail(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testTorrent2 := createTestTorrent()
|
||||||
|
|
||||||
|
foundTorrent, found, err := tx.FindTorrent(testTorrent2.Infohash)
|
||||||
|
panicErrNil(err)
|
||||||
|
if found {
|
||||||
|
t.Error("torrent found", foundTorrent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoveTorrent(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testTorrent1 := createTestTorrent()
|
||||||
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
|
|
||||||
|
panicErrNil(tx.RemoveTorrent(testTorrent1))
|
||||||
|
foundTorrent, found, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
|
panicErrNil(err)
|
||||||
|
if found {
|
||||||
|
t.Error("removed torrent found", foundTorrent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClientWhitelistSuccess(t *testing.T) {
|
||||||
tx := createTestTx()
|
tx := createTestTx()
|
||||||
testPeerID1 := "-lt0D30-"
|
testPeerID1 := "-lt0D30-"
|
||||||
testPeerID2 := "TIX0192"
|
|
||||||
|
|
||||||
panicErrNil(tx.WhitelistClient(testPeerID1))
|
panicErrNil(tx.WhitelistClient(testPeerID1))
|
||||||
found, err := tx.ClientWhitelisted(testPeerID1)
|
found, err := tx.ClientWhitelisted(testPeerID1)
|
||||||
panicErrNil(err)
|
panicErrNil(err)
|
||||||
if !found {
|
if !found {
|
||||||
t.Error("peerID not found")
|
t.Error("peerID not found", testPeerID1)
|
||||||
}
|
|
||||||
|
|
||||||
found, err = tx.ClientWhitelisted(testPeerID2)
|
|
||||||
panicErrNil(err)
|
|
||||||
if found {
|
|
||||||
t.Error("peerID found")
|
|
||||||
}
|
|
||||||
|
|
||||||
panicErrNil(tx.UnWhitelistClient(testPeerID1))
|
|
||||||
found, err = tx.ClientWhitelisted(testPeerID1)
|
|
||||||
panicErrNil(err)
|
|
||||||
if found {
|
|
||||||
t.Error("removed peerID found")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPeers(t *testing.T) {
|
func TestClientWhitelistFail(t *testing.T) {
|
||||||
tx := createTestTx()
|
tx := createTestTx()
|
||||||
|
testPeerID2 := "TIX0192"
|
||||||
|
|
||||||
// Randomly generated strings would be safter to test with
|
found, err := tx.ClientWhitelisted(testPeerID2)
|
||||||
|
panicErrNil(err)
|
||||||
|
if found {
|
||||||
|
t.Error("peerID found", testPeerID2)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestClientWhitelistRemove(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testPeerID1 := "-lt0D30-"
|
||||||
|
panicErrNil(tx.WhitelistClient(testPeerID1))
|
||||||
|
panicErrNil(tx.UnWhitelistClient(testPeerID1))
|
||||||
|
|
||||||
|
found, err := tx.ClientWhitelisted(testPeerID1)
|
||||||
|
panicErrNil(err)
|
||||||
|
if found {
|
||||||
|
t.Error("removed peerID found", testPeerID1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddSeeder(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
testTorrent1 := createTestTorrent()
|
testTorrent1 := createTestTorrent()
|
||||||
testTorrent2 := createTestTorrent()
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
|
testSeeder1 := createTestPeer(createTestUserID(), testTorrent1.ID)
|
||||||
|
|
||||||
|
panicErrNil(tx.AddSeeder(testTorrent1, testSeeder1))
|
||||||
foundTorrent, found, err := tx.FindTorrent(testTorrent1.Infohash)
|
foundTorrent, found, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
panicErrNil(err)
|
panicErrNil(err)
|
||||||
if found {
|
foundSeeder, found := foundTorrent.Seeders[testSeeder1.ID]
|
||||||
testTorrent1 = *foundTorrent
|
if found && foundSeeder != *testSeeder1 {
|
||||||
} else {
|
t.Error("seeder not added to cache", testSeeder1)
|
||||||
panicErrNil(tx.AddTorrent(&testTorrent1))
|
|
||||||
}
|
}
|
||||||
foundTorrent, found, err = tx.FindTorrent(testTorrent2.Infohash)
|
foundSeeder, found = testTorrent1.Seeders[testSeeder1.ID]
|
||||||
panicErrNil(err)
|
if found && foundSeeder != *testSeeder1 {
|
||||||
if found {
|
t.Error("seeder not added to local", testSeeder1)
|
||||||
testTorrent2 = *foundTorrent
|
|
||||||
} else {
|
|
||||||
panicErrNil(tx.AddTorrent(&testTorrent2))
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddLeecher(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testTorrent1 := createTestTorrent()
|
||||||
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
|
testLeecher1 := createTestPeer(createTestUserID(), testTorrent1.ID)
|
||||||
|
|
||||||
|
tx.AddLeecher(testTorrent1, testLeecher1)
|
||||||
|
foundTorrent, found, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
|
panicErrNil(err)
|
||||||
|
foundLeecher, found := foundTorrent.Leechers[testLeecher1.ID]
|
||||||
|
if found && foundLeecher != *testLeecher1 {
|
||||||
|
t.Error("leecher not added to cache", testLeecher1)
|
||||||
|
}
|
||||||
|
foundLeecher, found = testTorrent1.Leechers[testLeecher1.ID]
|
||||||
|
if found && foundLeecher != *testLeecher1 {
|
||||||
|
t.Error("leecher not added to local", testLeecher1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoveSeeder(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testTorrent1 := createTestTorrent()
|
||||||
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
testSeeder1 := createTestPeer(createTestUserID(), testTorrent1.ID)
|
testSeeder1 := createTestPeer(createTestUserID(), testTorrent1.ID)
|
||||||
testSeeder2 := createTestPeer(createTestUserID(), testTorrent2.ID)
|
tx.AddSeeder(testTorrent1, testSeeder1)
|
||||||
if testSeeder1 == testSeeder2 {
|
|
||||||
t.Error("seeders should not be equal")
|
panicErrNil(tx.RemoveSeeder(testTorrent1, testSeeder1))
|
||||||
|
foundSeeder, found := testTorrent1.Seeders[testSeeder1.ID]
|
||||||
|
if found || foundSeeder == *testSeeder1 {
|
||||||
|
t.Error("seeder not removed from local", foundSeeder)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, exists := testTorrent1.Seeders[testSeeder1.ID]; exists {
|
foundTorrent, found, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
t.Log("seeder aleady exists, removing")
|
|
||||||
err := tx.RemoveSeeder(&testTorrent1, &testSeeder1)
|
|
||||||
if err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
if _, exists := testTorrent1.Seeders[testSeeder1.ID]; exists {
|
|
||||||
t.Error("Remove seeder failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
panicErrNil(tx.AddSeeder(&testTorrent1, &testSeeder1))
|
|
||||||
if seeder1, exists := testTorrent1.Seeders[testSeeder1.ID]; !exists {
|
|
||||||
t.Error("seeder not added locally")
|
|
||||||
} else if seeder1 != testSeeder1 {
|
|
||||||
t.Error("seeder changed")
|
|
||||||
}
|
|
||||||
foundTorrent, found, err = tx.FindTorrent(testTorrent1.Infohash)
|
|
||||||
panicErrNil(err)
|
panicErrNil(err)
|
||||||
if !found {
|
foundSeeder, found = foundTorrent.Seeders[testSeeder1.ID]
|
||||||
t.Error("torrent should exist")
|
if found || foundSeeder == *testSeeder1 {
|
||||||
}
|
t.Error("seeder not removed from cache", foundSeeder)
|
||||||
if seeder1, exists := foundTorrent.Seeders[testSeeder1.ID]; !exists {
|
|
||||||
t.Error("seeder not added")
|
|
||||||
} else if seeder1 != testSeeder1 {
|
|
||||||
t.Error("seeder changed")
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRemoveLeecher(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testTorrent1 := createTestTorrent()
|
||||||
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
|
testLeecher1 := createTestPeer(createTestUserID(), testTorrent1.ID)
|
||||||
|
tx.AddLeecher(testTorrent1, testLeecher1)
|
||||||
|
|
||||||
|
tx.RemoveLeecher(testTorrent1, testLeecher1)
|
||||||
|
foundTorrent, found, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
|
panicErrNil(err)
|
||||||
|
foundLeecher, found := foundTorrent.Leechers[testLeecher1.ID]
|
||||||
|
if found || foundLeecher == *testLeecher1 {
|
||||||
|
t.Error("leecher not removed from cache", foundLeecher)
|
||||||
|
}
|
||||||
|
foundLeecher, found = testTorrent1.Leechers[testLeecher1.ID]
|
||||||
|
if found || foundLeecher == *testLeecher1 {
|
||||||
|
t.Error("leecher not removed from local", foundLeecher)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetSeeder(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testTorrent1 := createTestTorrent()
|
||||||
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
|
testSeeder1 := createTestPeer(createTestUserID(), testTorrent1.ID)
|
||||||
|
tx.AddSeeder(testTorrent1, testSeeder1)
|
||||||
|
|
||||||
|
testSeeder1.Uploaded += 100
|
||||||
|
|
||||||
|
tx.SetSeeder(testTorrent1, testSeeder1)
|
||||||
|
foundTorrent, _, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
|
panicErrNil(err)
|
||||||
|
foundSeeder, _ := foundTorrent.Seeders[testSeeder1.ID]
|
||||||
|
if foundSeeder != *testSeeder1 {
|
||||||
|
t.Error("seeder not updated in cache", testSeeder1)
|
||||||
|
}
|
||||||
|
foundSeeder, _ = testTorrent1.Seeders[testSeeder1.ID]
|
||||||
|
if foundSeeder != *testSeeder1 {
|
||||||
|
t.Error("seeder not updated in local", testSeeder1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetLeecher(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testTorrent1 := createTestTorrent()
|
||||||
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
|
testLeecher1 := createTestPeer(createTestUserID(), testTorrent1.ID)
|
||||||
|
tx.AddLeecher(testTorrent1, testLeecher1)
|
||||||
|
|
||||||
|
testLeecher1.Uploaded += 100
|
||||||
|
|
||||||
|
tx.SetLeecher(testTorrent1, testLeecher1)
|
||||||
|
foundTorrent, _, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
|
panicErrNil(err)
|
||||||
|
foundLeecher, _ := foundTorrent.Leechers[testLeecher1.ID]
|
||||||
|
if foundLeecher != *testLeecher1 {
|
||||||
|
t.Error("leecher not updated in cache", testLeecher1)
|
||||||
|
}
|
||||||
|
foundLeecher, _ = testTorrent1.Leechers[testLeecher1.ID]
|
||||||
|
if foundLeecher != *testLeecher1 {
|
||||||
|
t.Error("leecher not updated in local", testLeecher1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLeecherFinished(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testTorrent1 := createTestTorrent()
|
||||||
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
|
testLeecher1 := createTestPeer(createTestUserID(), testTorrent1.ID)
|
||||||
|
tx.AddLeecher(testTorrent1, testLeecher1)
|
||||||
|
testLeecher1.Left = 0
|
||||||
|
|
||||||
|
tx.LeecherFinished(testTorrent1, testLeecher1)
|
||||||
|
foundTorrent, _, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
|
panicErrNil(err)
|
||||||
|
foundSeeder, _ := foundTorrent.Seeders[testLeecher1.ID]
|
||||||
|
if foundSeeder != *testLeecher1 {
|
||||||
|
t.Error("seeder not added to cache", testLeecher1, foundSeeder)
|
||||||
|
}
|
||||||
|
foundSeeder, _ = foundTorrent.Leechers[testLeecher1.ID]
|
||||||
|
if foundSeeder == *testLeecher1 {
|
||||||
|
t.Error("leecher not removed from cache", testLeecher1)
|
||||||
|
}
|
||||||
|
foundSeeder, _ = testTorrent1.Seeders[testLeecher1.ID]
|
||||||
|
if foundSeeder != *testLeecher1 {
|
||||||
|
t.Error("seeder not added to local", testLeecher1)
|
||||||
|
}
|
||||||
|
foundSeeder, _ = testTorrent1.Leechers[testLeecher1.ID]
|
||||||
|
if foundSeeder == *testLeecher1 {
|
||||||
|
t.Error("leecher not removed from local", testLeecher1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add, update, verify remove
|
||||||
|
func TestUpdatePeer(t *testing.T) {
|
||||||
|
tx := createTestTx()
|
||||||
|
testTorrent1 := createTestTorrent()
|
||||||
|
testSeeder1 := createTestPeer(createTestUserID(), testTorrent1.ID)
|
||||||
|
panicErrNil(tx.AddTorrent(testTorrent1))
|
||||||
|
panicErrNil(tx.AddSeeder(testTorrent1, testSeeder1))
|
||||||
// Update a seeder, set it, then check to make sure it updated
|
// Update a seeder, set it, then check to make sure it updated
|
||||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||||
testSeeder1.Downloaded += uint64(r.Int63())
|
testSeeder1.Uploaded += uint64(r.Int63())
|
||||||
panicErrNil(tx.SetSeeder(&testTorrent1, &testSeeder1))
|
|
||||||
foundTorrent, found, err = tx.FindTorrent(testTorrent1.Infohash)
|
|
||||||
panicErrNil(err)
|
|
||||||
if seeder1, exists := foundTorrent.Seeders[testSeeder1.ID]; !exists {
|
|
||||||
t.Error("seeder not added")
|
|
||||||
} else if seeder1 != testSeeder1 {
|
|
||||||
t.Errorf("seeder changed from %v to %v", testSeeder1, seeder1)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
panicErrNil(tx.SetSeeder(testTorrent1, testSeeder1))
|
||||||
|
|
||||||
|
panicErrNil(tx.RemoveSeeder(testTorrent1, testSeeder1))
|
||||||
|
foundTorrent, _, err := tx.FindTorrent(testTorrent1.Infohash)
|
||||||
|
panicErrNil(err)
|
||||||
|
if seeder1, exists := foundTorrent.Seeders[testSeeder1.ID]; exists {
|
||||||
|
t.Error("seeder not removed from cache", seeder1)
|
||||||
|
}
|
||||||
|
if seeder1, exists := testTorrent1.Seeders[testSeeder1.ID]; exists {
|
||||||
|
t.Error("seeder not removed from local", seeder1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,11 +170,7 @@ func (s Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Panicf("server: %s", err)
|
log.Panicf("server: %s", err)
|
||||||
}
|
}
|
||||||
if leecher {
|
if leecher {
|
||||||
err := tx.RemoveLeecher(torrent, peer)
|
err := tx.LeecherFinished(torrent, peer)
|
||||||
if err != nil {
|
|
||||||
log.Panicf("server: %s", err)
|
|
||||||
}
|
|
||||||
err = tx.AddSeeder(torrent, peer)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicf("server: %s", err)
|
log.Panicf("server: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -182,11 +178,7 @@ func (s Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
case leecher && left == 0:
|
case leecher && left == 0:
|
||||||
// A leecher completed but the event was never received
|
// A leecher completed but the event was never received
|
||||||
err := tx.RemoveLeecher(torrent, peer)
|
err := tx.LeecherFinished(torrent, peer)
|
||||||
if err != nil {
|
|
||||||
log.Panicf("server: %s", err)
|
|
||||||
}
|
|
||||||
err = tx.AddSeeder(torrent, peer)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicf("server: %s", err)
|
log.Panicf("server: %s", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue