Add tests for plume webserver (#513)

* begin setup front-end test environment with selenium
* run migrations before tests
* use https for tests
This commit is contained in:
fdb-hiroshima 2019-04-06 17:41:57 +02:00 committed by GitHub
parent 1f7ff62c19
commit eabe73ddc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 171 additions and 45 deletions

View File

@ -1,18 +1,34 @@
version: 2.1 version: 2.1
aliases: aliases:
- &plume-docker
image: plumeorg/plume-buildenv:v0.0.5
- &defaults - &defaults
docker: docker:
- image: plumeorg/plume-buildenv:v0.0.3 - *plume-docker
working_directory: ~/projects/Plume working_directory: ~/projects/Plume
- &postgresql - &postgresql
docker: docker:
- image: plumeorg/plume-buildenv:v0.0.3 - *plume-docker
- image: circleci/postgres:9.6-alpine - image: circleci/postgres:9.6-alpine
environment: environment:
POSTGRES_USER: postgres POSTGRES_USER: postgres
POSTGRES_DB: plume POSTGRES_DB: plume
working_directory: ~/projects/Plume working_directory: ~/projects/Plume
- &selenium
docker:
- *plume-docker
- image: elgalu/selenium:latest
working_directory: ~/projects/Plume
- &postgresql_selenium
docker:
- *plume-docker
- image: circleci/postgres:9.6-alpine
environment:
POSTGRES_USER: postgres
POSTGRES_DB: plume
- image: elgalu/selenium:latest
working_directory: ~/projects/Plume
- &attach_workspace - &attach_workspace
attach_workspace: attach_workspace:
@ -25,13 +41,13 @@ aliases:
- &env_postgresql - &env_postgresql
environment: environment:
MIGRATION_DIR: migrations/postgres MIGRATION_DIRECTORY: migrations/postgres
FEATURES: postgres FEATURES: postgres
DATABASE_URL: postgres://postgres@localhost/plume DATABASE_URL: postgres://postgres@localhost/plume
RUST_TEST_THREADS: 1 RUST_TEST_THREADS: 1
- &env_sqlite - &env_sqlite
environment: environment:
MIGRATION_DIR: migrations/sqlite MIGRATION_DIRECTORY: migrations/sqlite
FEATURES: sqlite FEATURES: sqlite
DATABASE_URL: plume.sqlite3 DATABASE_URL: plume.sqlite3
RUST_TEST_THREADS: 1 RUST_TEST_THREADS: 1
@ -101,26 +117,48 @@ aliases:
name: clippy name: clippy
command: cargo clippy --no-default-features --features="${FEATURES}" --release -p plume-cli -- -D warnings command: cargo clippy --no-default-features --features="${FEATURES}" --release -p plume-cli -- -D warnings
- *save_cache_cli - *save_cache_cli
- &test_plume - &test_unit
steps: steps:
- *attach_workspace - *attach_workspace
- run: - run:
name: Set cache key name: Set cache key
command: echo "$FEATURES" > /FEATURES command: echo "$FEATURES" > /FEATURES
- run:
name: Set compiler flags
# rustflags = ["-Clink-dead-code", "-Clink-args=-Xlinker --no-keep-memory -Xlinker --reduce-memory-overheads"]
command: echo "W3RhcmdldC54ODZfNjQtdW5rbm93bi1saW51eC1nbnVdCnJ1c3RmbGFncyA9IFsiLUNsaW5rLWRlYWQtY29kZSIsICItQ2xpbmstYXJncz0tWGxpbmtlciAtLW5vLWtlZXAtbWVtb3J5IC1YbGlua2VyIC0tcmVkdWNlLW1lbW9yeS1vdmVyaGVhZHMiXQoK" | base64 -d >> ~/.cargo/config
- *restore_cache_plume_dead_code - *restore_cache_plume_dead_code
- run: - run:
name: clippy name: clippy
command: cargo clippy --no-default-features --features="${FEATURES}" --release -- -D warnings command: cargo clippy --no-default-features --features="${FEATURES}" --release -- -D warnings
- run: - run:
name: compile test name: compile test
command: cargo test --no-default-features --features="${FEATURES}" --all --exclude plume-front --no-run || cargo test --no-default-features --features="${FEATURES}" --all --exclude plume-front --no-run command: cargo test --no-default-features --features="${FEATURES}" --all --exclude plume-front --no-run || cargo test --no-default-features --features="${FEATURES}" --all --exclude plume-front --no-run
- run: - run:
name: run test and upload coverage name: run test
command: ./script/compute_coverage.sh command: ./script/run_unit_test.sh
- run:
name: upload coverage
command: ./script/upload_coverage.sh unit
- *save_cache_plume_dead_code
- &test_browser
steps:
- *attach_workspace
- run:
name: Set cache key
command: echo "$FEATURES" > /FEATURES
- *restore_cache_plume_dead_code
- run:
name: install server
command: cargo install --debug --no-default-features --features="${FEATURES}",test --path . || cargo install --debug --no-default-features --features="${FEATURES}",test --path .
- run:
name: install plm
command: cargo install --debug --no-default-features --features="${FEATURES}" --path plume-cli || cargo install --debug --no-default-features --features="${FEATURES}" --path plume-cli
- run:
name: run test
command: ./script/run_browser_test.sh
environment:
BROWSER: firefox
- run:
name: upload coverage
command: ./script/upload_coverage.sh integration
- *save_cache_plume_dead_code - *save_cache_plume_dead_code
jobs: jobs:
@ -160,16 +198,25 @@ jobs:
<<: *env_sqlite <<: *env_sqlite
<<: *test_cli <<: *test_cli
test_plume_postgresql: test_unit_postgresql:
<<: *postgresql <<: *postgresql
<<: *env_postgresql <<: *env_postgresql
<<: *test_plume <<: *test_unit
test_plume_sqlite: test_unit_sqlite:
<<: *defaults <<: *defaults
<<: *env_sqlite <<: *env_sqlite
<<: *test_plume <<: *test_unit
test_browser_postgresql:
<<: *postgresql_selenium
<<: *env_postgresql
<<: *test_browser
test_browser_sqlite:
<<: *selenium
<<: *env_sqlite
<<: *test_browser
workflows: workflows:
version: 2 version: 2
@ -188,9 +235,15 @@ workflows:
- test_cli_sqlite: - test_cli_sqlite:
requires: requires:
- download_deps - download_deps
- test_plume_postgresql: - test_unit_postgresql:
requires: requires:
- download_deps - download_deps
- test_plume_sqlite: - test_unit_sqlite:
requires: requires:
- download_deps - download_deps
- test_browser_postgresql:
requires:
- build_web
- test_browser_sqlite:
requires:
- build_web

View File

@ -0,0 +1,6 @@
localhost:443 {
proxy / localhost:7878 {
transparent
}
tls self_signed
}

View File

@ -4,16 +4,29 @@ ENV PATH="/root/.cargo/bin:${PATH}"
#install native/circleci/build dependancies #install native/circleci/build dependancies
RUN apt update &&\ RUN apt update &&\
apt install -y git ssh tar gzip ca-certificates &&\ apt install -y git ssh tar gzip ca-certificates &&\
apt install -y binutils-dev build-essential cmake curl gcc gettext git libcurl4-openssl-dev libdw-dev libelf-dev libiberty-dev libpq-dev libsqlite3-dev libssl-dev make openssl pkg-config postgresql postgresql-contrib python zlib1g-dev apt install -y binutils-dev build-essential cmake curl gcc gettext git libcurl4-openssl-dev libdw-dev libelf-dev libiberty-dev libpq-dev libsqlite3-dev libssl-dev make openssl pkg-config postgresql postgresql-contrib python zlib1g-dev python3-pip
#install and configure rust #install and configure rust
RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2019-03-23 -y &&\ RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2019-03-23 -y &&\
rustup component add rustfmt clippy &&\ rustup component add rustfmt clippy &&\
rustup component add rust-std --target wasm32-unknown-unknown &&\ rustup component add rust-std --target wasm32-unknown-unknown
cargo install cargo-web &&\
#compile some deps
RUN cargo install cargo-web &&\
cargo install diesel_cli --no-default-features --features postgres,sqlite --version '=1.3.0' &&\
rm -fr ~/.cargo/registry rm -fr ~/.cargo/registry
#install coverage tools #install coverage tools
RUN curl -L https://github.com/SimonKagstrom/kcov/archive/master.tar.gz | tar xz &&\ RUN curl -L https://github.com/SimonKagstrom/kcov/archive/master.tar.gz | tar xz &&\
mkdir -p kcov-master/build && cd kcov-master/build && cmake .. && make &&\ mkdir -p kcov-master/build && cd kcov-master/build && cmake .. && make &&\
make install && cd ../.. && rm -rf kcov-master make install && cd ../.. && rm -rf kcov-master
#set some compilation parametters
COPY cargo_config /root/.cargo/config
#install selenium for front end tests
RUN pip3 install selenium
#install and configure caddy
RUN curl https://getcaddy.com | bash -s personal
COPY Caddyfile /Caddyfile

View File

@ -0,0 +1,3 @@
[target.x86_64-unknown-linux-gnu]
# link dead code for coverage, attempt to reduce linking memory usage to not get killed
rustflags = ["-Clink-dead-code", "-Clink-args=-Xlinker --no-keep-memory -Xlinker --reduce-memory-overheads"]

1
.gitignore vendored
View File

@ -20,3 +20,4 @@ main.css
*.wasm *.wasm
*.js *.js
.buildconfig .buildconfig
__pycache__

View File

@ -75,6 +75,7 @@ default = ["postgres"]
postgres = ["plume-models/postgres", "diesel/postgres"] postgres = ["plume-models/postgres", "diesel/postgres"]
sqlite = ["plume-models/sqlite", "diesel/sqlite"] sqlite = ["plume-models/sqlite", "diesel/sqlite"]
debug-mailer = [] debug-mailer = []
test = []
[workspace] [workspace]
members = ["plume-api", "plume-cli", "plume-models", "plume-common", "plume-front"] members = ["plume-api", "plume-cli", "plume-models", "plume-common", "plume-front"]

View File

@ -188,7 +188,7 @@ lazy_static! {
pub static ref CONFIG: Config = Config { pub static ref CONFIG: Config = Config {
base_url: var("BASE_URL").unwrap_or_else(|_| format!( base_url: var("BASE_URL").unwrap_or_else(|_| format!(
"127.0.0.1:{}", "127.0.0.1:{}",
var("ROCKET_PORT").unwrap_or_else(|_| "8000".to_owned()) var("ROCKET_PORT").unwrap_or_else(|_| "7878".to_owned())
)), )),
db_name: DB_NAME, db_name: DB_NAME,
#[cfg(feature = "postgres")] #[cfg(feature = "postgres")]

View File

View File

@ -0,0 +1,7 @@
#!/usr/bin/python3
from utils import Browser
class InstanceName(Browser):
def test_name_in_title(self):
self.get("/")
self.assertIn("plume-test", self.driver.title)

View File

@ -0,0 +1,22 @@
#!/usr/bin/python3
import unittest,os
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
class Browser(unittest.TestCase):
def setUp(self):
if os.environ["BROWSER"] == "firefox":
capabilities=DesiredCapabilities.FIREFOX
elif os.environ["BROWSER"] == "chrome":
capabilities=DesiredCapabilities.CHROME
else:
raise Exception("No browser was requested")
capabilities['acceptSslCerts'] = True
self.driver = webdriver.Remote(
command_executor='http://localhost:24444/wd/hub',
desired_capabilities=capabilities)
def tearDown(self):
self.driver.close()
def get(self, url):
return self.driver.get("https://localhost" + url)

26
script/run_browser_test.sh Executable file
View File

@ -0,0 +1,26 @@
#!/bin/bash
set -eo pipefail
export ROCKET_SECRET_KEY="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
mkdir -p "target/cov/plume"
mkdir -p "target/cov/plm"
plm='kcov --exclude-pattern=/.cargo,/usr/lib --verify target/cov/plm plm'
diesel migration run
diesel migration redo
$plm instance new -d plume-test.local -n plume-test
$plm users new -n admin -N 'Admin' -e 'email@exemple.com' -p 'password'
$plm search init
kcov --exclude-pattern=/.cargo,/usr/lib --verify target/cov/plume plume &
caddy -conf /Caddyfile &
until curl http://localhost:7878/test/health -f; do sleep 1; done 2>/dev/null >/dev/null
cd $(dirname $0)/browser_test/
python3 -m unittest *.py
kill -SIGINT %1
kill -SIGKILL %2
wait

View File

@ -8,4 +8,3 @@ for file in target/debug/*-*[^\.d]; do
kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$filename" "$file" kcov --exclude-pattern=/.cargo,/usr/lib --verify "target/cov/$filename" "$file"
fi fi
done done
bash <(curl -s https://codecov.io/bash)

3
script/upload_coverage.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
set -eo pipefail
bash <(curl -s https://codecov.io/bash) -F $1

View File

@ -59,6 +59,8 @@ mod mail;
#[macro_use] #[macro_use]
mod template_utils; mod template_utils;
mod routes; mod routes;
#[cfg(feature = "test")]
mod test_routes;
include!(concat!(env!("OUT_DIR"), "/templates.rs")); include!(concat!(env!("OUT_DIR"), "/templates.rs"));
@ -122,6 +124,7 @@ Then try to restart Plume
let search_unlocker = searcher.clone(); let search_unlocker = searcher.clone();
ctrlc::set_handler(move || { ctrlc::set_handler(move || {
search_unlocker.commit();
search_unlocker.drop_writer(); search_unlocker.drop_writer();
exit(0); exit(0);
}) })
@ -133,7 +136,7 @@ Then try to restart Plume
println!("Please refer to the documentation to see how to configure it."); println!("Please refer to the documentation to see how to configure it.");
} }
rocket::custom(CONFIG.rocket.clone().unwrap()) let rocket = rocket::custom(CONFIG.rocket.clone().unwrap())
.mount( .mount(
"/", "/",
routes![ routes![
@ -258,16 +261,6 @@ Then try to restart Plume
"/@/<name>/inbox".to_owned(), "/@/<name>/inbox".to_owned(),
rocket::http::Method::Post, rocket::http::Method::Post,
), ),
(
"/login".to_owned(),
"/login".to_owned(),
rocket::http::Method::Post,
),
(
"/users/new".to_owned(),
"/users/new".to_owned(),
rocket::http::Method::Post,
),
( (
"/api/<path..>".to_owned(), "/api/<path..>".to_owned(),
"/api/<path..>".to_owned(), "/api/<path..>".to_owned(),
@ -276,6 +269,9 @@ Then try to restart Plume
]) ])
.finalize() .finalize()
.expect("main: csrf fairing creation error"), .expect("main: csrf fairing creation error"),
) );
.launch();
#[cfg(feature = "test")]
let rocket = rocket.mount("/test", routes![test_routes::health,]);
rocket.launch();
} }

View File

@ -43,10 +43,7 @@ pub fn create(
#[post("/~/<blog>/<slug>/like", rank = 2)] #[post("/~/<blog>/<slug>/like", rank = 2)]
pub fn create_auth(blog: String, slug: String, i18n: I18n) -> Flash<Redirect> { pub fn create_auth(blog: String, slug: String, i18n: I18n) -> Flash<Redirect> {
utils::requires_login( utils::requires_login(
&i18n!( &i18n!(i18n.catalog, "To like a post, you need to be logged in"),
i18n.catalog,
"To like a post, you need to be logged in"
),
uri!(create: blog = blog, slug = slug), uri!(create: blog = blog, slug = slug),
) )
} }

View File

@ -43,10 +43,7 @@ pub fn create(
#[post("/~/<blog>/<slug>/reshare", rank = 1)] #[post("/~/<blog>/<slug>/reshare", rank = 1)]
pub fn create_auth(blog: String, slug: String, i18n: I18n) -> Flash<Redirect> { pub fn create_auth(blog: String, slug: String, i18n: I18n) -> Flash<Redirect> {
utils::requires_login( utils::requires_login(
&i18n!( &i18n!(i18n.catalog, "To reshare a post, you need to be logged in"),
i18n.catalog,
"To reshare a post, you need to be logged in"
),
uri!(create: blog = blog, slug = slug), uri!(create: blog = blog, slug = slug),
) )
} }

2
src/test_routes.rs Normal file
View File

@ -0,0 +1,2 @@
#[get("/health")]
pub fn health() {}