Skip to content

Commit 7539d3c

Browse files
committed
Add channel and no-escape integration tests, LSP protocol tests, and worker_pool example. Run channel/spawn tests under TSan in CI and add a large-codegen compile check.
1 parent c181abc commit 7539d3c

20 files changed

Lines changed: 1485 additions & 0 deletions

.github/workflows/ci.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,44 @@ jobs:
6767
test_array_to_slice_coercion 10
6868
EOF
6969
70+
- name: Generated C thread sanitizer (Linux)
71+
shell: bash
72+
env:
73+
COMPILER: ${{ github.workspace }}/target/release/ion-compiler
74+
CC: gcc
75+
CFLAGS: -fsanitize=thread -fno-omit-frame-pointer
76+
LDFLAGS: -fsanitize=thread
77+
run: |
78+
cd tests
79+
"$CC" $CFLAGS -c ../runtime/ion_runtime.c -I. -I.. -I../runtime -o .ion_test_runtime_tsan.o
80+
while IFS=$'\t' read -r test kind expected _rest; do
81+
[ "$kind" = "run" ] || continue
82+
case "$test" in
83+
test_channel_*|test_spawn_*) ;;
84+
*) continue ;;
85+
esac
86+
[ -f "${test}.ion" ] || continue
87+
"$COMPILER" "${test}.ion" >/dev/null
88+
"$CC" $CFLAGS "${test}.c" .ion_test_runtime_tsan.o -I. -I.. -I../runtime -lpthread $LDFLAGS -o "$test"
89+
set +e
90+
"./$test" >/dev/null
91+
status=$?
92+
set -e
93+
if [ "$status" -ne "$expected" ]; then
94+
echo "$test: expected exit $expected, got $status"
95+
exit 1
96+
fi
97+
rm -f "${test}.c" "$test"
98+
done < <(awk -F '\t' 'NR > 1 && $2 == "run" && ($1 ~ /^test_channel_/ || $1 ~ /^test_spawn_/) { print $1, $2, $3 }' test_expectations.tsv)
99+
100+
- name: Large codegen smoke (Linux)
101+
shell: bash
102+
env:
103+
COMPILER: ${{ github.workspace }}/target/release/ion-compiler
104+
CC: gcc
105+
CFLAGS: -Wall -Wextra -Werror
106+
run: bash tests/large_codegen_smoke.sh
107+
70108
- name: Generated C warning-clean (Linux)
71109
shell: bash
72110
env:

Cargo.lock

Lines changed: 57 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,7 @@ tokio = { version = "1.48.0", features = ["full"] }
2222
toml = "1.1.2"
2323
tower-lsp = "0.20.0"
2424

25+
[dev-dependencies]
26+
tempfile = "3.27.0"
27+
url = "2.5.8"
28+

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,7 @@ On Linux or macOS, use `./target/release/ion-build` and drop `.exe`. Windows cha
180180
| [minimal/](examples/minimal/) | Smallest valid program |
181181
| [spawn_channel/](examples/spawn_channel/) | `spawn` with cross-thread channels |
182182
| [channel_worker/](examples/channel_worker/) | Channel worker |
183+
| [worker_pool/](examples/worker_pool/) | Three workers with per-worker job/result channels |
183184
| [showcase/](examples/showcase/) | Mixed language features |
184185
| [access_log/](examples/access_log/) | Log parsing, spawn, channels, fmt/io |
185186
| [http_server/](examples/http_server/) | Sockets FFI, spawn per client, stdin `quit` to stop; see [http_server/README.md](examples/http_server/README.md) |

examples/worker_pool/ion.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
name = "worker_pool"
2+
main = "worker_pool.ion"
3+
output = "worker_pool"
4+
mode = "single"
5+
out_dir = "target"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Three workers; per-worker job and result channels.
2+
fn worker_count() -> int {
3+
return 3;
4+
}
5+
6+
fn jobs_per_worker() -> int {
7+
return 4;
8+
}
9+
10+
fn main() -> int {
11+
let mut grand_total: int = 0;
12+
let mut w: int = 0;
13+
while w < worker_count() {
14+
let (job_tx, job_rx): (Sender<int>, Receiver<int>) = channel<int>();
15+
let (result_tx, result_rx): (Sender<int>, Receiver<int>) = channel<int>();
16+
17+
spawn {
18+
let mut rx: Receiver<int> = job_rx;
19+
let mut sum: int = 0;
20+
let mut j: int = 0;
21+
while j < jobs_per_worker() {
22+
let job: int = recv(&mut rx);
23+
sum = sum + job;
24+
j = j + 1;
25+
}
26+
send(&result_tx, sum);
27+
};
28+
29+
let mut job_id: int = 1;
30+
while job_id <= jobs_per_worker() {
31+
let payload: int = (w + 1) * 100 + job_id;
32+
send(&job_tx, payload);
33+
job_id = job_id + 1;
34+
}
35+
36+
let mut result_rx_mut: Receiver<int> = result_rx;
37+
let partial: int = recv(&mut result_rx_mut);
38+
grand_total = grand_total + partial;
39+
w = w + 1;
40+
}
41+
42+
if grand_total != 2430 {
43+
return 1;
44+
}
45+
return 0;
46+
}

src/lsp/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
pub mod server;
22
pub mod util;
3+
4+
#[cfg(test)]
5+
mod tests;

0 commit comments

Comments
 (0)