Skip to content

Commit

Permalink
merge: pull request #9 from namib-project/6_github-ci-migration
Browse files Browse the repository at this point in the history
Add CI workflow for GitHub actions
  • Loading branch information
pulsastrix authored May 22, 2023
2 parents 1df5fb2 + 0b60b47 commit 658efa6
Show file tree
Hide file tree
Showing 12 changed files with 196 additions and 27 deletions.
98 changes: 98 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
on:
push:
branches:
- main
pull_request:
branches:
- main

env:
CARGO_TERM_COLOR: always
RUST_TEST_TIME_UNIT: 60,120
RUST_TEST_TIME_INTEGRATION: 60,120
RUST_TEST_TIME_DOCTEST: 60,120

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
crate: [libcoap-sys, libcoap-rs]
dtls_backend: [openssl, gnutls, tinydtls]
steps:
- uses: actions/checkout@v3
with:
submodules: true
- uses: dtolnay/rust-toolchain@stable
with:
components: rust-src
- if: matrix.dtls_backend == 'gnutls'
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: libgnutls28-dev libgnutls30
version: 1.0
- if: matrix.crate == 'libcoap-rs'
run: cargo test -p ${{ matrix.crate }} --no-default-features --features dtls,tcp,vendored --features dtls_${{ matrix.dtls_backend }} --no-fail-fast -- -Z unstable-options --report-time --ensure-time
- if: matrix.crate == 'libcoap-sys'
run: cargo test -p ${{ matrix.crate }} --features dtls,dtls_backend_${{ matrix.dtls_backend }} --no-fail-fast -- -Z unstable-options --report-time --ensure-time

lint:
runs-on: ubuntu-latest
strategy:
matrix:
crate: [libcoap-sys, libcoap-rs]
steps:
- uses: actions/checkout@v3
with:
submodules: true
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- uses: giraffate/clippy-action@main
with:
reporter: 'github-pr-check'
clippy_flags: -p ${{ matrix.crate }} --no-deps
level: warning
tool_name: clippy (${{ matrix.crate }})

coverage:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
crate: [libcoap-rs]
steps:
- uses: actions/checkout@v3
with:
submodules: true
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- uses: baptiste0928/cargo-install@v2
with:
crate: cargo-tarpaulin
- run: cargo tarpaulin --no-fail-fast --workspace --verbose --features dtls,tcp,vendored --exclude-files libcoap-sys/tests,libcoap/tests --timeout 120 --out Xml
- uses: irongut/CodeCoverageSummary@v1.3.0
with:
filename: ./cobertura.xml
badge: true
fail_below_min: false
format: markdown
hide_branch_rate: false
hide_complexity: true
indicators: true
output: file
- run: |
# Snippet taken from https://github.com/marocchino/sticky-pull-request-comment#append-after-comment-every-time-it-runs
EOF=$(dd if=/dev/urandom bs=15 count=1 status=none | base64)
echo "coverage_report<<$EOF" >> "$GITHUB_ENV"
echo "### Code Coverage Report" >> "$GITHUB_ENV"
echo "Generated for commit ${{ github.sha }} on `date -u`." >> "$GITHUB_ENV"
cat code-coverage-results.md >> "$GITHUB_ENV"
echo "$EOF" >> "$GITHUB_ENV"
- if: github.event_name == 'pull_request'
uses: marocchino/sticky-pull-request-comment@v2
with:
message: ${{ env.coverage_report }}
- run: cat code-coverage-results.md >> $GITHUB_STEP_SUMMARY
17 changes: 7 additions & 10 deletions libcoap-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
* See the README as well as the LICENSE file for more information.
*/

use std::io::ErrorKind;
use std::{
default::Default,
env,
io::ErrorKind,
path::{Path, PathBuf},
process::Command,
};
Expand Down Expand Up @@ -178,16 +178,13 @@ fn main() {
// libcoap doesn't support overriding the MbedTLS CFLAGS, but doesn't set those
// either, so we just set CFLAGS and hope they propagate.
if let Some(mbedtls_include) = env::var_os("DEP_MBEDTLS_INCLUDE") {
let mbedtls_library_path = Path::new(env::var_os("DEP_MBEDTLS_CONFIG_H").unwrap().as_os_str())
.parent()
.unwrap()
.join("build")
.join("library");
build_config.env("CFLAGS", format!("-I{}", mbedtls_include.to_str().unwrap()));
build_config.env(
"PKG_CONFIG_PATH",
Path::new(mbedtls_include.as_os_str())
.parent()
.unwrap()
.join("lib")
.join("pkgconfig")
.into_os_string(),
);
build_config.env("LDFLAGS", format!("-L{}", mbedtls_library_path.to_str().unwrap()));
}
},
DtlsBackend::GnuTls => {
Expand Down
19 changes: 18 additions & 1 deletion libcoap/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,17 @@ impl CoapContext<'_> {
reserved: [0; 7],
validate_id_call_back: Some(dtls_server_id_callback),
id_call_back_arg: inner_ref.raw_context as *mut c_void,
validate_sni_call_back: Some(dtls_server_sni_callback),
validate_sni_call_back: {
// Unsupported by TinyDTLS
#[cfg(not(feature = "dtls_tinydtls"))]
{
Some(dtls_server_sni_callback)
}
#[cfg(feature = "dtls_tinydtls")]
{
None
}
},
sni_call_back_arg: inner_ref.raw_context as *mut c_void,
psk_info: initial_data,
})),
Expand Down Expand Up @@ -533,6 +543,13 @@ impl CoapContext<'_> {
.unwrap()
.apply_to_spsk_info(&mut inner_ref.crypto_last_info_ref);
Some(&inner_ref.crypto_last_info_ref.key)
} else if inner_ref.crypto_default_info.is_some() {
inner_ref
.crypto_default_info
.as_ref()
.unwrap()
.apply_to_spsk_info(&mut inner_ref.crypto_last_info_ref);
Some(&inner_ref.crypto_last_info_ref.key)
} else {
None
}
Expand Down
4 changes: 4 additions & 0 deletions libcoap/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ pub trait CoapClientCryptoProvider: Debug {
///
/// Return a CoapCryptoProviderResponse corresponding to the cryptographic information that
/// should be used.
///
/// Note: Unsupported by the MBedTLS DTLS backend.
fn provide_key_for_hint(
&mut self,
hint: &CoapCryptoPskIdentity,
Expand Down Expand Up @@ -110,6 +112,8 @@ pub trait CoapServerCryptoProvider: Debug {
/// hint.
///
/// Return None if the provided SNI is unacceptable, i.e. you have no key for this server name.
///
/// Note: Unsupported by the TinyDTLS DTLS backend.
#[allow(unused_variables)]
fn provide_hint_for_sni(&mut self, sni: &str) -> CoapCryptoProviderResponse<CoapCryptoPskInfo> {
CoapCryptoProviderResponse::UseCurrent
Expand Down
2 changes: 1 addition & 1 deletion libcoap/src/message/request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ impl CoapRequest {
}
pdu.clear_options();
for opt in additional_opts {
(&mut pdu).add_option(opt);
pdu.add_option(opt);
}
if proxy_scheme.is_some() && proxy_uri.is_some() {
return Err(MessageConversionError::InvalidOptionCombination(
Expand Down
8 changes: 5 additions & 3 deletions libcoap/src/resource.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,11 @@ impl<D: Any + ?Sized + Debug> CoapResource<D> {
let raw_resource = coap_resource_init(
uri_path,
(COAP_RESOURCE_FLAGS_RELEASE_URI
| (notify_con
.then(|| COAP_RESOURCE_FLAGS_NOTIFY_CON)
.unwrap_or(COAP_RESOURCE_FLAGS_NOTIFY_NON))) as i32,
| if notify_con {
COAP_RESOURCE_FLAGS_NOTIFY_CON
} else {
COAP_RESOURCE_FLAGS_NOTIFY_NON
}) as i32,
);
let inner = CoapFfiRcCell::new(CoapResourceInner {
raw_resource,
Expand Down
16 changes: 13 additions & 3 deletions libcoap/src/session/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@ impl CoapClientSession<'_> {
/// Will return a [SessionCreationError] if libcoap was unable to create a session (most likely
/// because it was not possible to bind to a port).
#[cfg(feature = "dtls")]
pub fn connect_dtls<'a, 'b, P: 'static + CoapClientCryptoProvider>(
ctx: &'b mut CoapContext<'a>,
pub fn connect_dtls<'a, P: 'static + CoapClientCryptoProvider>(
ctx: &mut CoapContext<'a>,
addr: SocketAddr,
mut crypto_provider: P,
) -> Result<CoapClientSession<'a>, SessionCreationError> {
Expand All @@ -65,7 +65,17 @@ impl CoapClientSession<'_> {
let client_setup_data = Box::into_raw(Box::new(coap_dtls_cpsk_t {
version: COAP_DTLS_SPSK_SETUP_VERSION as u8,
reserved: [0; 7],
validate_ih_call_back: Some(dtls_ih_callback),
validate_ih_call_back: {
// Unsupported by MbedTLS
#[cfg(not(feature = "dtls_mbedtls"))]
{
Some(dtls_ih_callback)
}
#[cfg(feature = "dtls_mbedtls")]
{
None
}
},
ih_call_back_arg: std::ptr::null_mut(),
client_sni: std::ptr::null_mut(),
psk_info: coap_dtls_cpsk_info_t {
Expand Down
1 change: 1 addition & 0 deletions libcoap/src/transport/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
* See the README as well as the LICENSE file for more information.
*/
/// TODO
#[allow(dead_code)]
#[cfg(feature = "tcp")]
pub struct CoapTcpEndpoint {}
1 change: 1 addition & 0 deletions libcoap/src/transport/tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
* See the README as well as the LICENSE file for more information.
*/
/// TODO
#[allow(dead_code)]
#[cfg(feature = "tcp")]
pub struct CoapTlsEndpoint {}
35 changes: 35 additions & 0 deletions libcoap/tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use libcoap_rs::{CoapContext, CoapRequestHandler, CoapResource};
use std::net::{SocketAddr, UdpSocket};
use std::rc::Rc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Condvar, Mutex};
use std::thread::JoinHandle;
use std::time::Duration;

pub(crate) fn get_unused_server_addr() -> SocketAddr {
Expand All @@ -25,6 +27,39 @@ pub(crate) fn get_unused_server_addr() -> SocketAddr {
.expect("Failed to get server socket address")
}

/// Spawns a test server in a new thread and waits for context_configurator to complete before
/// returning.
/// As the context_configurator closure is responsible for binding to sockets, this can be used to
/// spawn a test server and wait for it to be ready to accept requests before returning (avoiding
/// test failure due to "Connection Refused" errors).
pub(crate) fn spawn_test_server<F: FnOnce(&mut CoapContext) + Send + 'static>(
context_configurator: F,
) -> JoinHandle<()> {
let ready_condition = Arc::new((Mutex::new(false), Condvar::new()));
let ready_condition2 = Arc::clone(&ready_condition);

let server_handle = std::thread::spawn(move || {
let (ready_var, ready_cond) = &*ready_condition2;
run_test_server(|context| {
context_configurator(context);
let mut ready_var = ready_var.lock().expect("ready condition mutex is poisoned");
*ready_var = true;
ready_cond.notify_all();
});
});

let (ready_var, ready_cond) = &*ready_condition;
drop(
ready_cond
.wait_while(ready_var.lock().expect("ready condition mutex is poisoned"), |ready| {
!*ready
})
.expect("ready condition mutex is poisoned"),
);
server_handle
}

/// Configures and starts a test server in the current thread.
pub(crate) fn run_test_server<F: FnOnce(&mut CoapContext)>(context_configurator: F) {
let mut context = CoapContext::new().unwrap();
context_configurator(&mut context);
Expand Down
18 changes: 12 additions & 6 deletions libcoap/tests/dtls_client_server_test.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![cfg(feature = "dtls")]
use std::fmt::Debug;
use std::sync::{Arc, Condvar, Mutex};
use std::time::Duration;

use libcoap_rs::crypto::{
Expand All @@ -20,6 +21,13 @@ mod common;
struct DummyCryptoProvider;

impl CoapServerCryptoProvider for DummyCryptoProvider {
fn provide_key_for_identity(
&mut self,
identity: &CoapCryptoPskIdentity,
) -> CoapCryptoProviderResponse<Box<CoapCryptoPskData>> {
CoapCryptoProviderResponse::UseCurrent
}

fn provide_default_info(&mut self) -> CoapCryptoPskInfo {
CoapCryptoPskInfo {
identity: String::from("dtls_test_identity").into_boxed_str().into(),
Expand Down Expand Up @@ -48,11 +56,9 @@ impl CoapClientCryptoProvider for DummyCryptoProvider {
pub fn dtls_client_server_request() {
let server_address = common::get_unused_server_addr();

let server_handle = std::thread::spawn(move || {
common::run_test_server(|context| {
context.set_server_crypto_provider(Some(Box::new(DummyCryptoProvider {})));
context.add_endpoint_dtls(server_address).unwrap();
});
let server_handle = common::spawn_test_server(move |context| {
context.set_server_crypto_provider(Some(Box::new(DummyCryptoProvider {})));
context.add_endpoint_dtls(server_address).unwrap();
});

let mut context = CoapContext::new().unwrap();
Expand All @@ -65,7 +71,7 @@ pub fn dtls_client_server_request() {
for response in session.poll_handle(&req_handle) {
assert_eq!(response.code(), CoapMessageCode::Response(CoapResponseCode::Content));
assert_eq!(response.data().unwrap().as_ref(), "Hello World!".as_bytes());
server_handle.join().unwrap();
server_handle.join().expect("Test server crashed with failure.");
return;
}
}
Expand Down
4 changes: 1 addition & 3 deletions libcoap/tests/udp_client_server_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ mod common;
pub fn basic_client_server_request() {
let server_address = common::get_unused_server_addr();

let server_handle = std::thread::spawn(move || {
common::run_test_server(|context| context.add_endpoint_udp(server_address).unwrap());
});
let server_handle = common::spawn_test_server(move |context| context.add_endpoint_udp(server_address).unwrap());

let mut context = CoapContext::new().unwrap();
let session = CoapClientSession::connect_udp(&mut context, server_address).unwrap();
Expand Down

0 comments on commit 658efa6

Please sign in to comment.