Fix CI by using local ws echo server (#1711)

This commit is contained in:
Justin Starry 2021-01-23 18:59:48 +08:00 committed by GitHub
parent cf315476e8
commit aef2ee56c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 143 additions and 35 deletions

View File

@ -136,6 +136,10 @@ jobs:
image: kennethreitz/httpbin@sha256:599fe5e5073102dbb0ee3dbb65f049dab44fa9fc251f6835c9990f8fb196a72b
ports:
- 8080:80
echo_server:
image: jmalloc/echo-server@sha256:c461e7e54d947a8777413aaf9c624b4ad1f1bac5d8272475da859ae82c1abd7d
ports:
- 8081:8080
strategy:
matrix:
@ -169,19 +173,19 @@ jobs:
- name: Run tests - yew
env:
HTTPBIN_URL: "http://localhost:8080"
ECHO_SERVER_URL: "ws://localhost:8081"
run: |
cd packages/yew
# FIXME: Chrome appears to be timing out occasionally
wasm-pack test --firefox --headless -- --features "wasm_test httpbin_test"
wasm-pack test --chrome --firefox --headless -- --features "wasm_test httpbin_test echo_server_test"
- name: Run tests - yew-stdweb
if: matrix.toolchain != 'stable'
env:
HTTPBIN_URL: "http://localhost:8080"
ECHO_SERVER_URL: "ws://localhost:8081"
run: |
cd packages/yew-stdweb
# FIXME: Chrome really doesn't seem to like yew-stdweb
wasm-pack test --firefox --headless -- --features "wasm_test httpbin_test"
wasm-pack test --chrome --firefox --headless -- --features "wasm_test httpbin_test echo_server_test"
- name: Run tests - yew-functional
run: |

View File

@ -54,9 +54,15 @@ The tests for the fetch service require a local [httpbin](https://httpbin.org/)
If you have [Docker](https://www.docker.com/) installed,
`cargo make tests` will automatically run httpbin in a container for you.
Alternatively, you can manually run an httpbin instance however you want and set the `HTTPBIN_URL` environment variable to the URL.
Alternatively, you can set the `HTTPBIN_URL` environment variable to the URL you wish to run tests against.
Please note that the public httpbin instance can't be used for these tests.
### WebSocket service tests
The tests for the web-socket service require an echo server.
If you have [Docker](https://www.docker.com/) installed,
`cargo make tests` will automatically run an [echo server](https://hub.docker.com/r/jmalloc/echo-server) in a container for you.
Alternatively, you can set the `ECHO_SERVER_URL` environment variable to the URL you wish to run tests against.
### Macro tests

View File

@ -80,9 +80,27 @@ script = [
yew_test_features = set "${yew_test_features},httpbin_test"
end
fn set_echo_server_test_features
ECHO_SERVER_URL = get_env ECHO_SERVER_URL
echo INFO: using ${ECHO_SERVER_URL} for web-socket service tests
yew_test_features = set "${yew_test_features},echo_server_test"
end
run_httpbin_container = set false
if is_defined HTTPBIN_URL
set_httpbin_test_features
else
run_httpbin_container = set true
end
run_echo_server_container = set false
if is_defined ECHO_SERVER_URL
set_echo_server_test_features
else
run_echo_server_container = set true
end
if ${run_httpbin_container} or ${run_echo_server_container}
# only enable docker if docker executable is available
# and --skip-httpbin cli argument not provided to cargo make
docker_path = which docker
@ -99,41 +117,85 @@ script = [
end
if ${start_docker}
echo Starting httpbin docker image...
mkdir ./target
cidfile = set ./target/httpbin_container.cid
# if container already running, stop it
if is_file ${cidfile}
if ${run_httpbin_container}
echo Starting httpbin docker image...
cidfile = set ./target/httpbin_container.cid
# if container already running, stop it
if is_file ${cidfile}
container_id = readfile ${cidfile}
rm ${cidfile}
set_env HTTPBIN_CONTAINER_ID ${container_id}
cm_run_task tests-cleanup-httpbin
end
# get local port
docker_port = get_env YEW_HTTPBIN_PORT
if not is_defined docker_port
docker_port = set 7117
end
exec --fail-on-error docker run -d --cidfile ${cidfile} -p "${docker_port}:80" kennethreitz/httpbin
container_id = readfile ${cidfile}
rm ${cidfile}
container_id = trim ${container_id}
set_env HTTPBIN_CONTAINER_ID ${container_id}
cm_run_task tests-cleanup
set_env HTTPBIN_URL http://localhost:${docker_port}
set_httpbin_test_features
# wait for docker container to boot before running tests
if is_defined HTTPBIN_WAIT
sleep ${HTTPBIN_WAIT}
else
sleep 500
end
end
# get local port
docker_port = get_env YEW_HTTPBIN_PORT
if not is_defined docker_port
docker_port = set 7117
end
if ${run_echo_server_container}
echo Starting echo-server docker image...
cidfile = set ./target/echo_server_container.cid
exec --fail-on-error docker run -d --cidfile ${cidfile} -p "${docker_port}:80" kennethreitz/httpbin
container_id = readfile ${cidfile}
container_id = trim ${container_id}
set_env HTTPBIN_CONTAINER_ID ${container_id}
# if container already running, stop it
if is_file ${cidfile}
container_id = readfile ${cidfile}
rm ${cidfile}
set_env ECHO_SERVER_CONTAINER_ID ${container_id}
cm_run_task tests-cleanup-echo-server
end
set_env HTTPBIN_URL http://localhost:${docker_port}
set_httpbin_test_features
# get local port
docker_port = get_env YEW_ECHO_SERVER_PORT
if not is_defined docker_port
docker_port = set 7118
end
# wait for docker container to boot before running tests
if is_defined HTTPBIN_WAIT
sleep ${HTTPBIN_WAIT}
else
sleep 500
exec --fail-on-error docker run -d --cidfile ${cidfile} -p "${docker_port}:8080" jmalloc/echo-server
container_id = readfile ${cidfile}
container_id = trim ${container_id}
set_env ECHO_SERVER_CONTAINER_ID ${container_id}
set_env ECHO_SERVER_URL ws://localhost:${docker_port}
set_echo_server_test_features
# wait for docker container to boot before running tests
if is_defined ECHO_SERVER_WAIT
sleep ${ECHO_SERVER_WAIT}
else
sleep 500
end
end
else
echo "INFO: HTTPBIN_URL isn't set, won't run fetch service tests"
echo " please see the CONTRIBUTING.md file for instructions"
if ${run_httpbin_container}
echo "INFO: HTTPBIN_URL isn't set, won't run fetch service tests"
echo " please see the CONTRIBUTING.md file for instructions"
end
if ${run_echo_server_container}
echo "INFO: ECHO_SERVER_URL isn't set, won't run web-socket service tests"
echo " please see the CONTRIBUTING.md file for instructions"
end
end
end
@ -147,11 +209,26 @@ script = [
[tasks.tests-cleanup]
private = true
ignore_errors = true
run_task = { name = [
"test-cleanup-httpbin",
"test-cleanup-echo-server",
] }
[tasks.tests-cleanup-httpbin]
private = true
condition = { env_set = ["HTTPBIN_CONTAINER_ID"] }
ignore_errors = true
command = "docker"
args = ["rm", "--force", "${HTTPBIN_CONTAINER_ID}"]
[tasks.tests-cleanup-echo-server]
private = true
condition = { env_set = ["ECHO_SERVER_CONTAINER_ID"] }
ignore_errors = true
command = "docker"
args = ["rm", "--force", "${ECHO_SERVER_CONTAINER_ID}"]
[tasks.tests-stdweb]
private = true
extend = "core::wasm-pack-base"

View File

@ -69,6 +69,7 @@ std_web = ["stdweb"]
doc_test = []
wasm_test = []
httpbin_test = []
echo_server_test = []
services = []
agent = ["bincode"]
yaml = ["serde_yaml"]

View File

@ -135,6 +135,7 @@ web_sys = [
doc_test = []
wasm_test = []
httpbin_test = []
echo_server_test = []
wasm_bench = []
services = []
agent = ["bincode"]

View File

@ -172,7 +172,7 @@ pub(crate) mod test_util {
}
impl<T> CallbackFuture<T> {
fn ready(&self) -> Option<T> {
pub fn ready(&self) -> Option<T> {
self.0.borrow_mut().output.take()
}

View File

@ -366,16 +366,32 @@ impl Drop for WebSocketTask {
}
#[cfg(test)]
#[cfg(feature = "wasm_test")]
#[cfg(all(feature = "wasm_test", feature = "echo_server_test"))]
mod tests {
use super::*;
use crate::callback::{test_util::CallbackFuture, Callback};
use crate::format::{FormatError, Json};
use crate::services::TimeoutService;
use serde::{Deserialize, Serialize};
use std::time::Duration;
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
wasm_bindgen_test_configure!(run_in_browser);
const fn echo_server_url() -> &'static str {
// we can't do this at runtime because we're running in the browser.
env!("ECHO_SERVER_URL")
}
// Ignore the first response from the echo server
async fn ignore_first_message<T>(cb_future: &CallbackFuture<T>) {
let sleep_future = CallbackFuture::<()>::default();
let _sleep_task =
TimeoutService::spawn(Duration::from_millis(10), sleep_future.clone().into());
sleep_future.await;
cb_future.ready();
}
#[derive(Serialize, Deserialize, Debug, PartialEq)]
struct Message {
test: String,
@ -383,7 +399,7 @@ mod tests {
#[test]
async fn connect() {
let url = "wss://echo.websocket.org";
let url = echo_server_url();
let cb_future = CallbackFuture::<Json<Result<Message, anyhow::Error>>>::default();
let callback: Callback<_> = cb_future.clone().into();
let status_future = CallbackFuture::<WebSocketStatus>::default();
@ -391,6 +407,7 @@ mod tests {
let mut task = WebSocketService::connect(url, callback, notification).unwrap();
assert_eq!(status_future.await, WebSocketStatus::Opened);
ignore_first_message(&cb_future).await;
let msg = Message {
test: String::from("hello"),
@ -431,7 +448,7 @@ mod tests {
#[test]
async fn connect_text() {
let url = "wss://echo.websocket.org";
let url = echo_server_url();
let cb_future = CallbackFuture::<Json<Result<Message, anyhow::Error>>>::default();
let callback: Callback<_> = cb_future.clone().into();
let status_future = CallbackFuture::<WebSocketStatus>::default();
@ -439,6 +456,7 @@ mod tests {
let mut task = WebSocketService::connect_text(url, callback, notification).unwrap();
assert_eq!(status_future.await, WebSocketStatus::Opened);
ignore_first_message(&cb_future).await;
let msg = Message {
test: String::from("hello"),
@ -462,7 +480,7 @@ mod tests {
#[test]
async fn connect_binary() {
let url = "wss://echo.websocket.org";
let url = echo_server_url();
let cb_future = CallbackFuture::<Json<Result<Message, anyhow::Error>>>::default();
let callback: Callback<_> = cb_future.clone().into();
let status_future = CallbackFuture::<WebSocketStatus>::default();
@ -470,6 +488,7 @@ mod tests {
let mut task = WebSocketService::connect_binary(url, callback, notification).unwrap();
assert_eq!(status_future.await, WebSocketStatus::Opened);
ignore_first_message(&cb_future).await;
let msg = Message {
test: String::from("hello"),