Skip to content

Commit

Permalink
Refactor testing (#210)
Browse files Browse the repository at this point in the history
* Overhaul testing.
  • Loading branch information
wmedrano authored Sep 14, 2024
1 parent ecfc3ef commit 8dcc07d
Show file tree
Hide file tree
Showing 38 changed files with 722 additions and 2,075 deletions.
4 changes: 2 additions & 2 deletions .config/nextest.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[profile.default]
test-threads = 1
fail-fast = false
slow-timeout = { period = "30s", terminate-after = 4 }
retries = { backoff = "fixed", count = 2, delay = "1s" }
slow-timeout = { period = "2s", terminate-after = 2 }
retries = { backoff = "fixed", count = 3, delay = "1s" }
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ libc = "0.2"
log = { version = "0.4", optional = true}

[dev-dependencies]
approx = "0.5"
crossbeam-channel = "0.5"
ctor = "0.2"

[features]
default = ["dynamic_loading", "log"]
dynamic_loading = ["jack-sys/dynamic_loading"]
dynamic_loading = ["jack-sys/dynamic_loading"]
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ Rust bindings for [JACK Audio Connection Kit](<https://jackaudio.org>).

The JACK server is usually started by the user or system. Clients can request
that the JACK server is started on demand when they connect, but this can be
disabled by creating a client with the `NO_START_SERVER` option.
disabled by creating a client with the `NO_START_SERVER` option or
`ClientOptions::default()`.

- Linux and BSD users may install JACK1, JACK2 (preferred for low latency), or
Pipewire JACK (preferred for ease of use) from their system package manager.
Expand Down
4 changes: 2 additions & 2 deletions docs/contrib/closure_callbacks.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contains captures the required state and then activating it.
```rust
// 1. Create the client.
let (client, _status) =
jack::Client::new("silence", jack::ClientOptions::NO_START_SERVER).unwrap();
jack::Client::new("silence", jack::ClientOptions::default()).unwrap();

// 2. Define the state.
let mut output = client.register_port("out", jack::AudioOut::default());
Expand All @@ -45,7 +45,7 @@ buffer size.
```rust
// 1. Create the client.
let (client, _status) =
jack::Client::new("silence", jack::ClientOptions::NO_START_SERVER).unwrap();
jack::Client::new("silence", jack::ClientOptions::default()).unwrap();

// 2. Define the state.
struct State {
Expand Down
7 changes: 0 additions & 7 deletions docs/features.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,3 @@ Default: Yes
Load `libjack` at runtime as opposed to the standard dynamic linking. This is
preferred as it allows `pw-jack` to intercept the loading at runtime to provide
the Pipewire JACK server implementation.

## `metadata`

Default: No

Provides access to the metadata API. This is experimental. Details on the JACK
metadata API can be found at <https://jackaudio.org/metadata/>.
7 changes: 4 additions & 3 deletions docs/logging.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,16 @@ enabled by default. The `log` crate provides a *facade* for logging; it provides
macros to perform logging, but another mechanism or crate is required to
actually perform the logging.

In the example below, we use the [`env_logger` crate]() to display logging for
info and error severity level messages.
In the example below, we use the [`env_logger`
crate](https://crates.io/crates/env_logger) to display logging for info and
error severity level messages.

```rust
env_logger::builder().filter(None, log::LevelFilter::Info).init();

// JACK may log things to `info!` or `error!`.
let (client, _status) =
jack::Client::new("rust_jack_simple", jack::ClientOptions::NO_START_SERVER).unwrap();
jack::Client::new("rust_jack_simple", jack::ClientOptions::default()).unwrap();
```


Expand Down
2 changes: 1 addition & 1 deletion docs/quickstart.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ program that can take inputs and forward them to outputs.
fn main() {
// 1. Create client
let (client, _status) =
jack::Client::new("rust_jack_simple", jack::ClientOptions::NO_START_SERVER).unwrap();
jack::Client::new("rust_jack_simple", jack::ClientOptions::default()).unwrap();

// 2. Register ports. They will be used in a callback that will be
// called when new data is available.
Expand Down
2 changes: 1 addition & 1 deletion examples/internal_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fn main() {
// Create client
let (client, _status) = jack::Client::new(
"rust_jack_internal_client_tester",
jack::ClientOptions::NO_START_SERVER,
jack::ClientOptions::default(),
)
.unwrap();

Expand Down
2 changes: 1 addition & 1 deletion examples/playback_capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ fn main() {
// Create client
jack::set_logger(jack::LoggerType::Stdio);
let (client, _status) =
jack::Client::new("rust_jack_simple", jack::ClientOptions::NO_START_SERVER).unwrap();
jack::Client::new("rust_jack_simple", jack::ClientOptions::default()).unwrap();

// Register ports. They will be used in a callback that will be
// called when new data is available.
Expand Down
2 changes: 1 addition & 1 deletion examples/set_transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::env;

fn main() {
let (client, _status) =
jack::Client::new("rust_jack_trans", jack::ClientOptions::NO_START_SERVER).unwrap();
jack::Client::new("rust_jack_trans", jack::ClientOptions::default()).unwrap();

let transport = client.transport();

Expand Down
6 changes: 3 additions & 3 deletions examples/show_midi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ impl std::fmt::Debug for MidiCopy {
fn main() {
// Open the client.
let (client, _status) =
jack::Client::new("rust_jack_show_midi", jack::ClientOptions::NO_START_SERVER).unwrap();
jack::Client::new("rust_jack_show_midi", jack::ClientOptions::default()).unwrap();

// Create a sync channel to send back copies of midi messages we get.
let (sender, receiver) = sync_channel(64);

// Define process logic.
let mut maker = client
.register_port("rust_midi_maker", jack::MidiOut)
.register_port("rust_midi_maker", jack::MidiOut::default())
.unwrap();
let shower = client
.register_port("rust_midi_shower", jack::MidiIn)
.register_port("rust_midi_shower", jack::MidiIn::default())
.unwrap();
let cback = move |_: &jack::Client, ps: &jack::ProcessScope| -> jack::Control {
let show_p = shower.iter(ps);
Expand Down
2 changes: 1 addition & 1 deletion examples/show_transport.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::sync::{
fn main() {
// Create client
let (client, _status) =
jack::Client::new("rust_jack_trans", jack::ClientOptions::NO_START_SERVER).unwrap();
jack::Client::new("rust_jack_trans", jack::ClientOptions::default()).unwrap();

let transport = client.transport();
let stop = Arc::new(AtomicBool::new(false));
Expand Down
2 changes: 1 addition & 1 deletion examples/sine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::str::FromStr;
fn main() {
// 1. open a client
let (client, _status) =
jack::Client::new("rust_jack_sine", jack::ClientOptions::NO_START_SERVER).unwrap();
jack::Client::new("rust_jack_sine", jack::ClientOptions::default()).unwrap();

// 2. register port
let out_port = client
Expand Down
30 changes: 11 additions & 19 deletions src/client/async_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::sync::atomic::AtomicBool;
use super::callbacks::clear_callbacks;
use super::callbacks::{CallbackContext, NotificationHandler, ProcessHandler};
use crate::client::client_impl::Client;
use crate::client::common::{sleep_on_test, CREATE_OR_DESTROY_CLIENT_MUTEX};
use crate::client::common::CREATE_OR_DESTROY_CLIENT_MUTEX;
use crate::Error;

/// A JACK client that is processing data asynchronously, in real-time.
Expand All @@ -20,7 +20,7 @@ use crate::Error;
/// ```
/// // Create a client and a handler
/// let (client, _status) =
/// jack::Client::new("my_client", jack::ClientOptions::NO_START_SERVER).unwrap();
/// jack::Client::new("my_client", jack::ClientOptions::default()).unwrap();
/// let process_handler = jack::contrib::ClosureProcessHandler::new(
/// move |_: &jack::Client, _: &jack::ProcessScope| jack::Control::Continue,
/// );
Expand Down Expand Up @@ -56,19 +56,15 @@ where
pub fn new(client: Client, notification_handler: N, process_handler: P) -> Result<Self, Error> {
let _m = CREATE_OR_DESTROY_CLIENT_MUTEX.lock().ok();
unsafe {
sleep_on_test();
let mut callback_context = Box::new(CallbackContext {
client,
notification: notification_handler,
process: process_handler,
is_valid: AtomicBool::new(true),
is_valid_for_callback: AtomicBool::new(true),
has_panic: AtomicBool::new(false),
});
CallbackContext::register_callbacks(&mut callback_context)?;
sleep_on_test();
let res = j::jack_activate(callback_context.client.raw());
for _ in 0..4 {
sleep_on_test();
}
match res {
0 => Ok(AsyncClient {
callback: Some(callback_context),
Expand Down Expand Up @@ -114,25 +110,21 @@ impl<N, P> AsyncClient<N, P> {
return Err(Error::ClientIsNoLongerAlive);
}
let cb = self.callback.take().ok_or(Error::ClientIsNoLongerAlive)?;
let client = cb.client.raw();
let client_ptr = cb.client.raw();

// deactivate
sleep_on_test();
if j::jack_deactivate(client) != 0 {
if j::jack_deactivate(client_ptr) != 0 {
return Err(Error::ClientDeactivationError);
}

// clear the callbacks
sleep_on_test();
clear_callbacks(client)?;
clear_callbacks(client_ptr)?;
// done, take ownership of callback
if cb.is_valid.load(std::sync::atomic::Ordering::Relaxed) {
Ok(cb)
} else {
std::mem::forget(cb.notification);
std::mem::forget(cb.process);
Err(Error::ClientIsNoLongerAlive)
if cb.has_panic.load(std::sync::atomic::Ordering::Relaxed) {
std::mem::forget(cb);
return Err(Error::ClientPanicked);
}
Ok(cb)
}
}

Expand Down
Loading

0 comments on commit 8dcc07d

Please sign in to comment.