Repository: rust-random/getrandom
Pull request #108 (2019-09-20 00:44:33)

Improve CI for web targets
This PR uses simplifies the testing story for `getrandom`. All targets now use the same testing file (eliminating the need for a separate `tests/wasm_bindgen` crate).

We also use `.cargo/config` to allow users to run `cargo test` normally for `wasm32-wasi` or `wasm32-unknown bindgen`. This just requires that [`wasmtime`](https://github.com/CraneStation/wasmtime) or [`wasm-bindgen-test-runner`](https://github.com/rustwasm/wasm-bindgen/tree/master/crates/test)  exist in the user's path.

The CI for these targets has been overhauled:
  - Tests are now actually run a larger number of targets:
    - `wasm32-wasi`
    - `stdweb`: Node and Chrome
    - `wasm-bindgen`: Node, Firefox, and Chrome
  - Tests are built/linked for `asmjs-unknown-emscripten`
  - We download pre-built binaries for all our dependancies

Results:
  - Less code
  - Less duplication
  - More tests are run
  - WASM CI is much faster. Decreased from 13 mins to 4.5 mins

This is not part of #98, so it can be merged into master.

josephlr: Updated description to reflect the scope of these changes. 

@dhardy this is ready, the CI runs significantly faster now.
dhardy: I would prefer that someone more familiar with WASM could review. @stevebob wrote this test originally (rand#696).

Patch:
diff --git a/.cargo/config b/.cargo/config
new file mode 100644
index 0000000..291ce5e
--- /dev/null
+++ b/.cargo/config
@@ -0,0 +1,5 @@
+[target.wasm32-unknown-unknown]
+runner = 'wasm-bindgen-test-runner'
+
+[target.wasm32-wasi]
+runner = 'wasmtime'
diff --git a/.travis.yml b/.travis.yml
index 19e566c..f96ab70 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -29,34 +29,51 @@ matrix:
 
     - name: "WASM via emscripten, stdweb, wasm-bindgen and WASI"
       rust: nightly
+      addons:
+        firefox: 69.0
+        chrome: stable
       install:
         - rustup target add wasm32-unknown-unknown
         - rustup target add wasm32-unknown-emscripten
+        - rustup target add asmjs-unknown-emscripten
         - rustup target add wasm32-wasi
-        - nvm install 9
-        - ./utils/ci/install_cargo_web.sh
+        # Get geckodriver
+        - wget -O geckodriver.tar.gz https://github.com/mozilla/geckodriver/releases/download/v0.25.0/geckodriver-v0.25.0-linux64.tar.gz
+        - tar -xzf geckodriver.tar.gz
+        # Get chromedirver (we cannot pin chrome version, so don't pin chromedriver version)
+        - export VERSION=$(wget -q -O - https://chromedriver.storage.googleapis.com/LATEST_RELEASE)
+        - wget -O chromedriver.zip https://chromedriver.storage.googleapis.com/$VERSION/chromedriver_linux64.zip
+        - unzip chromedriver.zip
+        # Get cargo-web
+        - wget -O cargo-web.gz https://github.com/koute/cargo-web/releases/download/0.6.26/cargo-web-x86_64-unknown-linux-gnu.gz
+        - gunzip cargo-web.gz
+        - chmod +x cargo-web
+        # Get wasmtime
+        - wget -O wasmtime.tar.xz https://github.com/CraneStation/wasmtime/releases/download/v0.3.0/wasmtime-v0.3.0-x86_64-linux.tar.xz
+        - tar -xf wasmtime.tar.xz --strip-components=1
+        # Get wasm-bindgen-test-runner
+        - wget -O wasm-bindgen.tar.gz https://github.com/rustwasm/wasm-bindgen/releases/download/0.2.50/wasm-bindgen-0.2.50-x86_64-unknown-linux-musl.tar.gz
+        - tar -xzf wasm-bindgen.tar.gz --strip-components=1
+        # Place the runner binaries in our PATH
+        - mv cargo-web wasmtime wasm-bindgen-test-runner $HOME/.cargo/bin
+        # Download and setup emscripten
         - cargo web prepare-emscripten
-        - cargo web -V
-        - cargo list | grep install-update || cargo install -f cargo-update
-        - cargo install-update -i cargo-update wasm-bindgen-cli wasm-pack
-      addons:
-        chrome: stable
+      env: EMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0"
       script:
-        # Testing wasm32-unknown-emscripten fails because of rust-lang/rust#49877
+        # We cannot run emscripten test binaries (see rust-lang/rust#63649).
         # However, we can still build and link all tests to make sure that works.
         # This is actually useful as it finds stuff such as rust-random/rand#669
-        - EMCC_CFLAGS="-s ERROR_ON_UNDEFINED_SYMBOLS=0" cargo web test --target wasm32-unknown-emscripten --no-run
-        #- cargo web test --target wasm32-unknown-emscripten
-        #- cargo web test --nodejs --target wasm32-unknown-emscripten
-        #- cargo build --target wasm32-unknown-unknown # without any features
-        - cargo build --target wasm32-wasi
-        - cargo build --target wasm32-unknown-unknown
-        - cargo build --target wasm32-unknown-unknown --features=wasm-bindgen
-        - cargo web test --target wasm32-unknown-unknown --features=stdweb
-        - cargo build --manifest-path tests/wasm_bindgen/Cargo.toml --target wasm32-unknown-unknown
-        - wasm-bindgen --nodejs target/wasm32-unknown-unknown/debug/getrandom_wasm_bindgen_test.wasm --out-dir tests/wasm_bindgen/js
-        - node tests/wasm_bindgen/js/index.js
-        - wasm-pack test --node tests/wasm_bindgen
+        - cargo web test --target wasm32-unknown-emscripten --no-run
+        - cargo web test --target asmjs-unknown-emscripten --no-run
+        # wasi tests
+        - cargo test --target wasm32-wasi
+        # stdweb tests (Node, Chrome)
+        - cargo web test --nodejs --target=wasm32-unknown-unknown --features=stdweb
+        - cargo web test --target=wasm32-unknown-unknown --features=stdweb
+        # wasm-bindgen tests (Node, Firefox, Chrome)
+        - cargo test --target wasm32-unknown-unknown --features=wasm-bindgen
+        - GECKODRIVER=$PWD/geckodriver cargo test --target wasm32-unknown-unknown --features=test-in-browser
+        - CHROMEDRIVER=$PWD/chromedriver cargo test --target wasm32-unknown-unknown --features=test-in-browser
 
     - name: "Linux, nightly, docs"
       rust: nightly
diff --git a/Cargo.toml b/Cargo.toml
index 7ac5850..a938c20 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,9 +14,6 @@ exclude = ["utils/*", ".*", "appveyor.yml"]
 travis-ci = { repository = "rust-random/getrandom" }
 appveyor = { repository = "rust-random/getrandom" }
 
-[workspace]
-members = ["tests/wasm_bindgen"]
-
 [dependencies]
 log = { version = "0.4", optional = true }
 cfg-if = "0.1"
@@ -35,9 +32,14 @@ wasi = "0.7"
 wasm-bindgen = { version = "0.2.29", optional = true }
 stdweb = { version = "0.4.18", optional = true }
 
+[target.wasm32-unknown-unknown.dev-dependencies]
+wasm-bindgen-test = "0.2"
+
 [features]
 std = []
 # Enables dummy implementation for unsupported targets
 dummy = []
 # Unstable feature to support being a libstd dependency
 rustc-dep-of-std = ["compiler_builtins", "core"]
+# Unstable feature for testing
+test-in-browser = ["wasm-bindgen"]
diff --git a/utils/ci/install_cargo_web.sh b/utils/ci/install_cargo_web.sh
deleted file mode 100755
index b35f069..0000000
--- a/utils/ci/install_cargo_web.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-set -euo pipefail
-IFS=$'\n\t'
-
-CARGO_WEB_RELEASE=$(curl -L -s -H 'Accept: application/json' https://github.com/koute/cargo-web/releases/latest)
-CARGO_WEB_VERSION=$(echo $CARGO_WEB_RELEASE | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
-CARGO_WEB_URL="https://github.com/koute/cargo-web/releases/download/$CARGO_WEB_VERSION/cargo-web-x86_64-unknown-linux-gnu.gz"
-
-echo "Downloading cargo-web from: $CARGO_WEB_URL"
-curl -L $CARGO_WEB_URL | gzip -d > cargo-web
-chmod +x cargo-web
-
-mkdir -p ~/.cargo/bin
-mv cargo-web ~/.cargo/bin


Test patch:
diff --git a/tests/mod.rs b/tests/common.rs
similarity index 80%
rename from tests/mod.rs
rename to tests/common.rs
index 66a3656..afefa03 100644
--- a/tests/mod.rs
+++ b/tests/common.rs
@@ -1,13 +1,19 @@
-extern crate getrandom;
+#[cfg(feature = "wasm-bindgen")]
+use wasm_bindgen_test::*;
 
 use getrandom::getrandom;
 
+#[cfg(feature = "test-in-browser")]
+wasm_bindgen_test_configure!(run_in_browser);
+
+#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen_test)]
 #[test]
 fn test_zero() {
     // Test that APIs are happy with zero-length requests
     getrandom(&mut [0u8; 0]).unwrap();
 }
 
+#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen_test)]
 #[test]
 fn test_diff() {
     let mut v1 = [0u8; 1000];
@@ -25,6 +31,7 @@ fn test_diff() {
     assert!(n_diff_bits >= v1.len() as u32);
 }
 
+#[cfg_attr(feature = "wasm-bindgen", wasm_bindgen_test)]
 #[test]
 fn test_huge() {
     let mut huge = [0u8; 100_000];
diff --git a/tests/wasm_bindgen/Cargo.toml b/tests/wasm_bindgen/Cargo.toml
deleted file mode 100644
index 4b735c8..0000000
--- a/tests/wasm_bindgen/Cargo.toml
+++ /dev/null
@@ -1,15 +0,0 @@
-[package]
-name = "getrandom_wasm_bindgen_test"
-description = "Minimal test crate for getrandom using wasm-bindgen"
-version = "0.1.0"
-authors = ["The Rand Project Developers"]
-publish = false
-license = "MIT/Apache-2.0"
-
-[lib]
-crate-type = ["cdylib"]
-
-[dependencies]
-getrandom = { path = "../..", features = ["wasm-bindgen"] }
-wasm-bindgen = "0.2"
-wasm-bindgen-test = "0.2"
diff --git a/tests/wasm_bindgen/js/index.js b/tests/wasm_bindgen/js/index.js
deleted file mode 100644
index d3390f6..0000000
--- a/tests/wasm_bindgen/js/index.js
+++ /dev/null
@@ -1,5 +0,0 @@
-'use strict';
-
-const getrandom_wasm_bindgen_test = require('./getrandom_wasm_bindgen_test');
-
-console.log(getrandom_wasm_bindgen_test.test_gen());
diff --git a/tests/wasm_bindgen/src/lib.rs b/tests/wasm_bindgen/src/lib.rs
deleted file mode 100644
index 3629cbb..0000000
--- a/tests/wasm_bindgen/src/lib.rs
+++ /dev/null
@@ -1,55 +0,0 @@
-// Copyright 2018 Developers of the Rand project.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Crate to test WASM with the `wasm-bindgen` lib.
-
-#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk.png")]
-
-extern crate getrandom;
-extern crate wasm_bindgen;
-extern crate wasm_bindgen_test;
-
-use std::slice;
-use wasm_bindgen::prelude::*;
-use wasm_bindgen_test::*;
-
-use getrandom::getrandom;
-
-#[wasm_bindgen]
-pub fn test_gen() -> i32 {
-    let mut int: i32 = 0;
-    unsafe {
-        let ptr = &mut int as *mut i32 as *mut u8;
-        let slice = slice::from_raw_parts_mut(ptr, 4);
-        getrandom(slice).unwrap();
-    }
-    int
-}
-
-#[wasm_bindgen_test]
-fn test_call() {
-    let mut buf = [0u8; 0];
-    getrandom(&mut buf).unwrap();
-}
-
-#[wasm_bindgen_test]
-fn test_diff() {
-    let mut v1 = [0u8; 1000];
-    getrandom(&mut v1).unwrap();
-
-    let mut v2 = [0u8; 1000];
-    getrandom(&mut v2).unwrap();
-
-    let mut n_diff_bits = 0;
-    for i in 0..v1.len() {
-        n_diff_bits += (v1[i] ^ v2[i]).count_ones();
-    }
-
-    // Check at least 1 bit per byte differs. p(failure) < 1e-1000 with random input.
-    assert!(n_diff_bits >= v1.len() as u32);
-}