Add load tester

* Add Connection: close header to RPC
* Add load tester
This commit is contained in:
Lee Bousfield 2018-01-24 22:15:08 -07:00 committed by androm3da
commit f13c3e9907
11 changed files with 1518 additions and 3 deletions

3
.gitignore vendored
View file

@ -18,6 +18,9 @@
# Doxygen built HTML
/doc-build
# Rust generated files
/load-tester/target
# Executables
*.exe
*.out

View file

@ -33,7 +33,7 @@ compiler:
before_install:
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then sudo mkdir -p /etc/docker && echo '{"ipv6":true,"fixed-cidr-v6":"2001:db8:1::/64"}' | sudo tee /etc/docker/daemon.json && sudo service docker restart; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update && brew install qt5 && brew cask install xquartz && brew upgrade boost; fi
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update && brew install qt5 && brew cask install xquartz && brew upgrade boost && brew install rust; fi
- if [ "$TRAVIS_OS_NAME" = "linux" ]; then docker pull lukealonso/raiblocks-ci:latest; fi
script:

View file

@ -47,4 +47,16 @@ if [[ "$OSTYPE" == "darwin"* ]]; then
else
TRUE_CMD=true
fi
if ! cargo --version &>/dev/null; then
# We'll update the docker image once this PR gets merged.
# If you're reading this comment on master, contact @PlasmaPower
apt-get update && apt-get install -yq cargo
fi
pushd load-tester
cargo build --release
popd
cp ./load-tester/target/release/raiblocks-load-tester ./build/load_test
./ci/test.sh ./build || ${TRUE_CMD}

View file

@ -47,9 +47,13 @@ run_tests() {
xvfb_run_ ./qt_test
qt_test_res=${?}
./load_test ./rai_node
load_test_res=${?}
echo "Core Test return code: ${core_test_res}"
echo "QT Test return code: ${qt_test_res}"
return $((${core_test_res} + ${qt_test_res}))
echo "Load Test return code: ${qt_test_res}"
return $((${core_test_res} + ${qt_test_res} + ${load_test_res}))
}
cd ${build_dir}

View file

@ -26,6 +26,7 @@ ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get install -yq \
qt5-default \
valgrind \
xorg xvfb xauth xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic
xorg xvfb xauth xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic \
cargo
RUN rm -rf /tmp/*

724
load-tester/Cargo.lock generated Normal file
View file

@ -0,0 +1,724 @@
[[package]]
name = "ansi_term"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "atty"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "backtrace"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "backtrace-sys"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "base64"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "clap"
version = "2.29.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
"atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dtoa"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "error-chain"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fuchsia-zircon-sys"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "futures-cpupool"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "httparse"
version = "1.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hyper"
version = "0.11.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "iovec"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "kernel32-sys"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "language-tags"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazycell"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.2.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "log"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mime"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio"
version = "0.6.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-named-pipes"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio-uds"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miow"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"socket2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "net2"
version = "0.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
version = "0.1.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "num_cpus"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "percent-encoding"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "quote"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "raiblocks-load-tester"
version = "0.1.0"
dependencies = [
"clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-process 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "redox_syscall"
version = "0.1.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "relay"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-demangle"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "safemem"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "scoped-tls"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive_internals"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "slab"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "slab"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "socket2"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "strsim"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "syn"
version = "0.11.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synom"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "take"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "termion"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "textwrap"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-core"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-io"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-process"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-signal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-proto"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)",
"slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-service"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tokio-signal"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicase"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-width"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicode-xid"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "vec_map"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "version_check"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "ws2_32-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
"checksum atty 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "8352656fd42c30a0c3c89d26dea01e3b77c0ab2af18230835c15e2e13cd51859"
"checksum backtrace 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "ebbbf59b1c43eefa8c3ede390fcc36820b4999f7914104015be25025e0d62af2"
"checksum backtrace-sys 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "44585761d6161b0f57afc49482ab6bd067e4edef48c12a152c237eb0203f7661"
"checksum base64 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "229d032f1a99302697f10b27167ae6d03d49d032e6a8e2550e8d3fc13356d2b4"
"checksum bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b3c30d3802dfb7281680d6285f2ccdaa8c2d8fee41f93805dba5c4cf50dc23cf"
"checksum byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "652805b7e73fada9d85e9a6682a4abd490cb52d96aeecc12e33a0de34dfd0d23"
"checksum bytes 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1b7db437d718977f6dc9b2e3fd6fc343c02ac6b899b73fdd2179163447bd9ce9"
"checksum cc 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "deaf9ec656256bb25b404c51ef50097207b9cbb29c933d31f92cae5a8a0ffee0"
"checksum cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c819a1287eb618df47cc647173c5c4c66ba19d888a6e50d605672aed3140de"
"checksum clap 2.29.2 (registry+https://github.com/rust-lang/crates.io-index)" = "4151c5790817c7d21bbdc6c3530811f798172915f93258244948b93ba19604a6"
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ff511d5dc435d703f4971bc399647c9bc38e20cb41452e3b9feb4765419ed3f3"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
"checksum futures 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "118b49cac82e04121117cbd3121ede3147e885627d82c4546b87c702debb90c1"
"checksum futures-cpupool 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "ab90cde24b3319636588d0c35fe03b1333857621051837ed769faefb4c2162e4"
"checksum httparse 1.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f407128745b78abc95c0ffbe4e5d37427fdc0d45470710cfef8c44522a2e37"
"checksum hyper 0.11.15 (registry+https://github.com/rust-lang/crates.io-index)" = "4d6105c5eeb03068b10ff34475a0d166964f98e7b9777cc34b342a225af9b87c"
"checksum iovec 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b6e8b9c2247fcf6c6a1151f1156932be5606c9fd6f55a2d7f9fc1cb29386b2f7"
"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a91d884b6667cd606bb5a69aa0c99ba811a115fc68915e7056ec08a46e93199a"
"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
"checksum libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)" = "1e5d97d6708edaa407429faa671b942dc0f2727222fb6b6539bf1db936e4b121"
"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
"checksum log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "89f010e843f2b1a31dbd316b3b8d443758bc634bed37aabade59c686d644e0a2"
"checksum mime 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e2e00e17be181010a91dbfefb01660b17311059dc8c7f48b9017677721e732bd"
"checksum mio 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "75f72a93f046f1517e3cfddc0a096eb756a2ba727d36edc8227dee769a50a9b0"
"checksum mio-named-pipes 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "f5e374eff525ce1c5b7687c4cef63943e7686524a387933ad27ca7ec43779cb3"
"checksum mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1731a873077147b626d89cc6c2a0db6288d607496c5d10c0cfcf3adc697ec673"
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9224c91f82b3c47cf53dcf78dfaa20d6888fbcc5d272d5f2fcdf8a697f3c987d"
"checksum net2 0.2.31 (registry+https://github.com/rust-lang/crates.io-index)" = "3a80f842784ef6c9a958b68b7516bc7e35883c614004dd94959a4dca1b716c09"
"checksum num-traits 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)" = "9936036cc70fe4a8b2d338ab665900323290efb03983c86cbe235ae800ad8017"
"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum rand 0.3.20 (registry+https://github.com/rust-lang/crates.io-index)" = "512870020642bb8c221bf68baa1b2573da814f6ccfe5c9699b1c303047abe9b1"
"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
"checksum redox_syscall 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "0d92eecebad22b767915e4d529f89f28ee96dbbf5a4810d2b844373f136417fd"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum relay 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f301bafeb60867c85170031bdb2fcf24c8041f33aee09e7b116a58d4e9f781c5"
"checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
"checksum serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "db99f3919e20faa51bb2996057f5031d8685019b5a06139b1ce761da671b8526"
"checksum serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)" = "f4ba7591cfe93755e89eeecdbcc668885624829b020050e6aec99c2a03bd3fd0"
"checksum serde_derive_internals 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e03f1c9530c3fb0a0a5c9b826bdd9246a5921ae995d75f512ac917fc4dd55b5"
"checksum serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "c9db7266c7d63a4c4b7fe8719656ccdd51acf1bed6124b174f933b009fb10bcb"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum slab 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fdeff4cd9ecff59ec7e3744cbca73dfe5ac35c2aedb2cfba8a1c715a18912e9d"
"checksum smallvec 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4c8cbcd6df1e117c2210e13ab5109635ad68a929fcbb8964dc965b76cb5ee013"
"checksum socket2 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a76b792959eba82f021c9028c8ecb6396f085268d6d46af2ed96a829cc758d7c"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
"checksum take 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b157868d8ac1f56b64604539990685fa7611d8fa9e5476cf0c02cf34d32917c5"
"checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
"checksum time 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "a15375f1df02096fb3317256ce2cee6a1f42fc84ea5ad5fc8c421cfe40c73098"
"checksum tokio-core 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "52b4e32d8edbf29501aabb3570f027c6ceb00ccef6538f4bddba0200503e74e8"
"checksum tokio-io 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "514aae203178929dbf03318ad7c683126672d4d96eccb77b29603d33c9e25743"
"checksum tokio-process 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2e76e0cd21a4ae5362697e85f98aa5d26c88f09ce9fc367b57c0643ba0b022c2"
"checksum tokio-proto 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8fbb47ae81353c63c487030659494b295f6cb6576242f907f203473b191b0389"
"checksum tokio-service 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "24da22d077e0f15f55162bdbdc661228c1581892f52074fb242678d015b45162"
"checksum tokio-signal 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57c4031b97651d28c87a0a071e1c2809d70609d3120ce285b302eb7d52c96906"
"checksum unicase 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "284b6d3db520d67fbe88fd778c21510d1b0ba4a551e5d0fbb023d33405f6de8a"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"
"checksum unicode-xid 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f860d7d29cf02cb2f3f359fd35991af3d30bac52c57d265a3c461074cb4dc"
"checksum vec_map 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887b5b631c2ad01628bbbaa7dd4c869f80d3186688f8d0b6f58774fbe324988c"
"checksum version_check 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6b772017e347561807c1aa192438c5fd74242a670a6cffacc40f2defd1dc069d"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
"checksum winapi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "04e3bd221fcbe8a271359c04f21a76db7d0c6028862d1bb5512d85e1e2eb5bb3"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"

16
load-tester/Cargo.toml Normal file
View file

@ -0,0 +1,16 @@
[package]
name = "raiblocks-load-tester"
version = "0.1.0"
[dependencies]
clap = "2.29.2"
error-chain = "0.11.0"
serde_json = "1.0.9"
serde = "1.0.27"
hyper = "0.11.15"
tokio-core = "0.1.12"
futures = "0.1.17"
rand = "0.4.2"
serde_derive = "1.0.27"
tokio-process = "0.1.5"
time = "0.1.39"

View file

@ -0,0 +1,125 @@
use std::io;
use std::fs;
use std::fs::File;
use std::path::Path;
use std::process::Command;
use serde_json;
use futures::Future;
use hyper::client::Connect;
use tokio_core::reactor::Handle;
use tokio_process::{Child, CommandExt};
use serde_json::Value;
use errors::*;
use rpc::RpcClient;
const RPC_PORT_START: u64 = 55000;
const PEERING_PORT_START: u64 = 54000;
pub fn launch_node(
rai_node: &Path,
tmp_dir: &Path,
handle: Handle,
i: u64,
) -> Result<(Child, RpcClient)> {
let data_dir = tmp_dir.join(format!("RaiBlocks_load_test_{}", i));
match fs::create_dir(&data_dir) {
Ok(_) => {}
Err(ref e) if e.kind() == io::ErrorKind::AlreadyExists => {
let _ = fs::remove_file(data_dir.join("data.ldb"));
}
r => r.chain_err(|| "failed to create rai_node data directory")?,
}
let rpc_port = RPC_PORT_START + i;
let peering_port = PEERING_PORT_START + i;
let config = json!({
"version": "2",
"rpc_enable": "true",
"rpc": {
"address": "::1",
"port": rpc_port.to_string(),
"enable_control": "true",
"frontier_request_limit": "16384",
"chain_request_limit": "16384",
},
"node": {
"version": "8",
"peering_port": peering_port.to_string(),
"bootstrap_fraction_numerator": "1",
"receive_minimum": "1000000000000000000000000",
"logging": {
"version": "2",
"ledger": "false",
"ledger_duplicate": "false",
"vote": "false",
"network": "true",
"network_message": "false",
"network_publish": "false",
"network_packet": "false",
"network_keepalive": "false",
"node_lifetime_tracing": "false",
"insufficient_work": "true",
"log_rpc": "true",
"bulk_pull": "false",
"work_generation_time": "true",
"log_to_cerr": "false",
"max_size": "16777216",
},
"work_peers": "",
"preconfigured_peers": "",
"preconfigured_representatives": [
"xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo"
],
"inactive_supply": "0",
"password_fanout": "1024",
"io_threads": "8",
"work_threads": "8",
"enable_voting": "true",
"bootstrap_connections": "4",
"callback_address": "",
"callback_port": "0",
"callback_target": "",
"lmdb_max_dbs": "128",
},
"opencl_enable": "false",
"opencl": {
"platform": "0",
"device": "0",
"threads": "1048576",
}
});
let config_writer =
File::create(data_dir.join("config.json")).chain_err(|| "failed to create config.json")?;
serde_json::to_writer_pretty(config_writer, &config)
.chain_err(|| "failed to write config.json")?;
let child = Command::new(rai_node)
.arg("--data_path")
.arg(&data_dir)
.arg("--daemon")
.spawn_async(&handle)
.chain_err(|| "failed to spawn rai_node")?;
let rpc_client = RpcClient::new(
handle,
format!("http://[::1]:{}/", rpc_port).parse().unwrap(),
);
Ok((child, rpc_client))
}
pub fn connect_node<C: Connect>(
node: &RpcClient<C>,
i: u64,
) -> Box<Future<Item = (), Error = Error>> {
Box::new(
node.call::<_, Value>(&json!({
"action": "keepalive",
"address": "::1",
"port": PEERING_PORT_START + i,
})).then(|x| x.chain_err(|| "failed to call rai_node RPC"))
.map(|_| ()),
) as _
}

534
load-tester/src/main.rs Normal file
View file

@ -0,0 +1,534 @@
#![recursion_limit = "128"]
use std::process;
use std::path::PathBuf;
use std::thread;
use std::time::{Duration, Instant};
use std::collections::HashMap;
use std::iter;
use std::env;
extern crate clap;
use clap::Arg;
#[macro_use]
extern crate error_chain;
extern crate futures;
use futures::{stream, Future, Stream};
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;
use serde_json::Value;
extern crate tokio_core;
use tokio_core::reactor::Core;
extern crate tokio_process;
extern crate hyper;
extern crate rand;
use rand::Rng;
extern crate time;
mod errors {
error_chain!{}
}
use errors::*;
mod rpc;
use rpc::{RpcClient, RpcError};
mod launch_node;
struct Parameters {
node_count: u16,
node_path: PathBuf,
tmp_dir: PathBuf,
send_count: usize,
dest_count: usize,
simultaneous_process_calls: usize,
catch_up_timeout: u64,
generate_receives: bool,
precompute_blocks: bool,
output_stats: bool,
}
// found in secure.cpp
const GENESIS_ACCOUNT: &str = "xrb_3e3j5tkog48pnny9dmfzj1r16pg8t1e76dz5tmac6iq689wyjfpiij4txtdo";
const GENESIS_PRIVKEY: &str = "34F0A37AAD20F4A260F0A5B3CB3D7FB50673212263E58A380BC10474BB039CE4";
fn run(params: Parameters) -> Result<()> {
let output_stats = params.output_stats;
macro_rules! tstat {
($( $x:tt )*) => {
if output_stats {
let now = time::now().to_timespec();
println!("{}.{:09},{}", now.sec, now.nsec, format_args!( $( $x )* ));
}
}
}
let mut tokio_core = Core::new().chain_err(|| "failed to create tokio Core")?;
let mut children = Vec::with_capacity(params.node_count as _);
let mut nodes: Vec<RpcClient<_>> = Vec::with_capacity(params.node_count as _);
for i in 0..params.node_count {
let (child, rpc_client) = launch_node::launch_node(
&params.node_path,
&params.tmp_dir,
tokio_core.handle(),
i as _,
)?;
children.push(child);
nodes.push(rpc_client);
}
if nodes.is_empty() {
bail!("no nodes spun up");
}
eprintln!("Waiting for nodes to spin up...");
thread::sleep(Duration::from_secs(7));
eprintln!("Connecting nodes...");
let primary_node = nodes.first().unwrap();
for (a, node) in nodes.iter().enumerate() {
for b in 0..nodes.len() {
if a != b {
tokio_core.run(launch_node::connect_node(node, b as _))?;
}
}
}
thread::sleep(Duration::from_secs(5));
eprintln!("Beginning tests");
tstat!("start");
#[derive(Debug, Deserialize, PartialEq, Eq)]
struct AccountInfo {
frontier: String,
balance: String,
block_count: String,
}
tstat!("genesis_info,start");
let genesis_initial = primary_node.call(&json!({
"action": "account_info",
"account": GENESIS_ACCOUNT,
}));
let genesis_initial: AccountInfo = tokio_core
.run(genesis_initial)
.chain_err(|| "failed to get genesis account info")?;
tstat!("genesis_info,done");
let genesis_initial_balance = genesis_initial.balance;
#[derive(Deserialize)]
#[allow(dead_code)]
struct Account {
account: String,
private: String,
public: String,
}
tstat!("key_create,start");
let dest_accts = stream::iter_ok(0..params.dest_count)
.map(|_| {
primary_node.call(&json!({
"action": "key_create",
}))
})
.buffer_unordered(10) // execute 10 `key_create`s simultaniously
.inspect(|_| {
tstat!("key_create,progress");
})
.collect();
tstat!("key_create,done");
let dest_accts: Vec<Account> = tokio_core
.run(dest_accts)
.chain_err(|| "failed to generate destination accounts")?;
if dest_accts.is_empty() {
bail!("no destination accounts generated");
}
let mut frontiers = HashMap::new();
#[derive(Deserialize)]
struct BlockInfo {
hash: String,
block: String,
}
let mut rng: rand::XorShiftRng = rand::thread_rng().gen();
if params.precompute_blocks {
frontiers.insert(GENESIS_ACCOUNT, genesis_initial.frontier);
let mut last_percent = 0;
eprint!("Creating blocks: 00%");
tstat!("block_create,start");
let mut blocks: Vec<String> = Vec::new();
for i in 0..params.send_count {
let dest_acct = &rng.choose(&dest_accts).unwrap();
// since only `balance - amount` matters, each block spends 1 raw
let send_future = primary_node.call(&json!({
"action": "block_create",
"type": "send",
"key": GENESIS_PRIVKEY,
"balance": genesis_initial_balance,
"amount": i + 1,
"destination": dest_acct.account,
"previous": frontiers[GENESIS_ACCOUNT],
}));
// needs to be synchronous because of frontier ordering
let send: BlockInfo = tokio_core
.run(send_future)
.chain_err(|| "failed to create send block")?;
tstat!("block_create,progress,send");
blocks.push(send.block);
frontiers.insert(GENESIS_ACCOUNT, send.hash.clone());
if params.generate_receives {
let recv_future = if let Some(frontier) = frontiers.get(dest_acct.account.as_str())
{
primary_node.call(&json!({
"action": "block_create",
"type": "receive",
"key": dest_acct.private,
"previous": frontier,
"source": send.hash,
}))
} else {
primary_node.call(&json!({
"action": "block_create",
"type": "open",
"key": dest_acct.private,
"source": send.hash,
"representative": GENESIS_ACCOUNT,
}))
};
let recv: BlockInfo = tokio_core
.run(recv_future)
.chain_err(|| "failed to create receive block")?;
tstat!("block_create,progress,receive");
frontiers.insert(&dest_acct.account, recv.hash);
blocks.push(recv.block);
}
let new_percent = (100 * i) / params.send_count;
if last_percent == new_percent {
continue;
}
last_percent = new_percent;
eprint!("\rCreating blocks: {:02}%", new_percent);
}
eprintln!("\rCreated blocks ");
tstat!("block_create,done");
let mut process_calls_completed = 0;
last_percent = 0;
let n_blocks = blocks.len();
eprint!("Primary node processing blocks: 00%");
tstat!("process,start");
let process = stream::iter_ok(blocks.iter())
.map(|block| {
primary_node.call::<_, Value>(&json!({
"action": "process",
"block": block,
}))
})
.buffer_unordered(params.simultaneous_process_calls)
.then(|r| match r {
Ok(_) => Ok(()),
Err(RpcError::RpcError(Value::String(ref s)))
if params.simultaneous_process_calls != 1 && s.starts_with("Gap") =>
{
Ok(())
}
Err(err) => Err(err),
})
.inspect(|_| {
process_calls_completed += 1;
let new_percent = (100 * process_calls_completed) / n_blocks;
if last_percent == new_percent {
return;
}
last_percent = new_percent;
eprint!("\rPrimary node processing blocks: {:02}%", new_percent);
tstat!("process,progress");
});
tokio_core
.run(process.fold((), |_, _| Ok(())))
.chain_err(|| "failed to process blocks")?;
tstat!("process,done");
eprintln!("\rPrimary node processed blocks ");
} else {
#[derive(Deserialize)]
struct WalletInfo {
wallet: String,
}
let wallet = primary_node.call(&json!({
"action": "wallet_create",
}));
let wallet: WalletInfo = tokio_core
.run(wallet)
.chain_err(|| "failed to create wallet")?;
let wallet = wallet.wallet;
tstat!("wallet_add_key,start");
let add_genesis = primary_node.call::<_, Value>(&json!({
"action": "wallet_add",
"wallet": wallet,
"key": GENESIS_PRIVKEY,
}));
tokio_core
.run(add_genesis)
.chain_err(|| "failed to add genesis key to wallet")?;
tstat!("wallet_add_key,progress");
let add_keys = stream::iter_ok(dest_accts.iter())
.map(|acct| {
primary_node.call::<_, Value>(&json!({
"action": "wallet_add",
"wallet": wallet,
"key": acct.private,
"work": false, // We always manually call `receive`
}))
})
.buffer_unordered(10)
.inspect(|_| tstat!("wallet_add_key,progress"));
tokio_core
.run(add_keys.fold((), |_, _| Ok(())))
.chain_err(|| "failed to add keys to wallet")?;
tstat!("wallet_add_key,done");
let mut send_calls_completed = 0;
let mut last_percent = 0;
#[derive(Deserialize)]
struct TransactionInfo {
block: String,
}
eprint!("\rPrimary node processing transactions: 00%");
tstat!("transaction,start");
let wallet = wallet.as_str();
let dest_accts = dest_accts.as_slice();
let params = &params;
let stream = stream::iter_ok(0..params.send_count)
.map(move |_| {
let dest_acct = rng.choose(dest_accts).unwrap();
let send_future = primary_node
.call::<_, TransactionInfo>(&json!({
"action": "send",
"wallet": wallet,
"source": GENESIS_ACCOUNT,
"destination": dest_acct.account,
"amount": "1",
}))
.inspect(move |_| {
tstat!("transaction,progress,send");
});
if params.generate_receives {
Box::new(send_future.and_then(move |send| {
primary_node
.call::<_, TransactionInfo>(&json!({
"action": "receive",
"wallet": wallet,
"account": dest_acct.account,
"block": send.block,
}))
.inspect(move |_| {
tstat!("transaction,progress,receive");
})
})) as Box<Future<Item = TransactionInfo, Error = RpcError>>
} else {
Box::new(send_future) as Box<Future<Item = TransactionInfo, Error = RpcError>>
}
})
.buffer_unordered(params.simultaneous_process_calls)
.inspect(|_| {
send_calls_completed += 1;
let new_percent = (100 * send_calls_completed) / params.send_count;
if last_percent == new_percent {
return;
}
last_percent = new_percent;
eprint!(
"\rPrimary node processing transactions: {:02}%",
new_percent
);
});
tokio_core
.run(stream.fold((), |_, _| Ok(())))
.chain_err(|| "failed to process transactions")?;
eprintln!("\rPrimary node processed transactions ");
tstat!("transaction,progress,done");
}
let broadcasted_at = Instant::now();
eprintln!("Waiting for nodes to catch up...");
let timeout = Duration::from_secs(params.catch_up_timeout);
let mut known_account_info = HashMap::new();
tstat!("check,start");
for node in &nodes {
for (&acct, frontier) in frontiers.iter() {
// We only know frontiers if `precompute_blocks` is enabled.
loop {
if Instant::now() - broadcasted_at > timeout {
bail!("timed out while waiting for nodes to catch up");
}
let acct_info = node.call::<_, AccountInfo>(&json!({
"action": "account_info",
"account": acct,
}));
let acct_info = tokio_core
.run(acct_info)
.chain_err(|| "failed to check genesis account info")?;
if &acct_info.frontier == frontier {
break;
}
thread::sleep(Duration::from_secs(1));
}
}
if !frontiers.is_empty() {
tstat!("check,progress");
}
if node as *const _ == primary_node as *const _ {
for acct in dest_accts
.iter()
.map(|a| a.account.as_str())
.chain(iter::once(GENESIS_ACCOUNT))
{
let acct_info = node.call(&json!({
"action": "account_info",
"account": acct,
}));
let acct_info: AccountInfo = tokio_core.run(acct_info).chain_err(|| {
format!("failed to check account {} info on primary node", acct)
})?;
known_account_info.insert(acct, acct_info);
}
} else {
for (&acct, acct_info) in known_account_info.iter() {
loop {
if Instant::now() - broadcasted_at > timeout {
bail!("timed out while waiting for nodes to catch up");
}
let node_acct_info = node.call(&json!({
"action": "account_info",
"account": acct,
}));
let node_acct_info = tokio_core.run(node_acct_info);
match node_acct_info {
Err(RpcError::RpcError(ref s)) if s == "Account not found" => {}
Ok(node_acct_info) => if acct_info == &node_acct_info {
break;
},
r => {
r.chain_err(|| {
format!("failed to check account {} info on secondary node", acct)
})?;
}
}
thread::sleep(Duration::from_secs(1));
}
}
}
tstat!("check,progress");
}
tstat!("check,done");
eprintln!("Done!");
tstat!("done");
Ok(())
}
fn main() {
let matches = clap::App::new("raiblocks-load-tester")
.version(env!("CARGO_PKG_VERSION"))
.arg(
Arg::with_name("node_count")
.short("n")
.long("node_count")
.value_name("N")
.default_value("10")
.help("The number of nodes to spin up"),
)
.arg(
Arg::with_name("tmp_dir")
.long("tmp-dir")
.value_name("PATH")
.help("The path to a temporary directory for rai_node data"),
)
.arg(
Arg::with_name("node_path")
.value_name("PATH")
.required(true)
.help("The path to the rai_node to test"),
)
.arg(
Arg::with_name("send_count")
.short("s")
.short("send-count")
.value_name("N")
.default_value("2000")
.help("How many send blocks to generate"),
)
.arg(
Arg::with_name("destination_count")
.short("destination-count")
.value_name("N")
.default_value("2")
.help("How many destination accounts to choose between"),
)
.arg(
Arg::with_name("simultaneous_process_calls")
.long("simultaneous-process-calls")
.value_name("N")
.default_value("20")
.help("How many `process` or `send` calls to send at a given time"),
)
.arg(
Arg::with_name("catch_up_timeout")
.long("catch-up-timeout")
.value_name("SECONDS")
.default_value("120")
.help("The maximum number of seconds to wait for nodes to catch up"),
)
.arg(
Arg::with_name("no_receives")
.long("no-receives")
.help("Do not generate receives for the generated sends"),
)
.arg(
Arg::with_name("precompute_blocks")
.long("precompute-blocks")
.help("Use the `block_create` and `process` endpoints to precompute blocks"),
)
.arg(
Arg::with_name("stats")
.long("stats")
.help("Output stats on how long steps take in CSV format"),
)
.get_matches();
macro_rules! num_arg {
($arg:expr) => {
match matches.value_of($arg).unwrap().parse() {
Ok(n) => n,
Err(err) => {
eprintln!("Failed to parse {}: {}", $arg, err);
process::exit(2);
}
}
};
}
let params = Parameters {
node_count: num_arg!("node_count"),
node_path: matches.value_of("node_path").unwrap().into(),
tmp_dir: matches
.value_of("tmp_dir")
.or(env::var("TMPDIR").ok().as_ref().map(|x| x.as_str()))
.unwrap_or("/tmp")
.into(),
send_count: num_arg!("send_count"),
dest_count: num_arg!("destination_count"),
simultaneous_process_calls: num_arg!("simultaneous_process_calls"),
catch_up_timeout: num_arg!("catch_up_timeout"),
generate_receives: !matches.is_present("no_receives"),
precompute_blocks: matches.is_present("precompute_blocks"),
output_stats: matches.is_present("stats"),
};
if let Err(ref e) = run(params) {
eprintln!("Error: {}", e);
for e in e.iter().skip(1) {
eprintln!(" caused by: {}", e);
}
if let Some(backtrace) = e.backtrace() {
eprintln!("\nBacktrace:\n{:?}", backtrace);
}
process::exit(1);
}
}

95
load-tester/src/rpc.rs Normal file
View file

@ -0,0 +1,95 @@
use std::fmt;
use futures::{Future, Stream};
use futures::future;
use tokio_core::reactor::Handle;
use hyper::{self, Request, Uri};
use hyper::client::{Connect, HttpConnector};
use hyper::header::{ContentLength, ContentType};
use serde::{Deserialize, Serialize};
use serde_json::{self, Value};
#[derive(Debug)]
pub enum RpcError {
Http(hyper::Error),
Json(serde_json::Error),
/// An error returned from the RPC
RpcError(Value),
}
impl fmt::Display for RpcError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
RpcError::Http(ref err) => fmt::Display::fmt(err, f),
RpcError::Json(ref err) => fmt::Display::fmt(err, f),
RpcError::RpcError(ref val) => if let Some(s) = val.as_str() {
fmt::Display::fmt(s, f)
} else {
fmt::Display::fmt(val, f)
},
}
}
}
impl ::std::error::Error for RpcError {
fn description(&self) -> &str {
match *self {
RpcError::Http(_) => "HTTP error",
RpcError::Json(_) => "JSON parsing error",
RpcError::RpcError(_) => "RPC returned error",
}
}
}
pub struct RpcClient<C: Connect = HttpConnector> {
http_client: hyper::Client<C>,
uri: Uri,
}
impl RpcClient<HttpConnector> {
pub fn new(tokio_handle: Handle, rpc_uri: Uri) -> RpcClient<HttpConnector> {
RpcClient::from_hyper_client(hyper::Client::new(&tokio_handle), rpc_uri)
}
}
impl<C: Connect> RpcClient<C> {
pub fn from_hyper_client(hyper_client: hyper::Client<C>, rpc_uri: Uri) -> RpcClient<C> {
RpcClient {
http_client: hyper_client,
uri: rpc_uri,
}
}
pub fn call<'a, I: Serialize, O: Deserialize<'a> + 'static>(
&self,
request: &'a I,
) -> Box<Future<Item = O, Error = RpcError>> {
let json = match serde_json::to_vec(request).map_err(RpcError::Json) {
Ok(json) => json,
Err(err) => return Box::new(future::err(err)) as _,
};
let mut req = Request::new(hyper::Method::Post, self.uri.clone());
req.headers_mut().set(ContentType::json());
req.headers_mut().set(ContentLength(json.len() as u64));
req.set_body(json);
Box::new(
self.http_client
.request(req)
.and_then(|res| res.body().concat2())
.map_err(RpcError::Http)
.and_then(|slice| serde_json::from_slice(&slice).map_err(RpcError::Json))
.and_then(|mut json: Value| {
if let Some(obj) = json.as_object_mut() {
if let Some(err) = obj.remove("error") {
return Err(RpcError::RpcError(err));
}
}
O::deserialize(json).map_err(RpcError::Json)
}),
) as _
}
}

View file

@ -4127,6 +4127,7 @@ void rai::rpc_connection::parse_connection ()
this_l->res.set ("Content-Type", "application/json");
this_l->res.set ("Access-Control-Allow-Origin", "*");
this_l->res.set ("Access-Control-Allow-Headers", "Accept, Accept-Language, Content-Language, Content-Type");
this_l->res.set ("Connection", "close");
this_l->res.result (boost::beast::http::status::ok);
this_l->res.body () = body;
this_l->res.version (version);