Skip to content

Commit

Permalink
Add tests for channel.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ayak32 authored Aug 13, 2024
1 parent 1de1776 commit d4a8691
Show file tree
Hide file tree
Showing 16 changed files with 497 additions and 1 deletion.
43 changes: 43 additions & 0 deletions .github/workflows/actions/build/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,46 @@ runs:
category: task
sub-category: segmented_stack
test-name: return_values
# *** Tests for sync - channel ***

- name: Build test test-sync-channel-produce_consume_single_task
uses: ./.github/workflows/actions/build-test
with:
category: sync
sub-category: channel
test-name: produce_consume_single_task

- name: Build test test-sync-channel-produce_with_overflow
uses: ./.github/workflows/actions/build-test
with:
category: sync
sub-category: channel
test-name: produce_with_overflow

- name: Build test test-sync-channel-try_consume
uses: ./.github/workflows/actions/build-test
with:
category: sync
sub-category: channel
test-name: try_consume

- name: Build test test-sync-channel-multiple_producers
uses: ./.github/workflows/actions/build-test
with:
category: sync
sub-category: channel
test-name: multiple_producers

- name: Build test test-sync-channel-multiple_consumers
uses: ./.github/workflows/actions/build-test
with:
category: sync
sub-category: channel
test-name: multiple_consumers

- name: Build test test-sync-channel-concurrency_and_stress
uses: ./.github/workflows/actions/build-test
with:
category: sync
sub-category: channel
test-name: concurrency_and_stress
95 changes: 95 additions & 0 deletions .github/workflows/channel.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
name: Run Tests for Channel

on:
workflow_call:
secrets:
cookie:
required: true

env:
CARGO_TERM_COLOR: always

jobs:
produce_consume_single_task:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run test produce_consume_single_task
uses: ./.github/workflows/actions/run-test
with:
cookie: ${{ secrets.cookie }}
category: sync
sub-category: channel
test-name: produce_consume_single_task

produce_with_overflow:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run test produce_with_overflow
uses: ./.github/workflows/actions/run-test
with:
cookie: ${{ secrets.cookie }}
category: sync
sub-category: channel
test-name: produce_with_overflow

try_consume:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run test try_consume
uses: ./.github/workflows/actions/run-test
with:
cookie: ${{ secrets.cookie }}
category: sync
sub-category: channel
test-name: try_consume

multiple_producers:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run test multiple_producers
uses: ./.github/workflows/actions/run-test
with:
cookie: ${{ secrets.cookie }}
category: sync
sub-category: channel
test-name: multiple_producers

multiple_consumers:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run test multiple_consumers
uses: ./.github/workflows/actions/run-test
with:
cookie: ${{ secrets.cookie }}
category: sync
sub-category: channel
test-name: multiple_consumers

concurrency_and_stress:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run test concurrency_and_stress
uses: ./.github/workflows/actions/run-test
with:
cookie: ${{ secrets.cookie }}
category: sync
sub-category: channel
test-name: concurrency_and_stress
5 changes: 5 additions & 0 deletions .github/workflows/sync.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ jobs:
uses: ./.github/workflows/mutex.yaml
secrets:
cookie: ${{ secrets.cookie }}

channel:
uses: ./.github/workflows/channel.yaml
secrets:
cookie: ${{ secrets.cookie }}
27 changes: 26 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,37 @@ path = "examples/tests/sync/mutex/priority.rs"
name = "test-sync-mutex-poison"
path = "examples/tests/sync/mutex/poison.rs"

# *** Tests for task - priority ***
# *** Tests for sync - channel ***

[[example]]
name = "test-sync-channel-produce_with_overflow"
path = "examples/tests/sync/channel/produce_with_overflow.rs"

[[example]]
name = "test-sync-channel-try_consume"
path = "examples/tests/sync/channel/try_consume.rs"

[[example]]
name = "test-sync-channel-multiple_producers"
path = "examples/tests/sync/channel/multiple_producers.rs"

[[example]]
name = "test-sync-channel-concurrency_and_stress"
path = "examples/tests/sync/channel/concurrency_and_stress.rs"

[[example]]
name = "test-sync-channel-multiple_consumers"
path = "examples/tests/sync/channel/multiple_consumers.rs"

[[example]]
name = "test-task-priority-reduce_priority"
path = "examples/tests/task/priority/reduce_priority.rs"

# *** Tests for task - priority ***
[[example]]
name = "test-sync-channel-produce_consume_single_task"
path = "examples/tests/sync/channel/produce_consume_single_task.rs"

# *** Tests for task - unwind ***

[[example]]
Expand Down
86 changes: 86 additions & 0 deletions examples/tests/sync/channel/concurrency_and_stress.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
//! Tests the behavior of multiple producer tasks writing to a shared channel
//! (This test is similar to the test "multiple_producers", but includes more tasks and elements produced on the channel)
//! It creates four tasks, each producing a sequence of numbers, and verifies that all numbers are correctly
//! produced and consumed in the expected order.
#![no_main]
#![no_std]

extern crate alloc;
use alloc::vec;
use alloc::vec::Vec;
use core::sync::atomic::{AtomicUsize, Ordering};
use hopter::{boot::main, debug::semihosting, hprintln, sync, sync::Producer, task};

const NUM_TASKS: usize = 4;
const NUM_ITEMS: usize = 3; // Number of items each task will produce
static TASK_COMPLETION_COUNTER: AtomicUsize = AtomicUsize::new(0); // Counter to track task completion

#[main]
fn main(_: cortex_m::Peripherals) {
// Create a channel with a buffering capacity of 16
let (producer, consumer) = sync::create_channel::<usize, 16>();

// Create and spawn 4 producer tasks, each with different priorities and a cloned producer
let mut producer2 = producer.clone();
task::build()
.set_entry(move || fill_channel(&mut producer2, 2))
.set_priority(1)
.spawn()
.unwrap();

let mut producer3 = producer.clone();
task::build()
.set_entry(move || fill_channel(&mut producer3, 3))
.set_priority(2)
.spawn()
.unwrap();

let mut producer4 = producer.clone();
task::build()
.set_entry(move || fill_channel(&mut producer4, 4))
.set_priority(3)
.spawn()
.unwrap();

let mut producer5 = producer.clone();
task::build()
.set_entry(move || fill_channel(&mut producer5, 5))
.set_priority(3)
.spawn()
.unwrap();

// Change the priority of the current task to allow producer tasks to run first
task::change_current_priority(10).unwrap();

// Consume the numbers produced by the tasks, storing them in a vector
let mut results = vec![];
for _ in 0..(NUM_TASKS * NUM_ITEMS) {
results.push(consumer.consume()); // Consume and store each item produced by the tasks
}

// Create a vector of the expected results for comparison
// compare_vec = [6..18]
let compare_vec = (6..(NUM_TASKS * NUM_TASKS + 2)).collect::<Vec<_>>();

// Check if the produced results match the expected sequence
if results != compare_vec {
hprintln!("Test Failed");
semihosting::terminate(false);
}
hprintln!("Test Passed");
semihosting::terminate(true);
}

fn fill_channel(producer: &mut Producer<usize, 16>, task_num: usize) {
// Each task produces a sequence of 3 (NUM_ITEMS) numbers based on its task number
for j in 0..NUM_ITEMS {
// Conditionally yield to add more stress.
if j == task_num {
task::yield_current();
}
producer.produce(task_num * NUM_ITEMS + j);
}

TASK_COMPLETION_COUNTER.fetch_add(1, Ordering::SeqCst);
}
1 change: 1 addition & 0 deletions examples/tests/sync/channel/concurrency_and_stress.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Test Passed
54 changes: 54 additions & 0 deletions examples/tests/sync/channel/multiple_consumers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//! Tests the correct behavior of a multi-consumer, single-producer channel
//! It fills a channel with four elements, spawns two consumer tasks with different priorities to consume the elements,
//! and then checks that the channel is empty after all elements have been consumed.
#![no_main]
#![no_std]

extern crate alloc;
use hopter::{boot::main, debug::semihosting, hprintln, sync, sync::Consumer, task};

#[main]
fn main(_: cortex_m::Peripherals) {
// create a channel with a buffer capacity of 4
let (producer, consumer) = sync::create_channel::<usize, 4>();

// fill channel with 4 elements
producer.produce(1);
producer.produce(2);
producer.produce(3);
producer.produce(4);
// Clone the consumer to allow multiple consumers to pull data from the channel
let mut consumer2 = consumer.clone();
let mut consumer3 = consumer.clone();

// Spawn the first consumer task with priority 1
task::build()
.set_entry(move || consume_function(&mut consumer2))
.set_priority(1)
.spawn()
.unwrap();
// Spawn the second consumer task with priority 2
task::build()
.set_entry(move || consume_function(&mut consumer3))
.set_priority(2)
.spawn()
.unwrap();

// Change the priority of the current task to 10
// This ensures that both consumer tasks run before the final check
task::change_current_priority(10).unwrap();

// Check if the channel is empty after both consumers have finished
if consumer.try_consume_allow_isr() != None {
hprintln!("Channel not empty");
semihosting::terminate(false);
}
hprintln!("Test Passed");
semihosting::terminate(true);
}

fn consume_function(consumer: &mut Consumer<usize, 4>) {
hprintln!("{}", consumer.consume());
hprintln!("{}", consumer.consume());
}
5 changes: 5 additions & 0 deletions examples/tests/sync/channel/multiple_consumers.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
1
2
3
4
Test Passed
Loading

0 comments on commit d4a8691

Please sign in to comment.