Skip to content

Commit a261ae5

Browse files
BerrysoftCopilot
andauthored
ci: address sanitizer for Linux (#814)
* ci: asan on Linux * test(net): cfg out manually leaks * fix(ci): apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * ci(asan): run tests & lib tests only * ci(asan): test more features * test(ws): close after ping --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent e0c9b9d commit a261ae5

4 files changed

Lines changed: 82 additions & 4 deletions

File tree

.github/workflows/ci_test_asan.yml

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
name: TestASan
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
paths:
8+
- '**/*.rs'
9+
- '**/Cargo.toml'
10+
- '.github/workflows/ci_test_asan.yml'
11+
pull_request:
12+
branches:
13+
- master
14+
paths:
15+
- '**/*.rs'
16+
- '**/Cargo.toml'
17+
- '.github/workflows/ci_test_asan.yml'
18+
19+
concurrency:
20+
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
21+
cancel-in-progress: true
22+
23+
env:
24+
RUST_BACKTRACE: 1
25+
26+
jobs:
27+
asan:
28+
runs-on: ${{ matrix.setup.os }}
29+
strategy:
30+
matrix:
31+
setup:
32+
- os: 'ubuntu-22.04'
33+
features: 'io-compat,sync,ring,codec-serde-json'
34+
target: 'x86_64-unknown-linux-gnu'
35+
- os: 'ubuntu-22.04'
36+
features: 'polling,io-compat,sync,ring,codec-serde-json'
37+
target: 'x86_64-unknown-linux-gnu'
38+
- os: 'ubuntu-22.04'
39+
features: 'polling,io-compat,sync,ring,codec-serde-json'
40+
no_default_features: true
41+
target: 'x86_64-unknown-linux-gnu'
42+
steps:
43+
- uses: actions/checkout@v4
44+
- name: Setup nightly toolchain with rust-src
45+
run: rustup toolchain install nightly --component rust-src
46+
- name: Setup target
47+
if: ${{ matrix.setup.target }}
48+
run: rustup +nightly target install ${{ matrix.setup.target }}
49+
- name: Run ASan tests
50+
run: |
51+
set -ex
52+
53+
ARGS=("--features" "all,nightly")
54+
55+
# Add features if features is not empty
56+
if [[ -n "${{ matrix.setup.features }}" ]]; then
57+
ARGS+=("--features" "${{ matrix.setup.features }}")
58+
fi
59+
# Add no-default-features if no_default_features is true
60+
if [[ -n "${{ matrix.setup.no_default_features }}" ]]; then
61+
ARGS+=("--no-default-features")
62+
fi
63+
# Specify target if target is not empty
64+
if [[ -n "${{ matrix.setup.target }}" ]]; then
65+
ARGS+=("--target" "${{ matrix.setup.target }}")
66+
fi
67+
68+
cargo +nightly test --workspace --tests --lib -Zbuild-std "${ARGS[@]}"
69+
env:
70+
RUSTFLAGS: -Zsanitizer=address

compio-net/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ tempfile = { workspace = true }
4646
[features]
4747
# Nightly features
4848
once_cell_try = []
49-
nightly = ["once_cell_try"]
49+
sanitize = []
50+
nightly = ["once_cell_try", "sanitize"]

compio-net/tests/tcp_connect.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![cfg_attr(feature = "sanitize", feature(cfg_sanitize))]
2+
13
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
24

35
use compio_net::{TcpListener, TcpStream, ToSocketAddrsAsync};
@@ -96,9 +98,10 @@ async fn test_connect_impl<A: ToSocketAddrsAsync>(mapping: impl FnOnce(&TcpListe
9698
}
9799

98100
macro_rules! test_connect {
99-
($(($ident:ident, $mapping:tt),)*) => {
101+
($(($(#[$m:meta])* $ident:ident, $mapping:tt),)*) => {
100102
$(
101103
#[compio_macros::test]
104+
$(#[$m])*
102105
async fn $ident() {
103106
#[allow(unused_parens)]
104107
test_connect_impl($mapping).await;
@@ -111,7 +114,7 @@ test_connect! {
111114
(ip_string, (|listener: &TcpListener| {
112115
format!("127.0.0.1:{}", listener.local_addr().unwrap().port())
113116
})),
114-
(ip_str, (|listener: &TcpListener| {
117+
(#[cfg_attr(feature = "sanitize", cfg(not(sanitize = "address")))] ip_str, (|listener: &TcpListener| {
115118
let s = format!("127.0.0.1:{}", listener.local_addr().unwrap().port());
116119
let slice: &str = &*Box::leak(s.into_boxed_str());
117120
slice
@@ -120,7 +123,7 @@ test_connect! {
120123
let addr = listener.local_addr().unwrap();
121124
(addr.ip(), addr.port())
122125
})),
123-
(ip_port_tuple_ref, (|listener: &TcpListener| {
126+
(#[cfg_attr(feature = "sanitize", cfg(not(sanitize = "address")))] ip_port_tuple_ref, (|listener: &TcpListener| {
124127
let addr = listener.local_addr().unwrap();
125128
let tuple_ref: &(IpAddr, u16) = &*Box::leak(Box::new((addr.ip(), addr.port())));
126129
tuple_ref

compio-ws/tests/websocket.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ async fn compat_ping_pong() {
194194

195195
let msg = ws.next().await.unwrap().unwrap();
196196
assert!(matches!(msg, Message::Ping(_)));
197+
ws.close().await.unwrap();
197198
})
198199
.detach();
199200

@@ -211,4 +212,7 @@ async fn compat_ping_pong() {
211212

212213
let response = ws.next().await.unwrap().unwrap();
213214
assert_eq!(response, Message::Pong(ping_data.into()));
215+
216+
let response = ws.next().await.unwrap().unwrap();
217+
assert!(response.is_close());
214218
}

0 commit comments

Comments
 (0)