func TestTorrentPurging(t *testing.T) { tkr, err := tracker.New(&config.DefaultConfig) if err != nil { t.Fatalf("failed to create new tracker instance: %s", err) } srv, err := setupTracker(nil, tkr) if err != nil { t.Fatal(err) } defer srv.Close() // Add one seeder. peer := makePeerParams("peer1", true) announce(peer, srv) // Make sure the torrent was created. _, err = tkr.FindTorrent(infoHash) if err != nil { t.Fatalf("expected torrent to exist after announce: %s", err) } // Remove seeder. peer = makePeerParams("peer1", true) peer["event"] = "stopped" announce(peer, srv) _, err = tkr.FindTorrent(infoHash) if err != models.ErrTorrentDNE { t.Fatalf("expected torrent to have been purged: %s", err) } }
func setupTracker(cfg *config.Config, tkr *tracker.Tracker) (*httptest.Server, error) { if cfg == nil { cfg = &config.DefaultConfig } if tkr == nil { var err error tkr, err = tracker.New(cfg) if err != nil { return nil, err } } return createServer(tkr, cfg) }
func TestStalePeerPurging(t *testing.T) { cfg := config.DefaultConfig cfg.MinAnnounce = config.Duration{10 * time.Millisecond} cfg.ReapInterval = config.Duration{10 * time.Millisecond} tkr, err := tracker.New(&cfg) if err != nil { t.Fatalf("failed to create new tracker instance: %s", err) } srv, err := setupTracker(&cfg, tkr) if err != nil { t.Fatal(err) } defer srv.Close() // Add one seeder. peer1 := makePeerParams("peer1", true) announce(peer1, srv) // Make sure the torrent was created. _, err = tkr.FindTorrent(infoHash) if err != nil { t.Fatalf("expected torrent to exist after announce: %s", err) } // Add a leecher. peer2 := makePeerParams("peer2", false) expected := makeResponse(1, 1, peer1) expected["min interval"] = int64(0) checkAnnounce(peer2, expected, srv, t) // Let them both expire. time.Sleep(30 * time.Millisecond) _, err = tkr.FindTorrent(infoHash) if err != models.ErrTorrentDNE { t.Fatalf("expected torrent to have been purged: %s", err) } }
func TestPrivateAnnounce(t *testing.T) { cfg := config.DefaultConfig cfg.PrivateEnabled = true tkr, err := tracker.New(&cfg) if err != nil { t.Fatal(err) } loadPrivateTestData(tkr) srv, err := createServer(tkr, &cfg) if err != nil { t.Fatal(err) } defer srv.Close() baseURL := srv.URL peer1 := makePeerParams("-TR2820-peer1", false) peer2 := makePeerParams("-TR2820-peer2", false) peer3 := makePeerParams("-TR2820-peer3", true) expected := makeResponse(0, 1, peer1) srv.URL = baseURL + "/users/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv1" checkAnnounce(peer1, expected, srv, t) expected = makeResponse(0, 2, peer1) srv.URL = baseURL + "/users/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv2" checkAnnounce(peer2, expected, srv, t) expected = makeResponse(1, 2, peer1, peer2) srv.URL = baseURL + "/users/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv3" checkAnnounce(peer3, expected, srv, t) expected = makeResponse(1, 2, peer2, peer3) srv.URL = baseURL + "/users/vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv1" checkAnnounce(peer1, expected, srv, t) }
// Boot starts Chihaya. By exporting this function, anyone can import their own // custom drivers into their own package main and then call chihaya.Boot. func Boot() { defer glog.Flush() flag.Parse() runtime.GOMAXPROCS(maxProcs) glog.V(1).Info("Set max threads to ", maxProcs) debugBoot() defer debugShutdown() cfg, err := config.Open(configPath) if err != nil { glog.Fatalf("Failed to parse configuration file: %s\n", err) } if cfg == &config.DefaultConfig { glog.V(1).Info("Using default config") } else { glog.V(1).Infof("Loaded config file: %s", configPath) } stats.DefaultStats = stats.New(cfg.StatsConfig) tkr, err := tracker.New(cfg) if err != nil { glog.Fatal("New: ", err) } var servers []server if cfg.APIConfig.ListenAddr != "" { servers = append(servers, api.NewServer(cfg, tkr)) } servers = append(servers, http.NewServer(cfg, tkr)) var wg sync.WaitGroup for _, srv := range servers { wg.Add(1) // If you don't explicitly pass the server, every goroutine captures the // last server in the list. go func(srv server) { for { err := srv.Setup() if err == nil { defer wg.Done() srv.Serve() } else { glog.Error("Setup: ", err) time.Sleep(time.Second) } } }(srv) } shutdown := make(chan os.Signal) signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM) go func() { wg.Wait() signal.Stop(shutdown) close(shutdown) }() <-shutdown glog.Info("Shutting down...") for _, srv := range servers { srv.Stop() } <-shutdown if err := tkr.Close(); err != nil { glog.Errorf("Failed to shut down tracker cleanly: %s", err.Error()) } }