go fmt [ci skip]
This commit is contained in:
parent
cf36519c5e
commit
6549f49e26
10 changed files with 1735 additions and 1735 deletions
|
@ -6,83 +6,83 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Duration struct {
|
||||
time.Duration
|
||||
time.Duration
|
||||
}
|
||||
|
||||
func (d *Duration) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(d.String())
|
||||
return json.Marshal(d.String())
|
||||
}
|
||||
|
||||
func (d *Duration) UnmarshalJSON(b []byte) error {
|
||||
var str string
|
||||
err := json.Unmarshal(b, &str)
|
||||
d.Duration, err = time.ParseDuration(str)
|
||||
return err
|
||||
var str string
|
||||
err := json.Unmarshal(b, &str)
|
||||
d.Duration, err = time.ParseDuration(str)
|
||||
return err
|
||||
}
|
||||
|
||||
// DataStore represents the configuration used to connect to a data store.
|
||||
type DataStore struct {
|
||||
Driver string `json:"driver"`
|
||||
Network string `json:"network`
|
||||
Host string `json:"host"`
|
||||
Port string `json:"port"`
|
||||
Username string `json:"user"`
|
||||
Password string `json:"pass"`
|
||||
Schema string `json:"schema,omitempty"`
|
||||
Encoding string `json:"encoding,omitempty"`
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
Driver string `json:"driver"`
|
||||
Network string `json:"network`
|
||||
Host string `json:"host"`
|
||||
Port string `json:"port"`
|
||||
Username string `json:"user"`
|
||||
Password string `json:"pass"`
|
||||
Schema string `json:"schema,omitempty"`
|
||||
Encoding string `json:"encoding,omitempty"`
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
|
||||
MaxIdleConns int `json:"max_idle_conns,omitempty"`
|
||||
IdleTimeout *Duration `json:"idle_timeout,omitempty"`
|
||||
MaxIdleConns int `json:"max_idle_conns,omitempty"`
|
||||
IdleTimeout *Duration `json:"idle_timeout,omitempty"`
|
||||
}
|
||||
|
||||
// Config represents a configuration for a server.Server.
|
||||
type Config struct {
|
||||
Addr string `json:"addr"`
|
||||
PubAddr string `json:"pub_addr"`
|
||||
Cache DataStore `json:"cache"`
|
||||
Storage DataStore `json:"storage"`
|
||||
Addr string `json:"addr"`
|
||||
PubAddr string `json:"pub_addr"`
|
||||
Cache DataStore `json:"cache"`
|
||||
Storage DataStore `json:"storage"`
|
||||
|
||||
Private bool `json:"private"`
|
||||
Freeleech bool `json:"freeleech"`
|
||||
Slots bool `json:"slots"`
|
||||
Private bool `json:"private"`
|
||||
Freeleech bool `json:"freeleech"`
|
||||
Slots bool `json:"slots"`
|
||||
|
||||
Announce Duration `json:"announce"`
|
||||
MinAnnounce Duration `json:"min_announce"`
|
||||
ReadTimeout Duration `json:"read_timeout"`
|
||||
DefaultNumWant int `json:"default_num_want"`
|
||||
Announce Duration `json:"announce"`
|
||||
MinAnnounce Duration `json:"min_announce"`
|
||||
ReadTimeout Duration `json:"read_timeout"`
|
||||
DefaultNumWant int `json:"default_num_want"`
|
||||
}
|
||||
|
||||
// Open is a shortcut to open a file, read it, and generate a Config.
|
||||
// It supports relative and absolute paths.
|
||||
func Open(path string) (*Config, error) {
|
||||
expandedPath := os.ExpandEnv(path)
|
||||
f, err := os.Open(expandedPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
expandedPath := os.ExpandEnv(path)
|
||||
f, err := os.Open(expandedPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
conf, err := newConfig(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conf, nil
|
||||
conf, err := newConfig(f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conf, nil
|
||||
}
|
||||
|
||||
// New decodes JSON from a Reader into a Config.
|
||||
func newConfig(raw io.Reader) (*Config, error) {
|
||||
conf := &Config{}
|
||||
err := json.NewDecoder(raw).Decode(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conf, nil
|
||||
conf := &Config{}
|
||||
err := json.NewDecoder(raw).Decode(conf)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return conf, nil
|
||||
}
|
||||
|
|
|
@ -5,351 +5,351 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
)
|
||||
|
||||
func (s Server) serveAnnounce(w http.ResponseWriter, r *http.Request) {
|
||||
// Parse the required parameters off of a query
|
||||
compact, numWant, infohash, peerID, event, ip, port, uploaded, downloaded, left, err := s.validateAnnounceQuery(r)
|
||||
if err != nil {
|
||||
fail(err, w, r)
|
||||
return
|
||||
}
|
||||
// Parse the required parameters off of a query
|
||||
compact, numWant, infohash, peerID, event, ip, port, uploaded, downloaded, left, err := s.validateAnnounceQuery(r)
|
||||
if err != nil {
|
||||
fail(err, w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Get a connection to the tracker db
|
||||
conn, err := s.dbConnPool.Get()
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
// Get a connection to the tracker db
|
||||
conn, err := s.dbConnPool.Get()
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
|
||||
// Validate the user's passkey
|
||||
passkey, _ := path.Split(r.URL.Path)
|
||||
user, err := validateUser(conn, passkey)
|
||||
if err != nil {
|
||||
fail(err, w, r)
|
||||
return
|
||||
}
|
||||
// Validate the user's passkey
|
||||
passkey, _ := path.Split(r.URL.Path)
|
||||
user, err := validateUser(conn, passkey)
|
||||
if err != nil {
|
||||
fail(err, w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Check if the user's client is whitelisted
|
||||
whitelisted, err := conn.ClientWhitelisted(parsePeerID(peerID))
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if !whitelisted {
|
||||
fail(errors.New("Your client is not approved"), w, r)
|
||||
return
|
||||
}
|
||||
// Check if the user's client is whitelisted
|
||||
whitelisted, err := conn.ClientWhitelisted(parsePeerID(peerID))
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if !whitelisted {
|
||||
fail(errors.New("Your client is not approved"), w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Find the specified torrent
|
||||
torrent, exists, err := conn.FindTorrent(infohash)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if !exists {
|
||||
fail(errors.New("This torrent does not exist"), w, r)
|
||||
return
|
||||
}
|
||||
// Find the specified torrent
|
||||
torrent, exists, err := conn.FindTorrent(infohash)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if !exists {
|
||||
fail(errors.New("This torrent does not exist"), w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// If the torrent was pruned and the user is seeding, unprune it
|
||||
if !torrent.Active && left == 0 {
|
||||
err := conn.MarkActive(torrent)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
// If the torrent was pruned and the user is seeding, unprune it
|
||||
if !torrent.Active && left == 0 {
|
||||
err := conn.MarkActive(torrent)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create a new peer object from the request
|
||||
peer := &storage.Peer{
|
||||
ID: peerID,
|
||||
UserID: user.ID,
|
||||
TorrentID: torrent.ID,
|
||||
IP: ip,
|
||||
Port: port,
|
||||
Uploaded: uploaded,
|
||||
Downloaded: downloaded,
|
||||
Left: left,
|
||||
LastAnnounce: time.Now().Unix(),
|
||||
}
|
||||
// Create a new peer object from the request
|
||||
peer := &storage.Peer{
|
||||
ID: peerID,
|
||||
UserID: user.ID,
|
||||
TorrentID: torrent.ID,
|
||||
IP: ip,
|
||||
Port: port,
|
||||
Uploaded: uploaded,
|
||||
Downloaded: downloaded,
|
||||
Left: left,
|
||||
LastAnnounce: time.Now().Unix(),
|
||||
}
|
||||
|
||||
// Look for the user in in the pool of seeders and leechers
|
||||
_, seeder := torrent.Seeders[storage.PeerMapKey(peer)]
|
||||
_, leecher := torrent.Leechers[storage.PeerMapKey(peer)]
|
||||
// Look for the user in in the pool of seeders and leechers
|
||||
_, seeder := torrent.Seeders[storage.PeerMapKey(peer)]
|
||||
_, leecher := torrent.Leechers[storage.PeerMapKey(peer)]
|
||||
|
||||
switch {
|
||||
// Guarantee that no user is in both pools
|
||||
case seeder && leecher:
|
||||
if left == 0 {
|
||||
err := conn.RemoveLeecher(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
leecher = false
|
||||
} else {
|
||||
err := conn.RemoveSeeder(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
seeder = false
|
||||
}
|
||||
switch {
|
||||
// Guarantee that no user is in both pools
|
||||
case seeder && leecher:
|
||||
if left == 0 {
|
||||
err := conn.RemoveLeecher(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
leecher = false
|
||||
} else {
|
||||
err := conn.RemoveSeeder(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
seeder = false
|
||||
}
|
||||
|
||||
case seeder:
|
||||
// Update the peer with the stats from the request
|
||||
err := conn.SetSeeder(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
case seeder:
|
||||
// Update the peer with the stats from the request
|
||||
err := conn.SetSeeder(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
|
||||
case leecher:
|
||||
// Update the peer with the stats from the request
|
||||
err := conn.SetLeecher(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
case leecher:
|
||||
// Update the peer with the stats from the request
|
||||
err := conn.SetLeecher(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
|
||||
default:
|
||||
// Check the user's slots to see if they're allowed to leech
|
||||
if s.conf.Slots && user.Slots != -1 && left != 0 {
|
||||
if user.SlotsUsed >= user.Slots {
|
||||
fail(errors.New("You've run out of download slots."), w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
default:
|
||||
// Check the user's slots to see if they're allowed to leech
|
||||
if s.conf.Slots && user.Slots != -1 && left != 0 {
|
||||
if user.SlotsUsed >= user.Slots {
|
||||
fail(errors.New("You've run out of download slots."), w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if left == 0 {
|
||||
// Save the peer as a new seeder
|
||||
err := conn.AddSeeder(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
} else {
|
||||
// Save the peer as a new leecher and increment the user's slots
|
||||
err := conn.IncrementSlots(user)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
err = conn.AddLeecher(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if left == 0 {
|
||||
// Save the peer as a new seeder
|
||||
err := conn.AddSeeder(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
} else {
|
||||
// Save the peer as a new leecher and increment the user's slots
|
||||
err := conn.IncrementSlots(user)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
err = conn.AddLeecher(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Handle any events in the request
|
||||
switch {
|
||||
case event == "stopped" || event == "paused":
|
||||
if seeder {
|
||||
err := conn.RemoveSeeder(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
if leecher {
|
||||
err := conn.RemoveLeecher(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
err = conn.DecrementSlots(user)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
// Handle any events in the request
|
||||
switch {
|
||||
case event == "stopped" || event == "paused":
|
||||
if seeder {
|
||||
err := conn.RemoveSeeder(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
if leecher {
|
||||
err := conn.RemoveLeecher(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
err = conn.DecrementSlots(user)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
case event == "completed":
|
||||
err := conn.RecordSnatch(user, torrent)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if leecher {
|
||||
err := conn.LeecherFinished(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
case event == "completed":
|
||||
err := conn.RecordSnatch(user, torrent)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if leecher {
|
||||
err := conn.LeecherFinished(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
case leecher && left == 0:
|
||||
// A leecher completed but the event was never received
|
||||
err := conn.LeecherFinished(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
case leecher && left == 0:
|
||||
// A leecher completed but the event was never received
|
||||
err := conn.LeecherFinished(torrent, peer)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
if ip != peer.IP || port != peer.Port {
|
||||
peer.Port = port
|
||||
peer.IP = ip
|
||||
}
|
||||
if ip != peer.IP || port != peer.Port {
|
||||
peer.Port = port
|
||||
peer.IP = ip
|
||||
}
|
||||
|
||||
// Generate the response
|
||||
seedCount := len(torrent.Seeders)
|
||||
leechCount := len(torrent.Leechers)
|
||||
// Generate the response
|
||||
seedCount := len(torrent.Seeders)
|
||||
leechCount := len(torrent.Leechers)
|
||||
|
||||
writeBencoded(w, "d")
|
||||
writeBencoded(w, "complete")
|
||||
writeBencoded(w, seedCount)
|
||||
writeBencoded(w, "incomplete")
|
||||
writeBencoded(w, leechCount)
|
||||
writeBencoded(w, "interval")
|
||||
writeBencoded(w, s.conf.Announce.Duration)
|
||||
writeBencoded(w, "min interval")
|
||||
writeBencoded(w, s.conf.MinAnnounce.Duration)
|
||||
writeBencoded(w, "d")
|
||||
writeBencoded(w, "complete")
|
||||
writeBencoded(w, seedCount)
|
||||
writeBencoded(w, "incomplete")
|
||||
writeBencoded(w, leechCount)
|
||||
writeBencoded(w, "interval")
|
||||
writeBencoded(w, s.conf.Announce.Duration)
|
||||
writeBencoded(w, "min interval")
|
||||
writeBencoded(w, s.conf.MinAnnounce.Duration)
|
||||
|
||||
if numWant > 0 && event != "stopped" && event != "paused" {
|
||||
writeBencoded(w, "peers")
|
||||
var peerCount, count int
|
||||
if numWant > 0 && event != "stopped" && event != "paused" {
|
||||
writeBencoded(w, "peers")
|
||||
var peerCount, count int
|
||||
|
||||
if compact {
|
||||
if left > 0 {
|
||||
peerCount = minInt(numWant, leechCount)
|
||||
} else {
|
||||
peerCount = minInt(numWant, leechCount+seedCount-1)
|
||||
}
|
||||
writeBencoded(w, strconv.Itoa(peerCount*6))
|
||||
writeBencoded(w, ":")
|
||||
} else {
|
||||
writeBencoded(w, "l")
|
||||
}
|
||||
if compact {
|
||||
if left > 0 {
|
||||
peerCount = minInt(numWant, leechCount)
|
||||
} else {
|
||||
peerCount = minInt(numWant, leechCount+seedCount-1)
|
||||
}
|
||||
writeBencoded(w, strconv.Itoa(peerCount*6))
|
||||
writeBencoded(w, ":")
|
||||
} else {
|
||||
writeBencoded(w, "l")
|
||||
}
|
||||
|
||||
if left > 0 {
|
||||
// If they're seeding, give them only leechers
|
||||
writeLeechers(w, torrent, count, numWant, compact)
|
||||
} else {
|
||||
// If they're leeching, prioritize giving them seeders
|
||||
writeSeeders(w, torrent, count, numWant, compact)
|
||||
writeLeechers(w, torrent, count, numWant, compact)
|
||||
}
|
||||
if left > 0 {
|
||||
// If they're seeding, give them only leechers
|
||||
writeLeechers(w, torrent, count, numWant, compact)
|
||||
} else {
|
||||
// If they're leeching, prioritize giving them seeders
|
||||
writeSeeders(w, torrent, count, numWant, compact)
|
||||
writeLeechers(w, torrent, count, numWant, compact)
|
||||
}
|
||||
|
||||
if compact && peerCount != count {
|
||||
log.Panicf("Calculated peer count (%d) != real count (%d)", peerCount, count)
|
||||
}
|
||||
if compact && peerCount != count {
|
||||
log.Panicf("Calculated peer count (%d) != real count (%d)", peerCount, count)
|
||||
}
|
||||
|
||||
if !compact {
|
||||
writeBencoded(w, "e")
|
||||
}
|
||||
}
|
||||
writeBencoded(w, "e")
|
||||
if !compact {
|
||||
writeBencoded(w, "e")
|
||||
}
|
||||
}
|
||||
writeBencoded(w, "e")
|
||||
}
|
||||
|
||||
func (s Server) validateAnnounceQuery(r *http.Request) (compact bool, numWant int, infohash, peerID, event, ip string, port, uploaded, downloaded, left uint64, err error) {
|
||||
pq, err := parseQuery(r.URL.RawQuery)
|
||||
if err != nil {
|
||||
return false, 0, "", "", "", "", 0, 0, 0, 0, err
|
||||
}
|
||||
pq, err := parseQuery(r.URL.RawQuery)
|
||||
if err != nil {
|
||||
return false, 0, "", "", "", "", 0, 0, 0, 0, err
|
||||
}
|
||||
|
||||
compact = pq.Params["compact"] == "1"
|
||||
numWant = requestedPeerCount(s.conf.DefaultNumWant, pq)
|
||||
infohash, _ = pq.Params["info_hash"]
|
||||
peerID, _ = pq.Params["peer_id"]
|
||||
event, _ = pq.Params["event"]
|
||||
ip, _ = requestedIP(r, pq)
|
||||
port, portErr := pq.getUint64("port")
|
||||
uploaded, uploadedErr := pq.getUint64("uploaded")
|
||||
downloaded, downloadedErr := pq.getUint64("downloaded")
|
||||
left, leftErr := pq.getUint64("left")
|
||||
compact = pq.Params["compact"] == "1"
|
||||
numWant = requestedPeerCount(s.conf.DefaultNumWant, pq)
|
||||
infohash, _ = pq.Params["info_hash"]
|
||||
peerID, _ = pq.Params["peer_id"]
|
||||
event, _ = pq.Params["event"]
|
||||
ip, _ = requestedIP(r, pq)
|
||||
port, portErr := pq.getUint64("port")
|
||||
uploaded, uploadedErr := pq.getUint64("uploaded")
|
||||
downloaded, downloadedErr := pq.getUint64("downloaded")
|
||||
left, leftErr := pq.getUint64("left")
|
||||
|
||||
if infohash == "" ||
|
||||
peerID == "" ||
|
||||
ip == "" ||
|
||||
portErr != nil ||
|
||||
uploadedErr != nil ||
|
||||
downloadedErr != nil ||
|
||||
leftErr != nil {
|
||||
return false, 0, "", "", "", "", 0, 0, 0, 0, errors.New("Malformed request")
|
||||
}
|
||||
return
|
||||
if infohash == "" ||
|
||||
peerID == "" ||
|
||||
ip == "" ||
|
||||
portErr != nil ||
|
||||
uploadedErr != nil ||
|
||||
downloadedErr != nil ||
|
||||
leftErr != nil {
|
||||
return false, 0, "", "", "", "", 0, 0, 0, 0, errors.New("Malformed request")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func requestedPeerCount(fallback int, pq *parsedQuery) int {
|
||||
if numWantStr, exists := pq.Params["numWant"]; exists {
|
||||
numWant, err := strconv.Atoi(numWantStr)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
return numWant
|
||||
}
|
||||
return fallback
|
||||
if numWantStr, exists := pq.Params["numWant"]; exists {
|
||||
numWant, err := strconv.Atoi(numWantStr)
|
||||
if err != nil {
|
||||
return fallback
|
||||
}
|
||||
return numWant
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func requestedIP(r *http.Request, pq *parsedQuery) (string, error) {
|
||||
ip, ok := pq.Params["ip"]
|
||||
ipv4, okv4 := pq.Params["ipv4"]
|
||||
xRealIPs, xRealOk := pq.Params["X-Real-Ip"]
|
||||
ip, ok := pq.Params["ip"]
|
||||
ipv4, okv4 := pq.Params["ipv4"]
|
||||
xRealIPs, xRealOk := pq.Params["X-Real-Ip"]
|
||||
|
||||
switch {
|
||||
case ok:
|
||||
return ip, nil
|
||||
switch {
|
||||
case ok:
|
||||
return ip, nil
|
||||
|
||||
case okv4:
|
||||
return ipv4, nil
|
||||
case okv4:
|
||||
return ipv4, nil
|
||||
|
||||
case xRealOk && len(xRealIPs) > 0:
|
||||
return string(xRealIPs[0]), nil
|
||||
case xRealOk && len(xRealIPs) > 0:
|
||||
return string(xRealIPs[0]), nil
|
||||
|
||||
default:
|
||||
portIndex := len(r.RemoteAddr) - 1
|
||||
for ; portIndex >= 0; portIndex-- {
|
||||
if r.RemoteAddr[portIndex] == ':' {
|
||||
break
|
||||
}
|
||||
}
|
||||
if portIndex != -1 {
|
||||
return r.RemoteAddr[0:portIndex], nil
|
||||
}
|
||||
return "", errors.New("Failed to parse IP address")
|
||||
}
|
||||
default:
|
||||
portIndex := len(r.RemoteAddr) - 1
|
||||
for ; portIndex >= 0; portIndex-- {
|
||||
if r.RemoteAddr[portIndex] == ':' {
|
||||
break
|
||||
}
|
||||
}
|
||||
if portIndex != -1 {
|
||||
return r.RemoteAddr[0:portIndex], nil
|
||||
}
|
||||
return "", errors.New("Failed to parse IP address")
|
||||
}
|
||||
}
|
||||
|
||||
func minInt(a, b int) int {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func writeSeeders(w http.ResponseWriter, t *storage.Torrent, count, numWant int, compact bool) {
|
||||
for _, seed := range t.Seeders {
|
||||
if count >= numWant {
|
||||
break
|
||||
}
|
||||
if compact {
|
||||
// TODO writeBencoded(w, compactAddr)
|
||||
} else {
|
||||
writeBencoded(w, "d")
|
||||
writeBencoded(w, "ip")
|
||||
writeBencoded(w, seed.IP)
|
||||
writeBencoded(w, "peer id")
|
||||
writeBencoded(w, seed.ID)
|
||||
writeBencoded(w, "port")
|
||||
writeBencoded(w, seed.Port)
|
||||
writeBencoded(w, "e")
|
||||
}
|
||||
count++
|
||||
}
|
||||
for _, seed := range t.Seeders {
|
||||
if count >= numWant {
|
||||
break
|
||||
}
|
||||
if compact {
|
||||
// TODO writeBencoded(w, compactAddr)
|
||||
} else {
|
||||
writeBencoded(w, "d")
|
||||
writeBencoded(w, "ip")
|
||||
writeBencoded(w, seed.IP)
|
||||
writeBencoded(w, "peer id")
|
||||
writeBencoded(w, seed.ID)
|
||||
writeBencoded(w, "port")
|
||||
writeBencoded(w, seed.Port)
|
||||
writeBencoded(w, "e")
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
||||
func writeLeechers(w http.ResponseWriter, t *storage.Torrent, count, numWant int, compact bool) {
|
||||
for _, leech := range t.Leechers {
|
||||
if count >= numWant {
|
||||
break
|
||||
}
|
||||
if compact {
|
||||
// TODO writeBencoded(w, compactAddr)
|
||||
} else {
|
||||
writeBencoded(w, "d")
|
||||
writeBencoded(w, "ip")
|
||||
writeBencoded(w, leech.IP)
|
||||
writeBencoded(w, "peer id")
|
||||
writeBencoded(w, leech.ID)
|
||||
writeBencoded(w, "port")
|
||||
writeBencoded(w, leech.Port)
|
||||
writeBencoded(w, "e")
|
||||
}
|
||||
count++
|
||||
}
|
||||
for _, leech := range t.Leechers {
|
||||
if count >= numWant {
|
||||
break
|
||||
}
|
||||
if compact {
|
||||
// TODO writeBencoded(w, compactAddr)
|
||||
} else {
|
||||
writeBencoded(w, "d")
|
||||
writeBencoded(w, "ip")
|
||||
writeBencoded(w, leech.IP)
|
||||
writeBencoded(w, "peer id")
|
||||
writeBencoded(w, leech.ID)
|
||||
writeBencoded(w, "port")
|
||||
writeBencoded(w, leech.Port)
|
||||
writeBencoded(w, "e")
|
||||
}
|
||||
count++
|
||||
}
|
||||
}
|
||||
|
|
114
server/scrape.go
114
server/scrape.go
|
@ -5,72 +5,72 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"path"
|
||||
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
)
|
||||
|
||||
func (s *Server) serveScrape(w http.ResponseWriter, r *http.Request) {
|
||||
// Parse the query
|
||||
pq, err := parseQuery(r.URL.RawQuery)
|
||||
if err != nil {
|
||||
fail(errors.New("Error parsing query"), w, r)
|
||||
return
|
||||
}
|
||||
// Parse the query
|
||||
pq, err := parseQuery(r.URL.RawQuery)
|
||||
if err != nil {
|
||||
fail(errors.New("Error parsing query"), w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// Get a connection to the tracker db
|
||||
conn, err := s.dbConnPool.Get()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
// Get a connection to the tracker db
|
||||
conn, err := s.dbConnPool.Get()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Find and validate the user
|
||||
passkey, _ := path.Split(r.URL.Path)
|
||||
_, err = validateUser(conn, passkey)
|
||||
if err != nil {
|
||||
fail(err, w, r)
|
||||
return
|
||||
}
|
||||
// Find and validate the user
|
||||
passkey, _ := path.Split(r.URL.Path)
|
||||
_, err = validateUser(conn, passkey)
|
||||
if err != nil {
|
||||
fail(err, w, r)
|
||||
return
|
||||
}
|
||||
|
||||
io.WriteString(w, "d")
|
||||
writeBencoded(w, "files")
|
||||
if pq.Infohashes != nil {
|
||||
for _, infohash := range pq.Infohashes {
|
||||
torrent, exists, err := conn.FindTorrent(infohash)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if exists {
|
||||
writeBencoded(w, infohash)
|
||||
writeScrapeInfo(w, torrent)
|
||||
}
|
||||
}
|
||||
} else if infohash, exists := pq.Params["info_hash"]; exists {
|
||||
torrent, exists, err := conn.FindTorrent(infohash)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if exists {
|
||||
writeBencoded(w, infohash)
|
||||
writeScrapeInfo(w, torrent)
|
||||
}
|
||||
}
|
||||
io.WriteString(w, "e")
|
||||
io.WriteString(w, "d")
|
||||
writeBencoded(w, "files")
|
||||
if pq.Infohashes != nil {
|
||||
for _, infohash := range pq.Infohashes {
|
||||
torrent, exists, err := conn.FindTorrent(infohash)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if exists {
|
||||
writeBencoded(w, infohash)
|
||||
writeScrapeInfo(w, torrent)
|
||||
}
|
||||
}
|
||||
} else if infohash, exists := pq.Params["info_hash"]; exists {
|
||||
torrent, exists, err := conn.FindTorrent(infohash)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if exists {
|
||||
writeBencoded(w, infohash)
|
||||
writeScrapeInfo(w, torrent)
|
||||
}
|
||||
}
|
||||
io.WriteString(w, "e")
|
||||
|
||||
w.(http.Flusher).Flush()
|
||||
w.(http.Flusher).Flush()
|
||||
}
|
||||
|
||||
func writeScrapeInfo(w io.Writer, torrent *storage.Torrent) {
|
||||
io.WriteString(w, "d")
|
||||
writeBencoded(w, "complete")
|
||||
writeBencoded(w, len(torrent.Seeders))
|
||||
writeBencoded(w, "downloaded")
|
||||
writeBencoded(w, torrent.Snatches)
|
||||
writeBencoded(w, "incomplete")
|
||||
writeBencoded(w, len(torrent.Leechers))
|
||||
io.WriteString(w, "e")
|
||||
io.WriteString(w, "d")
|
||||
writeBencoded(w, "complete")
|
||||
writeBencoded(w, len(torrent.Seeders))
|
||||
writeBencoded(w, "downloaded")
|
||||
writeBencoded(w, torrent.Snatches)
|
||||
writeBencoded(w, "incomplete")
|
||||
writeBencoded(w, len(torrent.Leechers))
|
||||
io.WriteString(w, "e")
|
||||
}
|
||||
|
|
196
server/server.go
196
server/server.go
|
@ -6,140 +6,140 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"errors"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"path"
|
||||
"strconv"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/etix/stoppableListener"
|
||||
"github.com/etix/stoppableListener"
|
||||
|
||||
"github.com/pushrax/chihaya/config"
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
"github.com/pushrax/chihaya/storage/tracker"
|
||||
"github.com/pushrax/chihaya/config"
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
"github.com/pushrax/chihaya/storage/tracker"
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
conf *config.Config
|
||||
listener *stoppableListener.StoppableListener
|
||||
dbConnPool tracker.Pool
|
||||
conf *config.Config
|
||||
listener *stoppableListener.StoppableListener
|
||||
dbConnPool tracker.Pool
|
||||
|
||||
startTime time.Time
|
||||
startTime time.Time
|
||||
|
||||
deltaRequests int64
|
||||
rpm int64
|
||||
deltaRequests int64
|
||||
rpm int64
|
||||
|
||||
http.Server
|
||||
http.Server
|
||||
}
|
||||
|
||||
func New(conf *config.Config) (*Server, error) {
|
||||
pool, err := tracker.Open(&conf.Cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
pool, err := tracker.Open(&conf.Cache)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s := &Server{
|
||||
conf: conf,
|
||||
dbConnPool: pool,
|
||||
Server: http.Server{
|
||||
Addr: conf.Addr,
|
||||
ReadTimeout: conf.ReadTimeout.Duration,
|
||||
},
|
||||
}
|
||||
s.Server.Handler = s
|
||||
s := &Server{
|
||||
conf: conf,
|
||||
dbConnPool: pool,
|
||||
Server: http.Server{
|
||||
Addr: conf.Addr,
|
||||
ReadTimeout: conf.ReadTimeout.Duration,
|
||||
},
|
||||
}
|
||||
s.Server.Handler = s
|
||||
|
||||
return s, nil
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func (s *Server) ListenAndServe() error {
|
||||
l, err := net.Listen("tcp", s.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sl := stoppableListener.Handle(l)
|
||||
s.listener = sl
|
||||
s.startTime = time.Now()
|
||||
l, err := net.Listen("tcp", s.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sl := stoppableListener.Handle(l)
|
||||
s.listener = sl
|
||||
s.startTime = time.Now()
|
||||
|
||||
go s.updateStats()
|
||||
s.Serve(s.listener)
|
||||
go s.updateStats()
|
||||
s.Serve(s.listener)
|
||||
|
||||
return nil
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) Stop() error {
|
||||
s.listener.Stop <- true
|
||||
err := s.dbConnPool.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.listener.Close()
|
||||
s.listener.Stop <- true
|
||||
err := s.dbConnPool.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return s.listener.Close()
|
||||
}
|
||||
|
||||
func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
defer atomic.AddInt64(&s.deltaRequests, 1)
|
||||
r.Close = true
|
||||
defer atomic.AddInt64(&s.deltaRequests, 1)
|
||||
r.Close = true
|
||||
|
||||
switch r.URL.Path {
|
||||
case "/stats":
|
||||
s.serveStats(w, r)
|
||||
return
|
||||
case "/add":
|
||||
s.serveAdd(w, r)
|
||||
return
|
||||
case "/remove":
|
||||
s.serveRemove(w, r)
|
||||
return
|
||||
}
|
||||
switch r.URL.Path {
|
||||
case "/stats":
|
||||
s.serveStats(w, r)
|
||||
return
|
||||
case "/add":
|
||||
s.serveAdd(w, r)
|
||||
return
|
||||
case "/remove":
|
||||
s.serveRemove(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
_, action := path.Split(r.URL.Path)
|
||||
switch action {
|
||||
case "announce":
|
||||
s.serveAnnounce(w, r)
|
||||
return
|
||||
case "scrape":
|
||||
s.serveScrape(w, r)
|
||||
return
|
||||
default:
|
||||
fail(errors.New("Unknown action"), w, r)
|
||||
return
|
||||
}
|
||||
_, action := path.Split(r.URL.Path)
|
||||
switch action {
|
||||
case "announce":
|
||||
s.serveAnnounce(w, r)
|
||||
return
|
||||
case "scrape":
|
||||
s.serveScrape(w, r)
|
||||
return
|
||||
default:
|
||||
fail(errors.New("Unknown action"), w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func fail(err error, w http.ResponseWriter, r *http.Request) {
|
||||
errmsg := err.Error()
|
||||
message := "d14:failure reason" + strconv.Itoa(len(errmsg)) + ":" + errmsg + "e"
|
||||
length, _ := io.WriteString(w, message)
|
||||
w.Header().Add("Content-Length", string(length))
|
||||
w.(http.Flusher).Flush()
|
||||
errmsg := err.Error()
|
||||
message := "d14:failure reason" + strconv.Itoa(len(errmsg)) + ":" + errmsg + "e"
|
||||
length, _ := io.WriteString(w, message)
|
||||
w.Header().Add("Content-Length", string(length))
|
||||
w.(http.Flusher).Flush()
|
||||
}
|
||||
|
||||
func validateUser(conn tracker.Conn, dir string) (*storage.User, error) {
|
||||
if len(dir) != 34 {
|
||||
return nil, errors.New("Passkey is invalid")
|
||||
}
|
||||
passkey := dir[1:33]
|
||||
if len(dir) != 34 {
|
||||
return nil, errors.New("Passkey is invalid")
|
||||
}
|
||||
passkey := dir[1:33]
|
||||
|
||||
user, exists, err := conn.FindUser(passkey)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.New("User not found")
|
||||
}
|
||||
user, exists, err := conn.FindUser(passkey)
|
||||
if err != nil {
|
||||
log.Panicf("server: %s", err)
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.New("User not found")
|
||||
}
|
||||
|
||||
return user, nil
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// Takes a peer_id and returns a ClientID
|
||||
func parsePeerID(peerID string) (clientID string) {
|
||||
if peerID[0] == '-' {
|
||||
clientID = peerID[1:7]
|
||||
} else {
|
||||
clientID = peerID[0:6]
|
||||
}
|
||||
return
|
||||
if peerID[0] == '-' {
|
||||
clientID = peerID[1:7]
|
||||
} else {
|
||||
clientID = peerID[0:6]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -5,35 +5,35 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/pushrax/chihaya/config"
|
||||
"github.com/pushrax/chihaya/config"
|
||||
)
|
||||
|
||||
type stats struct {
|
||||
Uptime config.Duration `json:"uptime"`
|
||||
RPM int64 `json:"req_per_min"`
|
||||
Uptime config.Duration `json:"uptime"`
|
||||
RPM int64 `json:"req_per_min"`
|
||||
}
|
||||
|
||||
func (s *Server) serveStats(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
stats, _ := json.Marshal(&stats{
|
||||
config.Duration{time.Now().Sub(s.startTime)},
|
||||
s.rpm,
|
||||
})
|
||||
stats, _ := json.Marshal(&stats{
|
||||
config.Duration{time.Now().Sub(s.startTime)},
|
||||
s.rpm,
|
||||
})
|
||||
|
||||
length, _ := w.Write(stats)
|
||||
w.Header().Set("Content-Length", string(length))
|
||||
w.(http.Flusher).Flush()
|
||||
length, _ := w.Write(stats)
|
||||
w.Header().Set("Content-Length", string(length))
|
||||
w.(http.Flusher).Flush()
|
||||
}
|
||||
|
||||
func (s *Server) updateStats() {
|
||||
for _ = range time.NewTicker(time.Minute).C {
|
||||
s.rpm = s.deltaRequests
|
||||
atomic.StoreInt64(&s.deltaRequests, 0)
|
||||
}
|
||||
for _ = range time.NewTicker(time.Minute).C {
|
||||
s.rpm = s.deltaRequests
|
||||
atomic.StoreInt64(&s.deltaRequests, 0)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,51 +5,51 @@
|
|||
package server
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/pushrax/chihaya/config"
|
||||
"github.com/pushrax/chihaya/config"
|
||||
|
||||
_ "github.com/pushrax/chihaya/storage/backend/batter"
|
||||
_ "github.com/pushrax/chihaya/storage/tracker/redis"
|
||||
_ "github.com/pushrax/chihaya/storage/backend/batter"
|
||||
_ "github.com/pushrax/chihaya/storage/tracker/redis"
|
||||
)
|
||||
|
||||
func newTestServer() (*Server, error) {
|
||||
testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
s, err := New(testConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s, err := New(testConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s, nil
|
||||
return s, nil
|
||||
}
|
||||
|
||||
func TestStats(t *testing.T) {
|
||||
s, err := newTestServer()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
s, err := newTestServer()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
r, err := http.NewRequest("GET", "127.0.0.1:80/stats", nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
r, err := http.NewRequest("GET", "127.0.0.1:80/stats", nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
w := httptest.NewRecorder()
|
||||
s.serveStats(w, r)
|
||||
w := httptest.NewRecorder()
|
||||
s.serveStats(w, r)
|
||||
|
||||
if w.Code != 200 {
|
||||
t.Error(errors.New("/stats did not return HTTP 200"))
|
||||
}
|
||||
if w.Code != 200 {
|
||||
t.Error(errors.New("/stats did not return HTTP 200"))
|
||||
}
|
||||
|
||||
if w.Header()["Content-Type"][0] != "application/json" {
|
||||
t.Error(errors.New("/stats did not return the proper Content-Type header"))
|
||||
}
|
||||
if w.Header()["Content-Type"][0] != "application/json" {
|
||||
t.Error(errors.New("/stats did not return the proper Content-Type header"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,559 +5,559 @@
|
|||
package redis
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
"math/rand"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/pushrax/chihaya/config"
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
"github.com/pushrax/chihaya/storage/tracker"
|
||||
"github.com/pushrax/chihaya/config"
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
"github.com/pushrax/chihaya/storage/tracker"
|
||||
)
|
||||
|
||||
func createTestConn() tracker.Conn {
|
||||
testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH"))
|
||||
panicOnErr(err)
|
||||
conf := &testConfig.Cache
|
||||
testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH"))
|
||||
panicOnErr(err)
|
||||
conf := &testConfig.Cache
|
||||
|
||||
testPool, err := tracker.Open(conf)
|
||||
panicOnErr(err)
|
||||
testPool, err := tracker.Open(conf)
|
||||
panicOnErr(err)
|
||||
|
||||
newConn, err := testPool.Get()
|
||||
panicOnErr(err)
|
||||
newConn, err := testPool.Get()
|
||||
panicOnErr(err)
|
||||
|
||||
return newConn
|
||||
return newConn
|
||||
}
|
||||
|
||||
func TestFindUserSuccess(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
foundUser, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("user not found", testUser)
|
||||
}
|
||||
if *foundUser != *testUser {
|
||||
t.Error("found user mismatch", *foundUser, testUser)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
foundUser, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("user not found", testUser)
|
||||
}
|
||||
if *foundUser != *testUser {
|
||||
t.Error("found user mismatch", *foundUser, testUser)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
}
|
||||
|
||||
func TestFindUserFail(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
|
||||
foundUser, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("user found", foundUser)
|
||||
}
|
||||
foundUser, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("user found", foundUser)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveUser(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
err := conn.RemoveUser(testUser)
|
||||
panicOnErr(err)
|
||||
foundUser, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("removed user found", foundUser)
|
||||
}
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
err := conn.RemoveUser(testUser)
|
||||
panicOnErr(err)
|
||||
foundUser, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("removed user found", foundUser)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindTorrentSuccess(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("torrent not found", testTorrent)
|
||||
}
|
||||
if !reflect.DeepEqual(foundTorrent, testTorrent) {
|
||||
t.Error("found torrent mismatch", foundTorrent, testTorrent)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("torrent not found", testTorrent)
|
||||
}
|
||||
if !reflect.DeepEqual(foundTorrent, testTorrent) {
|
||||
t.Error("found torrent mismatch", foundTorrent, testTorrent)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestFindTorrentFail(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("torrent found", foundTorrent)
|
||||
}
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("torrent found", foundTorrent)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveTorrent(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("removed torrent found", foundTorrent)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("removed torrent found", foundTorrent)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestClientWhitelistSuccess(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testPeerID := "-lt0D30-"
|
||||
conn := createTestConn()
|
||||
testPeerID := "-lt0D30-"
|
||||
|
||||
panicOnErr(conn.WhitelistClient(testPeerID))
|
||||
found, err := conn.ClientWhitelisted(testPeerID)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("peerID not found", testPeerID)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.UnWhitelistClient(testPeerID))
|
||||
panicOnErr(conn.WhitelistClient(testPeerID))
|
||||
found, err := conn.ClientWhitelisted(testPeerID)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("peerID not found", testPeerID)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.UnWhitelistClient(testPeerID))
|
||||
}
|
||||
|
||||
func TestClientWhitelistFail(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testPeerID2 := "TIX0192"
|
||||
conn := createTestConn()
|
||||
testPeerID2 := "TIX0192"
|
||||
|
||||
found, err := conn.ClientWhitelisted(testPeerID2)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("peerID found", testPeerID2)
|
||||
}
|
||||
found, err := conn.ClientWhitelisted(testPeerID2)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("peerID found", testPeerID2)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRecordSnatch(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
|
||||
userSnatches := testUser.Snatches
|
||||
torrentSnatches := testTorrent.Snatches
|
||||
userSnatches := testUser.Snatches
|
||||
torrentSnatches := testTorrent.Snatches
|
||||
|
||||
panicOnErr(conn.RecordSnatch(testUser, testTorrent))
|
||||
panicOnErr(conn.RecordSnatch(testUser, testTorrent))
|
||||
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundUser, _, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundUser, _, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
|
||||
if testUser.Snatches != userSnatches+1 {
|
||||
t.Error("snatch not recorded to local user", testUser.Snatches, userSnatches+1)
|
||||
}
|
||||
if testTorrent.Snatches != torrentSnatches+1 {
|
||||
t.Error("snatch not recorded to local torrent")
|
||||
}
|
||||
if foundUser.Snatches != userSnatches+1 {
|
||||
t.Error("snatch not recorded to cached user", foundUser.Snatches, userSnatches+1)
|
||||
}
|
||||
if foundTorrent.Snatches != torrentSnatches+1 {
|
||||
t.Error("snatch not recorded to cached torrent")
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
if testUser.Snatches != userSnatches+1 {
|
||||
t.Error("snatch not recorded to local user", testUser.Snatches, userSnatches+1)
|
||||
}
|
||||
if testTorrent.Snatches != torrentSnatches+1 {
|
||||
t.Error("snatch not recorded to local torrent")
|
||||
}
|
||||
if foundUser.Snatches != userSnatches+1 {
|
||||
t.Error("snatch not recorded to cached user", foundUser.Snatches, userSnatches+1)
|
||||
}
|
||||
if foundTorrent.Snatches != torrentSnatches+1 {
|
||||
t.Error("snatch not recorded to cached torrent")
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
}
|
||||
|
||||
func TestMarkActive(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testTorrent.Active = false
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testTorrent.Active = false
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
|
||||
panicOnErr(conn.MarkActive(testTorrent))
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
panicOnErr(conn.MarkActive(testTorrent))
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
|
||||
if foundTorrent.Active != true {
|
||||
t.Error("cached torrent not activated")
|
||||
}
|
||||
if testTorrent.Active != true {
|
||||
t.Error("cached torrent not activated")
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
if foundTorrent.Active != true {
|
||||
t.Error("cached torrent not activated")
|
||||
}
|
||||
if testTorrent.Active != true {
|
||||
t.Error("cached torrent not activated")
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestClientWhitelistRemove(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testPeerID := "-lt0D30-"
|
||||
panicOnErr(conn.WhitelistClient(testPeerID))
|
||||
panicOnErr(conn.UnWhitelistClient(testPeerID))
|
||||
conn := createTestConn()
|
||||
testPeerID := "-lt0D30-"
|
||||
panicOnErr(conn.WhitelistClient(testPeerID))
|
||||
panicOnErr(conn.UnWhitelistClient(testPeerID))
|
||||
|
||||
found, err := conn.ClientWhitelisted(testPeerID)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("removed peerID found", testPeerID)
|
||||
}
|
||||
found, err := conn.ClientWhitelisted(testPeerID)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("removed peerID found", testPeerID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddSeeder(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, found := foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if found && foundSeeder != *testSeeder {
|
||||
t.Error("seeder not added to cache", testSeeder)
|
||||
}
|
||||
foundSeeder, found = testTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if found && foundSeeder != *testSeeder {
|
||||
t.Error("seeder not added to local", testSeeder)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, found := foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if found && foundSeeder != *testSeeder {
|
||||
t.Error("seeder not added to cache", testSeeder)
|
||||
}
|
||||
foundSeeder, found = testTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if found && foundSeeder != *testSeeder {
|
||||
t.Error("seeder not added to local", testSeeder)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestAddLeecher(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundLeecher, found := foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to cache", testLeecher)
|
||||
}
|
||||
foundLeecher, found = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to local", testLeecher)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundLeecher, found := foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to cache", testLeecher)
|
||||
}
|
||||
foundLeecher, found = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to local", testLeecher)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestRemoveSeeder(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
|
||||
panicOnErr(conn.RemoveSeeder(testTorrent, testSeeder))
|
||||
foundSeeder, found := testTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if found || foundSeeder == *testSeeder {
|
||||
t.Error("seeder not removed from local", foundSeeder)
|
||||
}
|
||||
panicOnErr(conn.RemoveSeeder(testTorrent, testSeeder))
|
||||
foundSeeder, found := testTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if found || foundSeeder == *testSeeder {
|
||||
t.Error("seeder not removed from local", foundSeeder)
|
||||
}
|
||||
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, found = foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if found || foundSeeder == *testSeeder {
|
||||
t.Error("seeder not removed from cache", foundSeeder, *testSeeder)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, found = foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if found || foundSeeder == *testSeeder {
|
||||
t.Error("seeder not removed from cache", foundSeeder, *testSeeder)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestRemoveLeecher(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
|
||||
panicOnErr(conn.RemoveLeecher(testTorrent, testLeecher))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundLeecher, found := foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found || foundLeecher == *testLeecher {
|
||||
t.Error("leecher not removed from cache", foundLeecher, *testLeecher)
|
||||
}
|
||||
foundLeecher, found = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found || foundLeecher == *testLeecher {
|
||||
t.Error("leecher not removed from local", foundLeecher, *testLeecher)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.RemoveLeecher(testTorrent, testLeecher))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundLeecher, found := foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found || foundLeecher == *testLeecher {
|
||||
t.Error("leecher not removed from cache", foundLeecher, *testLeecher)
|
||||
}
|
||||
foundLeecher, found = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found || foundLeecher == *testLeecher {
|
||||
t.Error("leecher not removed from local", foundLeecher, *testLeecher)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestSetSeeder(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
testSeeder.Uploaded += uint64(r.Int63())
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
testSeeder.Uploaded += uint64(r.Int63())
|
||||
|
||||
panicOnErr(conn.SetSeeder(testTorrent, testSeeder))
|
||||
panicOnErr(conn.SetSeeder(testTorrent, testSeeder))
|
||||
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, _ := foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in cache", foundSeeder, *testSeeder)
|
||||
}
|
||||
foundSeeder, _ = testTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in local", foundSeeder, *testSeeder)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, _ := foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in cache", foundSeeder, *testSeeder)
|
||||
}
|
||||
foundSeeder, _ = testTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in local", foundSeeder, *testSeeder)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestSetLeecher(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
testLeecher.Uploaded += uint64(r.Int63())
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
testLeecher.Uploaded += uint64(r.Int63())
|
||||
|
||||
panicOnErr(conn.SetLeecher(testTorrent, testLeecher))
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundLeecher, _ := foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if foundLeecher != *testLeecher {
|
||||
t.Error("leecher not updated in cache", testLeecher)
|
||||
}
|
||||
foundLeecher, _ = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if foundLeecher != *testLeecher {
|
||||
t.Error("leecher not updated in local", testLeecher)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.SetLeecher(testTorrent, testLeecher))
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundLeecher, _ := foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if foundLeecher != *testLeecher {
|
||||
t.Error("leecher not updated in cache", testLeecher)
|
||||
}
|
||||
foundLeecher, _ = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if foundLeecher != *testLeecher {
|
||||
t.Error("leecher not updated in local", testLeecher)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestIncrementSlots(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
numSlots := testUser.Slots
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
numSlots := testUser.Slots
|
||||
|
||||
panicOnErr(conn.IncrementSlots(testUser))
|
||||
foundUser, _, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
panicOnErr(conn.IncrementSlots(testUser))
|
||||
foundUser, _, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
|
||||
if foundUser.Slots != numSlots+1 {
|
||||
t.Error("cached slots not incremented")
|
||||
}
|
||||
if testUser.Slots != numSlots+1 {
|
||||
t.Error("local slots not incremented")
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
if foundUser.Slots != numSlots+1 {
|
||||
t.Error("cached slots not incremented")
|
||||
}
|
||||
if testUser.Slots != numSlots+1 {
|
||||
t.Error("local slots not incremented")
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
}
|
||||
|
||||
func TestDecrementSlots(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
numSlots := testUser.Slots
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
numSlots := testUser.Slots
|
||||
|
||||
panicOnErr(conn.DecrementSlots(testUser))
|
||||
foundUser, _, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
panicOnErr(conn.DecrementSlots(testUser))
|
||||
foundUser, _, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
|
||||
if foundUser.Slots != numSlots-1 {
|
||||
t.Error("cached slots not incremented")
|
||||
}
|
||||
if testUser.Slots != numSlots-1 {
|
||||
t.Error("local slots not incremented")
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
if foundUser.Slots != numSlots-1 {
|
||||
t.Error("cached slots not incremented")
|
||||
}
|
||||
if testUser.Slots != numSlots-1 {
|
||||
t.Error("local slots not incremented")
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
}
|
||||
|
||||
func TestLeecherFinished(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
testLeecher.Left = 0
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
testLeecher.Left = 0
|
||||
|
||||
panicOnErr(conn.LeecherFinished(testTorrent, testLeecher))
|
||||
panicOnErr(conn.LeecherFinished(testTorrent, testLeecher))
|
||||
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, _ := foundTorrent.Seeders[storage.PeerMapKey(testLeecher)]
|
||||
if foundSeeder != *testLeecher {
|
||||
t.Error("seeder not added to cache", foundSeeder, *testLeecher)
|
||||
}
|
||||
foundSeeder, _ = foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if foundSeeder == *testLeecher {
|
||||
t.Error("leecher not removed from cache", testLeecher)
|
||||
}
|
||||
foundSeeder, _ = testTorrent.Seeders[storage.PeerMapKey(testLeecher)]
|
||||
if foundSeeder != *testLeecher {
|
||||
t.Error("seeder not added to local", testLeecher)
|
||||
}
|
||||
foundSeeder, _ = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if foundSeeder == *testLeecher {
|
||||
t.Error("leecher not removed from local", testLeecher)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, _ := foundTorrent.Seeders[storage.PeerMapKey(testLeecher)]
|
||||
if foundSeeder != *testLeecher {
|
||||
t.Error("seeder not added to cache", foundSeeder, *testLeecher)
|
||||
}
|
||||
foundSeeder, _ = foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if foundSeeder == *testLeecher {
|
||||
t.Error("leecher not removed from cache", testLeecher)
|
||||
}
|
||||
foundSeeder, _ = testTorrent.Seeders[storage.PeerMapKey(testLeecher)]
|
||||
if foundSeeder != *testLeecher {
|
||||
t.Error("seeder not added to local", testLeecher)
|
||||
}
|
||||
foundSeeder, _ = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if foundSeeder == *testLeecher {
|
||||
t.Error("leecher not removed from local", testLeecher)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
// Add, update, verify remove
|
||||
func TestUpdatePeer(t *testing.T) {
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
// Update a seeder, set it, then check to make sure it updated
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
testSeeder.Uploaded += uint64(r.Int63())
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
// Update a seeder, set it, then check to make sure it updated
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
testSeeder.Uploaded += uint64(r.Int63())
|
||||
|
||||
panicOnErr(conn.SetSeeder(testTorrent, testSeeder))
|
||||
panicOnErr(conn.SetSeeder(testTorrent, testSeeder))
|
||||
|
||||
panicOnErr(conn.RemoveSeeder(testTorrent, testSeeder))
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if seeder, exists := foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]; exists {
|
||||
t.Error("seeder not removed from cache", seeder)
|
||||
}
|
||||
if seeder, exists := testTorrent.Seeders[storage.PeerMapKey(testSeeder)]; exists {
|
||||
t.Error("seeder not removed from local", seeder)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.RemoveSeeder(testTorrent, testSeeder))
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if seeder, exists := foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]; exists {
|
||||
t.Error("seeder not removed from cache", seeder)
|
||||
}
|
||||
if seeder, exists := testTorrent.Seeders[storage.PeerMapKey(testSeeder)]; exists {
|
||||
t.Error("seeder not removed from local", seeder)
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestParallelFindUser(t *testing.T) {
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
conn := createTestConn()
|
||||
testUserSuccess := createTestUser()
|
||||
testUserFail := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUserSuccess))
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
conn := createTestConn()
|
||||
testUserSuccess := createTestUser()
|
||||
testUserFail := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUserSuccess))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
foundUser, found, err := conn.FindUser(testUserFail.Passkey)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("user found", foundUser)
|
||||
}
|
||||
foundUser, found, err = conn.FindUser(testUserSuccess.Passkey)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("user not found", testUserSuccess)
|
||||
}
|
||||
if *foundUser != *testUserSuccess {
|
||||
t.Error("found user mismatch", *foundUser, testUserSuccess)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveUser(testUserSuccess))
|
||||
for i := 0; i < 10; i++ {
|
||||
foundUser, found, err := conn.FindUser(testUserFail.Passkey)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("user found", foundUser)
|
||||
}
|
||||
foundUser, found, err = conn.FindUser(testUserSuccess.Passkey)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("user not found", testUserSuccess)
|
||||
}
|
||||
if *foundUser != *testUserSuccess {
|
||||
t.Error("found user mismatch", *foundUser, testUserSuccess)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveUser(testUserSuccess))
|
||||
}
|
||||
|
||||
func TestParallelFindTorrent(t *testing.T) {
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
conn := createTestConn()
|
||||
testTorrentSuccess := createTestTorrent()
|
||||
testTorrentFail := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrentSuccess))
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
conn := createTestConn()
|
||||
testTorrentSuccess := createTestTorrent()
|
||||
testTorrentFail := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrentSuccess))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrentSuccess.Infohash)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("torrent not found", testTorrentSuccess)
|
||||
}
|
||||
if !reflect.DeepEqual(foundTorrent, testTorrentSuccess) {
|
||||
t.Error("found torrent mismatch", foundTorrent, testTorrentSuccess)
|
||||
}
|
||||
foundTorrent, found, err = conn.FindTorrent(testTorrentFail.Infohash)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("torrent found", foundTorrent)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrentSuccess))
|
||||
for i := 0; i < 10; i++ {
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrentSuccess.Infohash)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
t.Error("torrent not found", testTorrentSuccess)
|
||||
}
|
||||
if !reflect.DeepEqual(foundTorrent, testTorrentSuccess) {
|
||||
t.Error("found torrent mismatch", foundTorrent, testTorrentSuccess)
|
||||
}
|
||||
foundTorrent, found, err = conn.FindTorrent(testTorrentFail.Infohash)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
t.Error("torrent found", foundTorrent)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrentSuccess))
|
||||
}
|
||||
|
||||
func TestParallelSetSeeder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
testSeeder.Uploaded += uint64(r.Int63())
|
||||
for i := 0; i < 10; i++ {
|
||||
testSeeder.Uploaded += uint64(r.Int63())
|
||||
|
||||
panicOnErr(conn.SetSeeder(testTorrent, testSeeder))
|
||||
panicOnErr(conn.SetSeeder(testTorrent, testSeeder))
|
||||
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, _ := foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in cache", foundSeeder, *testSeeder)
|
||||
}
|
||||
foundSeeder, _ = testTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in local", foundSeeder, *testSeeder)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
foundTorrent, _, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundSeeder, _ := foundTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in cache", foundSeeder, *testSeeder)
|
||||
}
|
||||
foundSeeder, _ = testTorrent.Seeders[storage.PeerMapKey(testSeeder)]
|
||||
if foundSeeder != *testSeeder {
|
||||
t.Error("seeder not updated in local", foundSeeder, *testSeeder)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
||||
func TestParallelAddLeecher(t *testing.T) {
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
t.Parallel()
|
||||
if testing.Short() {
|
||||
t.Skip()
|
||||
}
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
for i := 0; i < 10; i++ {
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundLeecher, found := foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to cache", testLeecher)
|
||||
}
|
||||
foundLeecher, found = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to local", testLeecher)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
foundLeecher, found := foundTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to cache", testLeecher)
|
||||
}
|
||||
foundLeecher, found = testTorrent.Leechers[storage.PeerMapKey(testLeecher)]
|
||||
if found && foundLeecher != *testLeecher {
|
||||
t.Error("leecher not added to local", testLeecher)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -5,284 +5,284 @@
|
|||
package redis
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
"math/rand"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func BenchmarkSuccessfulFindUser(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
|
||||
foundUser, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
b.Error("user not found", testUser)
|
||||
}
|
||||
if *foundUser != *testUser {
|
||||
b.Error("found user mismatch", *foundUser, testUser)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
b.StartTimer()
|
||||
foundUser, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
b.Error("user not found", testUser)
|
||||
}
|
||||
if *foundUser != *testUser {
|
||||
b.Error("found user mismatch", *foundUser, testUser)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
func BenchmarkFailedFindUser(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
|
||||
_, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
b.Error("user not found", testUser)
|
||||
}
|
||||
}
|
||||
_, found, err := conn.FindUser(testUser.Passkey)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
b.Error("user not found", testUser)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSuccessfulFindTorrent(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
b.Error("torrent not found", testTorrent)
|
||||
}
|
||||
// Incomplete comparison as maps make struct not nativly comparable
|
||||
if foundTorrent.Infohash != testTorrent.Infohash {
|
||||
b.Error("found torrent mismatch", foundTorrent, testTorrent)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
b.Error("torrent not found", testTorrent)
|
||||
}
|
||||
// Incomplete comparison as maps make struct not nativly comparable
|
||||
if foundTorrent.Infohash != testTorrent.Infohash {
|
||||
b.Error("found torrent mismatch", foundTorrent, testTorrent)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
func BenchmarkFailFindTorrent(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
b.Error("torrent found", foundTorrent)
|
||||
}
|
||||
}
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
foundTorrent, found, err := conn.FindTorrent(testTorrent.Infohash)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
b.Error("torrent found", foundTorrent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSuccessfulClientWhitelisted(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testPeerID := "-lt0D30-"
|
||||
panicOnErr(conn.WhitelistClient(testPeerID))
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testPeerID := "-lt0D30-"
|
||||
panicOnErr(conn.WhitelistClient(testPeerID))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
found, err := conn.ClientWhitelisted(testPeerID)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
b.Error("peerID not found", testPeerID)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.UnWhitelistClient(testPeerID))
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
found, err := conn.ClientWhitelisted(testPeerID)
|
||||
panicOnErr(err)
|
||||
if !found {
|
||||
b.Error("peerID not found", testPeerID)
|
||||
}
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.UnWhitelistClient(testPeerID))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
func BenchmarkFailClientWhitelisted(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testPeerID2 := "TIX0192"
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testPeerID2 := "TIX0192"
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
found, err := conn.ClientWhitelisted(testPeerID2)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
b.Error("peerID found", testPeerID2)
|
||||
}
|
||||
}
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
found, err := conn.ClientWhitelisted(testPeerID2)
|
||||
panicOnErr(err)
|
||||
if found {
|
||||
b.Error("peerID found", testPeerID2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkRecordSnatch(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
panicOnErr(conn.RecordSnatch(testUser, testTorrent))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
panicOnErr(conn.RecordSnatch(testUser, testTorrent))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
func BenchmarkMarkActive(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testTorrent.Active = false
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
testTorrent.Active = false
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
panicOnErr(conn.MarkActive(testTorrent))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
panicOnErr(conn.MarkActive(testTorrent))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
func BenchmarkAddSeeder(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
b.StartTimer()
|
||||
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
func BenchmarkRemoveSeeder(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
conn.AddSeeder(testTorrent, testSeeder)
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
conn.AddSeeder(testTorrent, testSeeder)
|
||||
b.StartTimer()
|
||||
|
||||
panicOnErr(conn.RemoveSeeder(testTorrent, testSeeder))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
panicOnErr(conn.RemoveSeeder(testTorrent, testSeeder))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
func BenchmarkSetSeeder(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
testSeeder := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testSeeder))
|
||||
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
testSeeder.Uploaded += uint64(r.Int63())
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
testSeeder.Uploaded += uint64(r.Int63())
|
||||
b.StartTimer()
|
||||
|
||||
conn.SetSeeder(testTorrent, testSeeder)
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
conn.SetSeeder(testTorrent, testSeeder)
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
func BenchmarkIncrementSlots(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testUser := createTestUser()
|
||||
panicOnErr(conn.AddUser(testUser))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
panicOnErr(conn.IncrementSlots(testUser))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
panicOnErr(conn.IncrementSlots(testUser))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveUser(testUser))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
func BenchmarkLeecherFinished(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
testLeecher.Left = 0
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
testLeecher.Left = 0
|
||||
b.StartTimer()
|
||||
|
||||
panicOnErr(conn.LeecherFinished(testTorrent, testLeecher))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
panicOnErr(conn.LeecherFinished(testTorrent, testLeecher))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
panicOnErr(conn.RemoveTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
}
|
||||
|
||||
// This is a comparision to the Leecher finished function
|
||||
func BenchmarkRemoveLeecherAddSeeder(b *testing.B) {
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
b.StopTimer()
|
||||
conn := createTestConn()
|
||||
testTorrent := createTestTorrent()
|
||||
panicOnErr(conn.AddTorrent(testTorrent))
|
||||
b.StartTimer()
|
||||
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
testLeecher.Left = 0
|
||||
b.StartTimer()
|
||||
for bCount := 0; bCount < b.N; bCount++ {
|
||||
b.StopTimer()
|
||||
testLeecher := createTestPeer(createTestUserID(), testTorrent.ID)
|
||||
panicOnErr(conn.AddLeecher(testTorrent, testLeecher))
|
||||
testLeecher.Left = 0
|
||||
b.StartTimer()
|
||||
|
||||
panicOnErr(conn.RemoveLeecher(testTorrent, testLeecher))
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testLeecher))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
conn.RemoveTorrent(testTorrent)
|
||||
b.StartTimer()
|
||||
panicOnErr(conn.RemoveLeecher(testTorrent, testLeecher))
|
||||
panicOnErr(conn.AddSeeder(testTorrent, testLeecher))
|
||||
}
|
||||
// Cleanup
|
||||
b.StopTimer()
|
||||
conn.RemoveTorrent(testTorrent)
|
||||
b.StartTimer()
|
||||
}
|
||||
|
|
|
@ -5,180 +5,180 @@
|
|||
package redis
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
"crypto/rand"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/garyburd/redigo/redis"
|
||||
"github.com/garyburd/redigo/redis"
|
||||
|
||||
"github.com/pushrax/chihaya/config"
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
"github.com/pushrax/chihaya/config"
|
||||
"github.com/pushrax/chihaya/storage"
|
||||
)
|
||||
|
||||
var (
|
||||
testTorrentIDChannel chan uint64
|
||||
testUserIDChannel chan uint64
|
||||
testPeerIDChannel chan 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
|
||||
}
|
||||
}()
|
||||
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 {
|
||||
return <-testTorrentIDChannel
|
||||
return <-testTorrentIDChannel
|
||||
}
|
||||
|
||||
func createTestUserID() uint64 {
|
||||
return <-testUserIDChannel
|
||||
return <-testUserIDChannel
|
||||
}
|
||||
|
||||
func createTestPeerID() string {
|
||||
return "-testPeerID-" + strconv.Itoa(<-testPeerIDChannel)
|
||||
return "-testPeerID-" + strconv.Itoa(<-testPeerIDChannel)
|
||||
}
|
||||
|
||||
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)
|
||||
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)
|
||||
uuid := make([]byte, 40)
|
||||
n, err := io.ReadFull(rand.Reader, uuid)
|
||||
if n != len(uuid) || err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return string(uuid)
|
||||
}
|
||||
|
||||
func panicOnErr(err error) {
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
panic(err)
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func createTestRedisConn() *Conn {
|
||||
testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH"))
|
||||
conf := &testConfig.Cache
|
||||
panicOnErr(err)
|
||||
testConfig, err := config.Open(os.Getenv("TESTCONFIGPATH"))
|
||||
conf := &testConfig.Cache
|
||||
panicOnErr(err)
|
||||
|
||||
testPool := &Pool{
|
||||
conf: conf,
|
||||
pool: redis.Pool{
|
||||
MaxIdle: conf.MaxIdleConns,
|
||||
IdleTimeout: conf.IdleTimeout.Duration,
|
||||
Dial: makeDialFunc(conf),
|
||||
TestOnBorrow: testOnBorrow,
|
||||
},
|
||||
}
|
||||
testPool := &Pool{
|
||||
conf: conf,
|
||||
pool: redis.Pool{
|
||||
MaxIdle: conf.MaxIdleConns,
|
||||
IdleTimeout: conf.IdleTimeout.Duration,
|
||||
Dial: makeDialFunc(conf),
|
||||
TestOnBorrow: testOnBorrow,
|
||||
},
|
||||
}
|
||||
|
||||
newConn := &Conn{
|
||||
conf: testPool.conf,
|
||||
done: false,
|
||||
Conn: testPool.pool.Get(),
|
||||
}
|
||||
panicOnErr(err)
|
||||
newConn := &Conn{
|
||||
conf: testPool.conf,
|
||||
done: false,
|
||||
Conn: testPool.pool.Get(),
|
||||
}
|
||||
panicOnErr(err)
|
||||
|
||||
// Test connection before returning
|
||||
_, err = newConn.Do("PING")
|
||||
panicOnErr(err)
|
||||
return newConn
|
||||
// Test connection before returning
|
||||
_, err = newConn.Do("PING")
|
||||
panicOnErr(err)
|
||||
return newConn
|
||||
}
|
||||
|
||||
func createTestUser() *storage.User {
|
||||
return &storage.User{ID: createTestUserID(), Passkey: createTestPasskey(),
|
||||
UpMultiplier: 1.01, DownMultiplier: 1.0, Slots: 4, SlotsUsed: 2, Snatches: 7}
|
||||
return &storage.User{ID: createTestUserID(), Passkey: createTestPasskey(),
|
||||
UpMultiplier: 1.01, DownMultiplier: 1.0, Slots: 4, SlotsUsed: 2, Snatches: 7}
|
||||
}
|
||||
|
||||
func createTestPeer(userID uint64, torrentID uint64) *storage.Peer {
|
||||
|
||||
return &storage.Peer{ID: createTestPeerID(), UserID: userID, TorrentID: torrentID,
|
||||
IP: "127.0.0.1", Port: 6889, Uploaded: 1024, Downloaded: 3000, Left: 4200, LastAnnounce: 11}
|
||||
return &storage.Peer{ID: createTestPeerID(), UserID: userID, TorrentID: torrentID,
|
||||
IP: "127.0.0.1", Port: 6889, Uploaded: 1024, Downloaded: 3000, Left: 4200, LastAnnounce: 11}
|
||||
}
|
||||
|
||||
func createTestPeers(torrentID uint64, num int) map[string]storage.Peer {
|
||||
testPeers := make(map[string]storage.Peer)
|
||||
for i := 0; i < num; i++ {
|
||||
tempPeer := createTestPeer(createTestUserID(), torrentID)
|
||||
testPeers[storage.PeerMapKey(tempPeer)] = *tempPeer
|
||||
}
|
||||
return testPeers
|
||||
testPeers := make(map[string]storage.Peer)
|
||||
for i := 0; i < num; i++ {
|
||||
tempPeer := createTestPeer(createTestUserID(), torrentID)
|
||||
testPeers[storage.PeerMapKey(tempPeer)] = *tempPeer
|
||||
}
|
||||
return testPeers
|
||||
}
|
||||
|
||||
func createTestTorrent() *storage.Torrent {
|
||||
|
||||
torrentInfohash := createTestInfohash()
|
||||
torrentID := createTestTorrentID()
|
||||
torrentInfohash := createTestInfohash()
|
||||
torrentID := createTestTorrentID()
|
||||
|
||||
testSeeders := createTestPeers(torrentID, 4)
|
||||
testLeechers := createTestPeers(torrentID, 2)
|
||||
testSeeders := createTestPeers(torrentID, 4)
|
||||
testLeechers := createTestPeers(torrentID, 2)
|
||||
|
||||
testTorrent := storage.Torrent{ID: torrentID, Infohash: torrentInfohash, Active: true,
|
||||
Seeders: testSeeders, Leechers: testLeechers, Snatches: 11, UpMultiplier: 1.0, DownMultiplier: 1.0, LastAction: 0}
|
||||
return &testTorrent
|
||||
testTorrent := storage.Torrent{ID: torrentID, Infohash: torrentInfohash, Active: true,
|
||||
Seeders: testSeeders, Leechers: testLeechers, Snatches: 11, UpMultiplier: 1.0, DownMultiplier: 1.0, LastAction: 0}
|
||||
return &testTorrent
|
||||
}
|
||||
|
||||
func TestValidPeers(t *testing.T) {
|
||||
testConn := createTestRedisConn()
|
||||
testTorrentID := createTestTorrentID()
|
||||
testPeers := createTestPeers(testTorrentID, 3)
|
||||
testConn := createTestRedisConn()
|
||||
testTorrentID := createTestTorrentID()
|
||||
testPeers := createTestPeers(testTorrentID, 3)
|
||||
|
||||
panicOnErr(testConn.addPeers(testPeers, "test:"))
|
||||
peerMap, err := testConn.getPeers(testTorrentID, "test:")
|
||||
panicOnErr(err)
|
||||
if len(peerMap) != len(testPeers) {
|
||||
t.Error("Num Peers not equal ", len(peerMap), len(testPeers))
|
||||
}
|
||||
panicOnErr(testConn.removePeers(testTorrentID, testPeers, "test:"))
|
||||
panicOnErr(testConn.addPeers(testPeers, "test:"))
|
||||
peerMap, err := testConn.getPeers(testTorrentID, "test:")
|
||||
panicOnErr(err)
|
||||
if len(peerMap) != len(testPeers) {
|
||||
t.Error("Num Peers not equal ", len(peerMap), len(testPeers))
|
||||
}
|
||||
panicOnErr(testConn.removePeers(testTorrentID, testPeers, "test:"))
|
||||
}
|
||||
|
||||
func TestInvalidPeers(t *testing.T) {
|
||||
testConn := createTestRedisConn()
|
||||
testTorrentID := createTestTorrentID()
|
||||
testPeers := createTestPeers(testTorrentID, 3)
|
||||
tempPeer := createTestPeer(createTestUserID(), testTorrentID)
|
||||
testPeers[storage.PeerMapKey(tempPeer)] = *tempPeer
|
||||
testConn := createTestRedisConn()
|
||||
testTorrentID := createTestTorrentID()
|
||||
testPeers := createTestPeers(testTorrentID, 3)
|
||||
tempPeer := createTestPeer(createTestUserID(), testTorrentID)
|
||||
testPeers[storage.PeerMapKey(tempPeer)] = *tempPeer
|
||||
|
||||
panicOnErr(testConn.addPeers(testPeers, "test:"))
|
||||
// Imitate a peer being removed during get
|
||||
hashKey := testConn.conf.Prefix + getPeerHashKey(tempPeer)
|
||||
_, err := testConn.Do("DEL", hashKey)
|
||||
panicOnErr(err)
|
||||
panicOnErr(testConn.addPeers(testPeers, "test:"))
|
||||
// Imitate a peer being removed during get
|
||||
hashKey := testConn.conf.Prefix + getPeerHashKey(tempPeer)
|
||||
_, err := testConn.Do("DEL", hashKey)
|
||||
panicOnErr(err)
|
||||
|
||||
peerMap, err := testConn.getPeers(testTorrentID, "test:")
|
||||
panicOnErr(err)
|
||||
// Expect 1 less peer due to delete
|
||||
if len(peerMap) != len(testPeers)-1 {
|
||||
t.Error("Num Peers not equal ", len(peerMap), len(testPeers)-1)
|
||||
}
|
||||
panicOnErr(testConn.removePeers(testTorrentID, testPeers, "test:"))
|
||||
if len(testPeers) != 0 {
|
||||
t.Errorf("All peers not removed, %d peers remain!", len(testPeers))
|
||||
}
|
||||
peerMap, err := testConn.getPeers(testTorrentID, "test:")
|
||||
panicOnErr(err)
|
||||
// Expect 1 less peer due to delete
|
||||
if len(peerMap) != len(testPeers)-1 {
|
||||
t.Error("Num Peers not equal ", len(peerMap), len(testPeers)-1)
|
||||
}
|
||||
panicOnErr(testConn.removePeers(testTorrentID, testPeers, "test:"))
|
||||
if len(testPeers) != 0 {
|
||||
t.Errorf("All peers not removed, %d peers remain!", len(testPeers))
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue