Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teach CircleCI to build Rust wrapper #353

Merged
merged 9 commits into from
Jan 28, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
GOTHEMIS_IMPORT: github.com/cossacklabs/themis/gothemis
CFLAGS: "-DCIRICLE_TEST"
steps:
- run: sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get -y install libssl-dev python python-setuptools python3 python3-setuptools ruby-dev nodejs npm lcov libc6-dbg rsync software-properties-common
- run: sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get -y install libssl-dev python python-setuptools python3 python3-setuptools ruby-dev nodejs npm lcov libc6-dbg rsync software-properties-common pkg-config clang
- run: sudo ln -sf /usr/bin/gcov-5 /usr/bin/gcov
- run: sudo ln -sf /usr/bin/nodejs /usr/bin/node
- run: sudo gem install coveralls-lcov
Expand All @@ -36,6 +36,17 @@ jobs:
- run: sudo apt-add-repository -y ppa:rael-gc/rvm
- run: sudo apt-get update && sudo DEBIAN_FRONTEND=noninteractive apt-get -y install rvm

- restore_cache:
keys:
- rust

# Install Rust toolchain (stable) via rustup
# Instructions taken from https://rustup.rs
- run: curl https://sh.rustup.rs -sSf | sh -s -- -y && cat ~/.cargo/env >> $BASH_ENV && source ~/.cargo/env && cargo --version && rustc --version
ilammy marked this conversation as resolved.
Show resolved Hide resolved
- run: rustup component add clippy
- run: rustup component add rustfmt
- run: cargo deadlinks --version || cargo install cargo-deadlinks

# download last valgrind because current version of valgrind on ubuntu (3.11.0) gives false positive errors
# link from http://valgrind.org/downloads/current.html
# don't fetch if was cached
Expand Down Expand Up @@ -76,6 +87,7 @@ jobs:
# it's important to set version of ruby precisely.
- run: source /etc/profile.d/rvm.sh && rvm use system && make test_ruby
- run: make test_go
- run: make test_rust
- run: $HOME/valgrind/bin/valgrind build/tests/soter_test 2>&1 | grep "ERROR SUMMARY\|definitely lost\|indirectly lost\|possibly lost" | awk '{sum += $4} END {print $0; if ( sum > 0 ) { exit 1 } }'
- run: $HOME/valgrind/bin/valgrind build/tests/themis_test 2>&1 | grep "ERROR SUMMARY\|definitely lost\|indirectly lost\|possibly lost" | awk '{sum += $4} END {print $0; if ( sum > 0 ) { exit 1 } }'
- run: cover_build/tests/soter_test
Expand All @@ -87,6 +99,12 @@ jobs:
- run: $HOME/valgrind/bin/valgrind build_with_boringssl/tests/soter_test 2>&1 | grep "ERROR SUMMARY\|definitely lost\|indirectly lost\|possibly lost" | awk '{sum += $4} END {print $0; if ( sum > 0 ) { exit 1 } }'
- run: $HOME/valgrind/bin/valgrind build_with_boringssl/tests/themis_test 2>&1 | grep "ERROR SUMMARY\|definitely lost\|indirectly lost\|possibly lost" | awk '{sum += $4} END {print $0; if ( sum > 0 ) { exit 1 } }'

- save_cache:
key: rust
paths:
- ~/.cargo
- ~/.rustup

integration_tests:
docker:
- image: cossacklabs/android-build:2019.01
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ endif

PHP_VERSION := $(shell php -r "echo PHP_MAJOR_VERSION;" 2>/dev/null)
RUBY_GEM_VERSION := $(shell gem --version 2>/dev/null)
RUST_VERSION := $(shell rustc --version 2>/dev/null)
GO_VERSION := $(shell go version 2>&1)
NPM_VERSION := $(shell npm --version 2>/dev/null)
PIP_VERSION := $(shell pip --version 2>/dev/null)
Expand Down
1 change: 0 additions & 1 deletion src/wrappers/themis/rust/libthemis-src/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ categories = ["development-tools::build-utils"]
license = "Apache-2.0"

[dependencies]
copy_dir = "0.1.2"
make-cmd = "0.1.0"

[dev-dependencies]
Expand Down
11 changes: 6 additions & 5 deletions src/wrappers/themis/rust/libthemis-src/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -133,8 +133,8 @@ impl Build {
let themis_build_dir = out_dir.join("build");
let themis_install_dir = out_dir.join("install");

// Themis uses in-source build. Cargo requires build scripts to never write anything
// outside of OUT_DIR so we just have to copy the source code there.
// Cargo requires build scripts to never write anything outside of OUT_DIR.
// Take care to honor this requirement. It is checked by tools during builds.

if !out_dir.exists() {
fs::create_dir(&out_dir).expect("mkdir themis");
Expand All @@ -146,14 +146,15 @@ impl Build {
fs::remove_dir_all(&themis_install_dir).expect("rm -r themis/install");
}

// TODO: fix a bug in copy_dir which ignores directory source if it is a symlink
copy_dir::copy_dir(&themis_src_dir, &themis_build_dir).expect("cp -r src build");
fs::create_dir(&themis_build_dir).expect("mkdir themis/build");
fs::create_dir(&themis_install_dir).expect("mkdir themis/install");

// Now we can build Themis and install it properly into OUT_DIR.
let mut themis_build_and_install = make_cmd::make();
themis_build_and_install
.current_dir(&themis_build_dir)
.current_dir(&themis_src_dir)
.stdout(Stdio::null())
.env("BUILD_PATH", &themis_build_dir)
.env("PREFIX", &themis_install_dir)
.arg("install");

Expand Down
1 change: 0 additions & 1 deletion src/wrappers/themis/rust/libthemis-src/themis

This file was deleted.

1 change: 1 addition & 0 deletions src/wrappers/themis/rust/libthemis-src/themis/LICENSE
1 change: 1 addition & 0 deletions src/wrappers/themis/rust/libthemis-src/themis/Makefile
1 change: 1 addition & 0 deletions src/wrappers/themis/rust/libthemis-src/themis/README.md
1 change: 1 addition & 0 deletions src/wrappers/themis/rust/libthemis-src/themis/jni
1 change: 1 addition & 0 deletions src/wrappers/themis/rust/libthemis-src/themis/src/soter
1 change: 1 addition & 0 deletions src/wrappers/themis/rust/libthemis-src/themis/src/themis
1 change: 1 addition & 0 deletions src/wrappers/themis/rust/libthemis-src/themis/tests
24 changes: 0 additions & 24 deletions tests/rust/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,3 @@ fn join_mismatching_keys() {
let error = KeyPair::try_join(secret_ec, public_rsa).expect_err("kind mismatch");
assert_eq!(error.kind(), ErrorKind::InvalidParameter);
}

#[test]
fn zero_memory_on_drop() {
ilammy marked this conversation as resolved.
Show resolved Hide resolved
let (secret, public) = gen_ec_key_pair().split();

let secret_bytes = slice_alias(secret.as_ref());
let public_bytes = slice_alias(public.as_ref());

assert!(!secret_bytes.iter().all(|&byte| byte == 0));
assert!(!public_bytes.iter().all(|&byte| byte == 0));

drop(secret);
drop(public);

// Technically, the following is *not* safe and is undefined behavior (the slices contain
// dangling pointers that cannot be dereferenced now), but it's gonna be alright, darling.

assert!(secret_bytes.iter().all(|&byte| byte == 0));
assert!(public_bytes.iter().all(|&byte| byte == 0));
}

fn slice_alias<'a, 'b, T>(slice: &'a [T]) -> &'b [T] {
unsafe { std::slice::from_raw_parts(slice.as_ptr(), slice.len()) }
}
37 changes: 37 additions & 0 deletions tests/rust/run_tests.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/sh

set -e

# Treat warnings as errors
export RUSTFLAGS="-D warnings"

echo
echo "Checking code style..."
echo
cargo fmt -- --check

echo "Running static analysis..."
echo
cargo clippy --all --all-targets

echo
echo "Building Themis..."
echo
LIBTHEMIS_DYNAMIC=1 cargo build
LIBTHEMIS_STATIC=1 cargo build

echo
echo "Running tests..."
echo
cargo test --all

echo
echo "Checking documentation..."
echo
cargo clean --doc && cargo doc --no-deps
cargo clean --doc && cargo doc --no-deps --features "vendored"
cargo deadlinks

echo
echo "Rust tests OK!"
echo
8 changes: 4 additions & 4 deletions tests/rust/secure_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ mod context_imprint {

let plaintext = b"example plaintext";
let mut ciphertext = cell.encrypt(&plaintext).unwrap();
ciphertext[10] = 42;
ciphertext[10] = !ciphertext[10];
let recovered = cell.decrypt(&ciphertext).unwrap();

assert_ne!(recovered, plaintext);
Expand Down Expand Up @@ -121,7 +121,7 @@ mod seal {

let plaintext = b"example plaintext";
let mut ciphertext = seal.encrypt(&plaintext).unwrap();
ciphertext[10] = 42;
ciphertext[10] = !ciphertext[10];
let error = seal.decrypt(&ciphertext).unwrap_err();

assert_eq!(error.kind(), ErrorKind::InvalidParameter);
Expand Down Expand Up @@ -174,7 +174,7 @@ mod token_protect {

let plaintext = b"example plaintext";
let (mut ciphertext, token) = cell.encrypt(&plaintext).unwrap();
ciphertext[10] = 42;
ciphertext[10] = !ciphertext[10];
let error = cell.decrypt(&ciphertext, &token).unwrap_err();

assert_eq!(error.kind(), ErrorKind::Fail);
Expand All @@ -186,7 +186,7 @@ mod token_protect {

let plaintext = b"example plaintext";
let (ciphertext, mut token) = cell.encrypt(&plaintext).unwrap();
token[10] = 42;
token[10] = !token[10];
let error = cell.decrypt(&ciphertext, &token).unwrap_err();

assert_eq!(error.kind(), ErrorKind::InvalidParameter);
Expand Down
2 changes: 1 addition & 1 deletion tests/rust/secure_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ fn corrupted_data() {
// could use some audit because it does not really handle corrupted messages well.
let plaintext = b"test message please ignore";
let mut wrapped = secure.wrap(&plaintext).expect("encryption");
wrapped[5] = 42;
wrapped[5] = !wrapped[5];
let error = secure.unwrap(&wrapped).expect_err("decryption error");

assert_eq!(error.kind(), ErrorKind::InvalidParameter);
Expand Down
12 changes: 11 additions & 1 deletion tests/test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,14 @@ ifdef GO_VERSION
@go test -v $(GOTHEMIS_IMPORT)/...
endif

test_all: test prepare_tests_all test_cpp test_php test_python test_ruby test_js test_go
test_rust:
ifdef RUST_VERSION
@echo "------------------------------------------------------------"
@echo "Running rust-themis tests."
@echo "In case of errors please see https://github.com/cossacklabs/themis/wiki/Rust-HowTo"
@echo "------------------------------------------------------------"
$(TEST_SRC_PATH)/rust/run_tests.sh
@echo "------------------------------------------------------------"
endif

test_all: test prepare_tests_all test_cpp test_php test_python test_ruby test_js test_go test_rust