cmd: add e2e command

This change unifies chihaya and chihaya-e2e binaries.
It also vendors the code missing from the project that was used in
chihaya-e2e.

Fixes #402.
This commit is contained in:
Jimmy Zelinskie 2018-08-30 20:50:04 -04:00
parent 085234044a
commit 3aa7d1a91d
6 changed files with 163 additions and 124 deletions

View file

@ -1,6 +1,6 @@
language: go language: go
go: go:
- 1.9.x - 1.11.x
sudo: false sudo: false
matrix: matrix:
include: include:
@ -18,9 +18,8 @@ matrix:
- go install github.com/chihaya/chihaya/cmd/chihaya - go install github.com/chihaya/chihaya/cmd/chihaya
- chihaya --config=example_config.yaml --debug& - chihaya --config=example_config.yaml --debug&
- pid=$! - pid=$!
# we move the installation here so chihaya has enough time to start up - sleep 2 # wait for chihaya to start up (gross)
- go install github.com/chihaya/chihaya/cmd/chihaya-e2e - chihaya e2e --debug
- chihaya-e2e
- kill $pid - kill $pid
# Using HEAD of dependencies # Using HEAD of dependencies
- install: - install:
@ -35,9 +34,8 @@ matrix:
- go install github.com/chihaya/chihaya/cmd/chihaya - go install github.com/chihaya/chihaya/cmd/chihaya
- chihaya --config=example_config.yaml --debug& - chihaya --config=example_config.yaml --debug&
- pid=$! - pid=$!
# we move the installation here so chihaya has enough time to start up - sleep 2 # wait for chihaya to start up (gross)
- go install github.com/chihaya/chihaya/cmd/chihaya-e2e - chihaya e2e --debug
- chihaya-e2e
- kill $pid - kill $pid
allow_failures: allow_failures:
# Using HEAD of dependencies # Using HEAD of dependencies
@ -53,9 +51,8 @@ matrix:
- go install github.com/chihaya/chihaya/cmd/chihaya - go install github.com/chihaya/chihaya/cmd/chihaya
- chihaya --config=example_config.yaml --debug& - chihaya --config=example_config.yaml --debug&
- pid=$! - pid=$!
# we move the installation here so chihaya has enough time to start up - sleep 2 # wait for chihaya to start up (gross)
- go install github.com/chihaya/chihaya/cmd/chihaya-e2e - chihaya e2e --debug
- chihaya-e2e
- kill $pid - kill $pid
notifications: notifications:
irc: irc:

76
Gopkg.lock generated
View file

@ -12,33 +12,39 @@
revision = "f6df55f235c24f236d11dbcf665249a59ac2021f" revision = "f6df55f235c24f236d11dbcf665249a59ac2021f"
version = "1.1" version = "1.1"
[[projects]]
branch = "master"
name = "github.com/anacrolix/dht"
packages = ["krpc"]
revision = "cae37fd1842087605e61382e82e4f87fab27afdc"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/anacrolix/missinggo" name = "github.com/anacrolix/missinggo"
packages = [ packages = [
".", ".",
"assert", "expect",
"httptoo", "httptoo",
"mime", "mime",
"pproffd" "pproffd",
"slices"
] ]
revision = "173db517b5f8002d630f815e2097a1858c27f8ef" revision = "60ef2fbf63df5d871ada2680d4d8a6013dcd1745"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/anacrolix/torrent" name = "github.com/anacrolix/torrent"
packages = [ packages = [
"bencode", "bencode",
"tracker", "tracker"
"util"
] ]
revision = "64d13d86a6ba04269e2abacedcdd890165901010" revision = "4431464fd62c37843addc79822f7cd30b4467471"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/beorn7/perks" name = "github.com/beorn7/perks"
packages = ["quantile"] packages = ["quantile"]
revision = "4c0e84591b9aa9e6dcfdf3e020114cd81f89d5f9" revision = "3a771d992973f24aa725d07868b467d1ddfceafb"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -49,14 +55,20 @@
[[projects]] [[projects]]
name = "github.com/davecgh/go-spew" name = "github.com/davecgh/go-spew"
packages = ["spew"] packages = ["spew"]
revision = "346938d642f2ec3594ed81d874461961cd0faa76" revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73"
version = "v1.1.0" version = "v1.1.1"
[[projects]] [[projects]]
branch = "master"
name = "github.com/golang/protobuf" name = "github.com/golang/protobuf"
packages = ["proto"] packages = ["proto"]
revision = "1e59b77b52bf8e4b449a57e6f79f21226d571845" revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5"
version = "v1.2.0"
[[projects]]
name = "github.com/huandu/xstrings"
packages = ["."]
revision = "55ae428c2ac4f74d7430952ef528631e656ac92c"
version = "v1.1.0"
[[projects]] [[projects]]
name = "github.com/inconshreveable/mousetrap" name = "github.com/inconshreveable/mousetrap"
@ -73,8 +85,8 @@
[[projects]] [[projects]]
name = "github.com/matttproud/golang_protobuf_extensions" name = "github.com/matttproud/golang_protobuf_extensions"
packages = ["pbutil"] packages = ["pbutil"]
revision = "3247c84500bff8d9fb6d579d800f20b3e091582c" revision = "c12348ce28de40eed0136aa2b644d0ee0650e56c"
version = "v1.0.0" version = "v1.0.1"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -89,10 +101,10 @@
revision = "ad98a36ba0da87206e3378c556abbfeaeaa98668" revision = "ad98a36ba0da87206e3378c556abbfeaeaa98668"
[[projects]] [[projects]]
branch = "master"
name = "github.com/pkg/errors" name = "github.com/pkg/errors"
packages = ["."] packages = ["."]
revision = "30136e27e2ac8d167177e8a583aa4c3fea5be833" revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
version = "v0.8.0"
[[projects]] [[projects]]
name = "github.com/pmezard/go-difflib" name = "github.com/pmezard/go-difflib"
@ -110,7 +122,7 @@
branch = "master" branch = "master"
name = "github.com/prometheus/client_model" name = "github.com/prometheus/client_model"
packages = ["go"] packages = ["go"]
revision = "99fa1f4be8e564e8a6b613da7fa6f46c9edafc6c" revision = "5c3871d89910bfb32f5fcab2aa4b9ec68e65a99f"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -120,34 +132,36 @@
"internal/bitbucket.org/ww/goautoneg", "internal/bitbucket.org/ww/goautoneg",
"model" "model"
] ]
revision = "2e54d0b93cba2fd133edc32211dcc32c06ef72ca" revision = "c7de2306084e37d54b8be01f3541a8464345e9a5"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "github.com/prometheus/procfs" name = "github.com/prometheus/procfs"
packages = [ packages = [
".", ".",
"internal/util",
"nfs",
"xfs" "xfs"
] ]
revision = "8f918ac9ab4be3a790338bda8624fec5d71260b3" revision = "05ee40e3a273f7245e8777337fc7b46e533a9a92"
[[projects]] [[projects]]
name = "github.com/sirupsen/logrus" name = "github.com/sirupsen/logrus"
packages = ["."] packages = ["."]
revision = "d682213848ed68c0a260ca37d6dd5ace8423f5ba" revision = "3e01752db0189b9157070a0e1668a620f9a85da2"
version = "v1.0.4" version = "v1.0.6"
[[projects]] [[projects]]
name = "github.com/spf13/cobra" name = "github.com/spf13/cobra"
packages = ["."] packages = ["."]
revision = "7b2c5ac9fc04fc5efafb60700713d4fa609b777b" revision = "ef82de70bb3f60c65fb8eebacbb2d122ef517385"
version = "v0.0.1" version = "v0.0.3"
[[projects]] [[projects]]
name = "github.com/spf13/pflag" name = "github.com/spf13/pflag"
packages = ["."] packages = ["."]
revision = "e57e3eeb33f795204c1ca35f56c44f83227c6e66" revision = "9a97c102cda95a86cec2345a6f09f55a939babf5"
version = "v1.0.0" version = "v1.0.2"
[[projects]] [[projects]]
name = "github.com/stretchr/testify" name = "github.com/stretchr/testify"
@ -155,14 +169,14 @@
"assert", "assert",
"require" "require"
] ]
revision = "69483b4bd14f5845b5a1e55bca19e954e827f1d0" revision = "f35b8ab0b5a2cef36673838d662e249dd9c94686"
version = "v1.1.4" version = "v1.2.2"
[[projects]] [[projects]]
branch = "master" branch = "master"
name = "golang.org/x/crypto" name = "golang.org/x/crypto"
packages = ["ssh/terminal"] packages = ["ssh/terminal"]
revision = "d585fd2cc9195196078f516b69daff6744ef5e84" revision = "182538f80094b6a8efaade63a8fd8e0d9d5843dd"
[[projects]] [[projects]]
branch = "master" branch = "master"
@ -171,17 +185,17 @@
"unix", "unix",
"windows" "windows"
] ]
revision = "83801418e1b59fb1880e363299581ee543af32ca" revision = "49385e6e15226593f68b26af201feec29d5bba22"
[[projects]] [[projects]]
branch = "v2"
name = "gopkg.in/yaml.v2" name = "gopkg.in/yaml.v2"
packages = ["."] packages = ["."]
revision = "287cf08546ab5e7e37d55a84f7ed3fd1db036de5" revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
version = "v2.2.1"
[solve-meta] [solve-meta]
analyzer-name = "dep" analyzer-name = "dep"
analyzer-version = 1 analyzer-version = 1
inputs-digest = "70d8adf87b226f38ffea02e5edd2a0adb03b5e1a567eb2ed74ab9d480b9fd68c" inputs-digest = "073ea42bedc8b51977e04bb4e86deb764315fa1b904e1da4cf48e2247a056caf"
solver-name = "gps-cdcl" solver-name = "gps-cdcl"
solver-version = 1 solver-version = 1

View file

@ -1,7 +1,6 @@
# Gopkg.toml example # Gopkg.toml example
# #
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md # Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation. # for detailed Gopkg.toml documentation.
# #
# required = ["github.com/user/thing/cmd/thing"] # required = ["github.com/user/thing/cmd/thing"]
@ -17,14 +16,23 @@
# source = "github.com/myfork/project2" # source = "github.com/myfork/project2"
# #
# [[override]] # [[override]]
# name = "github.com/x/y" # name = "github.com/x/y"
# version = "2.4.0" # version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true
[[constraint]] [[constraint]]
name = "github.com/SermoDigital/jose" name = "github.com/SermoDigital/jose"
version = "1.1.0" version = "1.1.0"
[[constraint]]
branch = "master"
name = "github.com/anacrolix/torrent"
[[constraint]] [[constraint]]
name = "github.com/julienschmidt/httprouter" name = "github.com/julienschmidt/httprouter"
version = "1.1.0" version = "1.1.0"
@ -37,30 +45,30 @@
branch = "master" branch = "master"
name = "github.com/minio/sha256-simd" name = "github.com/minio/sha256-simd"
[[constraint]]
name = "github.com/pkg/errors"
version = "0.8.0"
[[constraint]] [[constraint]]
name = "github.com/prometheus/client_golang" name = "github.com/prometheus/client_golang"
version = "0.8.0" version = "0.8.0"
[[constraint]] [[constraint]]
name = "github.com/sirupsen/logrus" name = "github.com/sirupsen/logrus"
version = "1.0.4" version = "1.0.6"
[[constraint]] [[constraint]]
name = "github.com/spf13/cobra" name = "github.com/spf13/cobra"
version = "0.0.1" version = "0.0.3"
[[constraint]] [[constraint]]
name = "github.com/stretchr/testify" name = "github.com/stretchr/testify"
version = "1.1.4" version = "1.2.2"
[[constraint]] [[constraint]]
branch = "v2"
name = "gopkg.in/yaml.v2" name = "gopkg.in/yaml.v2"
version = "2.2.1"
[[constraint]] [prune]
name = "github.com/pkg/errors" go-tests = true
branch = "master" unused-packages = true
[[constraint]]
name = "github.com/anacrolix/torrent"
branch = "master"

View file

@ -1,5 +0,0 @@
# chihaya-e2e
A very simple tool to black-box test a bittorrent tracker.
This tool uses [github.com/anacrolix/torrent/tracker](github.com/anacrolix/torrent/tracker) to make a UDP and an HTTP announce to given trackers.
It is used by chihaya for end-to-end testing the tracker during CI.

View file

@ -2,52 +2,57 @@ package main
import ( import (
"crypto/rand" "crypto/rand"
"flag"
"fmt" "fmt"
"net/http" "net/http"
"os"
"time" "time"
"github.com/anacrolix/torrent/tracker" "github.com/anacrolix/torrent/tracker"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/spf13/cobra"
"github.com/chihaya/chihaya/bittorrent" "github.com/chihaya/chihaya/bittorrent"
"github.com/chihaya/chihaya/pkg/log"
) )
func init() { // EndToEndRunCmdFunc implements a Cobra command that runs the end-to-end test
flag.StringVar(&httpTrackerURL, "http", "http://127.0.0.1:6969/announce", "the address of the HTTP tracker") // suite for a Chihaya build.
flag.StringVar(&udpTrackerURL, "udp", "udp://127.0.0.1:6969", "the address of the UDP tracker") func EndToEndRunCmdFunc(cmd *cobra.Command, args []string) error {
flag.DurationVar(&delay, "delay", 1*time.Second, "the delay between announces") delay, err := cmd.Flags().GetDuration("delay")
} if err != nil {
return err
var (
httpTrackerURL string
udpTrackerURL string
delay time.Duration
)
func main() {
flag.Parse()
if len(httpTrackerURL) != 0 {
fmt.Println("testing HTTP...")
err := testHTTP()
if err != nil {
fmt.Println("failed:", err)
os.Exit(1)
}
fmt.Println("success")
} }
if len(udpTrackerURL) != 0 { // Test the HTTP tracker
fmt.Println("testing UDP...") httpAddr, err := cmd.Flags().GetString("httpaddr")
err := testUDP() if err != nil {
if err != nil { return err
fmt.Println("failed:", err)
os.Exit(1)
}
fmt.Println("success")
} }
if len(httpAddr) != 0 {
log.Info("testing HTTP...")
err := test(httpAddr, delay)
if err != nil {
return err
}
log.Info("success")
}
// Test the UDP tracker.
udpAddr, err := cmd.Flags().GetString("udpaddr")
if err != nil {
return err
}
if len(udpAddr) != 0 {
log.Info("testing UDP...")
err := test(udpAddr, delay)
if err != nil {
return err
}
log.Info("success")
}
return nil
} }
func generateInfohash() [20]byte { func generateInfohash() [20]byte {
@ -64,17 +69,12 @@ func generateInfohash() [20]byte {
return [20]byte(bittorrent.InfoHashFromBytes(b)) return [20]byte(bittorrent.InfoHashFromBytes(b))
} }
func testUDP() error { func test(addr string, delay time.Duration) error {
ih := generateInfohash() ih := generateInfohash()
return testWithInfohash(ih, udpTrackerURL) return testWithInfohash(ih, addr, delay)
} }
func testHTTP() error { func testWithInfohash(infoHash [20]byte, url string, delay time.Duration) error {
ih := generateInfohash()
return testWithInfohash(ih, httpTrackerURL)
}
func testWithInfohash(infoHash [20]byte, url string) error {
req := tracker.AnnounceRequest{ req := tracker.AnnounceRequest{
InfoHash: infoHash, InfoHash: infoHash,
PeerId: [20]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}, PeerId: [20]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20},
@ -82,12 +82,17 @@ func testWithInfohash(infoHash [20]byte, url string) error {
Left: 100, Left: 100,
Uploaded: 50, Uploaded: 50,
Event: tracker.Started, Event: tracker.Started,
IPAddress: int32(50<<24 | 10<<16 | 12<<8 | 1), IPAddress: uint32(50<<24 | 10<<16 | 12<<8 | 1),
NumWant: 50, NumWant: 50,
Port: 10001, Port: 10001,
} }
resp, err := tracker.Announce(&http.Client{}, "ekop", url, &req) resp, err := tracker.Announce{
TrackerUrl: url,
Request: req,
UserAgent: "chihaya-e2e",
HttpClient: &http.Client{},
}.Do()
if err != nil { if err != nil {
return errors.Wrap(err, "announce failed") return errors.Wrap(err, "announce failed")
} }
@ -105,12 +110,17 @@ func testWithInfohash(infoHash [20]byte, url string) error {
Left: 100, Left: 100,
Uploaded: 50, Uploaded: 50,
Event: tracker.Started, Event: tracker.Started,
IPAddress: int32(50<<24 | 10<<16 | 12<<8 | 2), IPAddress: uint32(50<<24 | 10<<16 | 12<<8 | 2),
NumWant: 50, NumWant: 50,
Port: 10002, Port: 10002,
} }
resp, err = tracker.Announce(&http.Client{}, "ekop", url, &req) resp, err = tracker.Announce{
TrackerUrl: url,
Request: req,
UserAgent: "chihaya-e2e",
HttpClient: &http.Client{},
}.Do()
if err != nil { if err != nil {
return errors.Wrap(err, "announce failed") return errors.Wrap(err, "announce failed")
} }

View file

@ -9,6 +9,7 @@ import (
"runtime/trace" "runtime/trace"
"strings" "strings"
"syscall" "syscall"
"time"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -132,9 +133,9 @@ func (r *Run) Stop(keepPeerStore bool) (storage.PeerStore, error) {
return r.peerStore, nil return r.peerStore, nil
} }
// RunCmdFunc implements a Cobra command that runs an instance of Chihaya and // RootRunCmdFunc implements a Cobra command that runs an instance of Chihaya
// handles reloading and shutdown via process signals. // and handles reloading and shutdown via process signals.
func RunCmdFunc(cmd *cobra.Command, args []string) error { func RootRunCmdFunc(cmd *cobra.Command, args []string) error {
configFilePath, err := cmd.Flags().GetString("config") configFilePath, err := cmd.Flags().GetString("config")
if err != nil { if err != nil {
return err return err
@ -173,8 +174,8 @@ func RunCmdFunc(cmd *cobra.Command, args []string) error {
} }
} }
// PreRunCmdFunc handles command line flags for the Run command. // RootPreRunCmdFunc handles command line flags for the Run command.
func PreRunCmdFunc(cmd *cobra.Command, args []string) error { func RootPreRunCmdFunc(cmd *cobra.Command, args []string) error {
noColors, err := cmd.Flags().GetBool("nocolors") noColors, err := cmd.Flags().GetBool("nocolors")
if err != nil { if err != nil {
return err return err
@ -230,9 +231,9 @@ func PreRunCmdFunc(cmd *cobra.Command, args []string) error {
return nil return nil
} }
// PostRunCmdFunc handles clean up of any state initialized by command line // RootPostRunCmdFunc handles clean up of any state initialized by command line
// flags. // flags.
func PostRunCmdFunc(cmd *cobra.Command, args []string) error { func RootPostRunCmdFunc(cmd *cobra.Command, args []string) error {
// These can be called regardless because it noops when not profiling. // These can be called regardless because it noops when not profiling.
pprof.StopCPUProfile() pprof.StopCPUProfile()
trace.Stop() trace.Stop()
@ -245,22 +246,36 @@ func main() {
Use: "chihaya", Use: "chihaya",
Short: "BitTorrent Tracker", Short: "BitTorrent Tracker",
Long: "A customizable, multi-protocol BitTorrent Tracker", Long: "A customizable, multi-protocol BitTorrent Tracker",
PersistentPreRunE: PreRunCmdFunc, PersistentPreRunE: RootPreRunCmdFunc,
RunE: RunCmdFunc, RunE: RootRunCmdFunc,
PersistentPostRunE: PostRunCmdFunc, PersistentPostRunE: RootPostRunCmdFunc,
}
rootCmd.PersistentFlags().String("cpuprofile", "", "location to save a CPU profile")
rootCmd.PersistentFlags().String("trace", "", "location to save a trace")
rootCmd.PersistentFlags().Bool("debug", false, "enable debug logging")
rootCmd.PersistentFlags().Bool("json", false, "enable json logging")
if runtime.GOOS == "windows" {
rootCmd.PersistentFlags().Bool("nocolors", true, "disable log coloring")
} else {
rootCmd.PersistentFlags().Bool("nocolors", false, "disable log coloring")
} }
rootCmd.Flags().String("config", "/etc/chihaya.yaml", "location of configuration file") rootCmd.Flags().String("config", "/etc/chihaya.yaml", "location of configuration file")
rootCmd.Flags().String("cpuprofile", "", "location to save a CPU profile")
rootCmd.Flags().String("trace", "", "location to save a trace") var e2eCmd = &cobra.Command{
rootCmd.Flags().Bool("debug", false, "enable debug logging") Use: "e2e",
rootCmd.Flags().Bool("json", false, "enable json logging") Short: "exec e2e tests",
if runtime.GOOS == "windows" { Long: "Execute the Chihaya end-to-end test suite",
rootCmd.Flags().Bool("nocolors", true, "disable log coloring") RunE: EndToEndRunCmdFunc,
} else {
rootCmd.Flags().Bool("nocolors", false, "disable log coloring")
} }
e2eCmd.Flags().String("httpaddr", "http://127.0.0.1:6969/announce", "address of the HTTP tracker")
e2eCmd.Flags().String("udpaddr", "udp://127.0.0.1:6969", "address of the UDP tracker")
e2eCmd.Flags().Duration("delay", time.Second, "delay between announces")
rootCmd.AddCommand(e2eCmd)
if err := rootCmd.Execute(); err != nil { if err := rootCmd.Execute(); err != nil {
log.Fatal("failed when executing root cobra command: " + err.Error()) log.Fatal("failed when executing root cobra command: " + err.Error())
} }