diff --git a/Cargo.toml b/Cargo.toml index 7e036e31..b4f7e75d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ thiserror = "2.0.2" tracing = { version = "0.1" } url = "2.2" walkdir = { version = "2", optional = true } +web-time = { version = "1.1.0" } # Cloud storage support base64 = { version = "0.22", default-features = false, features = ["std"], optional = true } @@ -61,13 +62,19 @@ serde = { version = "1.0", default-features = false, features = ["derive"], opti serde_json = { version = "1.0", default-features = false, features = ["std"], optional = true } serde_urlencoded = { version = "0.7", optional = true } tokio = { version = "1.29.0", features = ["sync", "macros", "rt", "time", "io-util"] } +n0-future = "0.3.2" [target.'cfg(target_family="unix")'.dev-dependencies] nix = { version = "0.31.1", features = ["fs"] } [target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dependencies] -web-time = { version = "1.1.0" } + wasm-bindgen-futures = "0.4.18" +send_wrapper = { version = "0.6", features = ["futures"] } +gloo-timers = { version = "0.3", features = ["futures"] } +chrono = { version = "0.4.34", default-features = false, features = ["clock", "wasmbind"] } + + [features] default = ["fs"] @@ -89,7 +96,7 @@ regex = "1.11.1" # The "gzip" feature for reqwest is enabled for an integration test. reqwest = { version = "0.12", default-features = false, features = ["gzip"] } -[target.'cfg(all(target_arch = "wasm32", target_os = "unknown"))'.dev-dependencies] +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] wasm-bindgen-test = "0.3.50" [dev-dependencies.getrandom_v03] diff --git a/src/attributes.rs b/src/attributes.rs index cac5b36b..4d2bab91 100644 --- a/src/attributes.rs +++ b/src/attributes.rs @@ -197,6 +197,7 @@ impl<'a> Iterator for AttributesIter<'a> { #[cfg(test)] mod tests { use super::*; + use crate::test_macros::test; #[test] fn test_attributes_basic() { diff --git a/src/buffered.rs b/src/buffered.rs index d22ecda5..354c19ae 100644 --- a/src/buffered.rs +++ b/src/buffered.rs @@ -494,7 +494,9 @@ mod tests { use itertools::Itertools; use tokio::io::{AsyncBufReadExt, AsyncReadExt, AsyncSeekExt, AsyncWriteExt}; - #[tokio::test] + use crate::test_macros::*; + + #[async_test] async fn test_buf_reader() { let store = Arc::new(InMemory::new()) as Arc; @@ -574,7 +576,7 @@ mod tests { } // Note: `BufWriter::with_tags` functionality is tested in `crate::tests::tagging` - #[tokio::test] + #[async_test] async fn test_buf_writer() { let store = Arc::new(InMemory::new()) as Arc; let path = Path::from("file.txt"); @@ -612,7 +614,7 @@ mod tests { assert_eq!(response.attributes, attributes); } - #[tokio::test] + #[async_test] async fn test_buf_writer_with_put() { let store = Arc::new(InMemory::new()) as Arc; let path = Path::from("file.txt"); diff --git a/src/chunked.rs b/src/chunked.rs index b362366d..3fc5e0fd 100644 --- a/src/chunked.rs +++ b/src/chunked.rs @@ -182,10 +182,11 @@ mod tests { use crate::local::LocalFileSystem; use crate::memory::InMemory; use crate::path::Path; + use crate::test_macros::*; use super::*; - #[tokio::test] + #[async_test] async fn test_chunked_basic() { let location = Path::parse("test").unwrap(); let store: Arc = Arc::new(InMemory::new()); diff --git a/src/client/backoff.rs b/src/client/backoff.rs index e1160d60..35f8f7d7 100644 --- a/src/client/backoff.rs +++ b/src/client/backoff.rs @@ -110,6 +110,7 @@ impl Backoff { #[cfg(test)] mod tests { use super::*; + use crate::test_macros::test; use rand::rand_core::impls::fill_bytes_via_next; struct FixedRng(u64); diff --git a/src/client/builder.rs b/src/client/builder.rs index f74c5ec1..29f48d82 100644 --- a/src/client/builder.rs +++ b/src/client/builder.rs @@ -272,6 +272,7 @@ where #[cfg(test)] mod tests { use super::*; + use crate::test_macros::test; #[test] fn test_add_query_pairs() { diff --git a/src/client/get.rs b/src/client/get.rs index 5a5ec370..48f879d3 100644 --- a/src/client/get.rs +++ b/src/client/get.rs @@ -222,7 +222,7 @@ impl GetContext { sleep.as_secs_f32() ); - tokio::time::sleep(sleep).await; + crate::util::sleep(sleep).await; let options = GetOptions { range: Some(GetRange::Bounded(range.clone())), @@ -372,6 +372,7 @@ fn get_attributes( #[cfg(test)] mod tests { use super::*; + use crate::test_macros::{async_test, test}; use http::header::*; fn make_response( @@ -407,7 +408,7 @@ mod tests { user_defined_metadata_prefix: Some("x-test-meta-"), }; - #[tokio::test] + #[async_test] async fn test_get_range_meta() { let path = Path::from("test"); diff --git a/src/client/mod.rs b/src/client/mod.rs index fcc2a089..37938293 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -989,6 +989,7 @@ pub(crate) use cloud::*; #[cfg(test)] mod tests { use super::*; + use crate::test_macros::test; use std::collections::HashMap; #[test] diff --git a/src/client/retry.rs b/src/client/retry.rs index 5437896f..cbbecf27 100644 --- a/src/client/retry.rs +++ b/src/client/retry.rs @@ -386,7 +386,7 @@ impl RetryableRequest { ctx.retries, ctx.max_retries, ); - tokio::time::sleep(sleep).await; + crate::util::sleep(sleep).await; } } else if status == StatusCode::NOT_MODIFIED { return Err(self.err(RequestError::Status { status, body: None }, ctx)); @@ -431,7 +431,7 @@ impl RetryableRequest { ctx.retries, ctx.max_retries, ); - tokio::time::sleep(sleep).await; + crate::util::sleep(sleep).await; } } Err(e) => { @@ -457,7 +457,7 @@ impl RetryableRequest { ctx.max_retries, e, ); - tokio::time::sleep(sleep).await; + crate::util::sleep(sleep).await; } } } @@ -749,14 +749,14 @@ mod tests { // Retries on client timeout mock.push_async_fn(|_| async move { - tokio::time::sleep(Duration::from_secs(10)).await; + crate::util::sleep(Duration::from_secs(10)).await; panic!() }); do_request().await.unwrap(); // Does not retry PUT request mock.push_async_fn(|_| async move { - tokio::time::sleep(Duration::from_secs(10)).await; + crate::util::sleep(Duration::from_secs(10)).await; panic!() }); let res = client.request(Method::PUT, mock.url()).send_retry(&retry); diff --git a/src/client/token.rs b/src/client/token.rs index 81ffc110..71cef4cb 100644 --- a/src/client/token.rs +++ b/src/client/token.rs @@ -16,8 +16,8 @@ // under the License. use std::future::Future; -use std::time::{Duration, Instant}; use tokio::sync::Mutex; +use web_time::{Duration, Instant}; /// A temporary authentication token with an associated expiry #[derive(Debug, Clone)] @@ -91,6 +91,7 @@ impl TokenCache { #[cfg(test)] mod test { use crate::client::token::{TemporaryToken, TokenCache}; + use crate::test_macros::async_test; use std::sync::atomic::{AtomicU32, Ordering}; use std::time::{Duration, Instant}; @@ -102,7 +103,7 @@ mod test { } } - #[tokio::test] + #[async_test] async fn test_expired_token_is_refreshed() { let cache = TokenCache::default(); static COUNTER: AtomicU32 = AtomicU32::new(0); @@ -116,14 +117,14 @@ mod test { let _ = cache.get_or_insert_with(get_token).await.unwrap(); assert_eq!(COUNTER.load(Ordering::SeqCst), 1); - tokio::time::sleep(Duration::from_millis(2)).await; + crate::util::sleep(Duration::from_millis(2)).await; // Token is expired, so should fetch again let _ = cache.get_or_insert_with(get_token).await.unwrap(); assert_eq!(COUNTER.load(Ordering::SeqCst), 2); } - #[tokio::test] + #[async_test] async fn test_min_ttl_causes_refresh() { let cache = TokenCache { cache: Default::default(), @@ -146,7 +147,7 @@ mod test { let _ = cache.get_or_insert_with(get_token).await.unwrap(); assert_eq!(COUNTER.load(Ordering::SeqCst), 1); - tokio::time::sleep(Duration::from_millis(2)).await; + crate::util::sleep(Duration::from_millis(2)).await; // Should fetch, since we've passed fetch_backoff let _ = cache.get_or_insert_with(get_token).await.unwrap(); diff --git a/src/config.rs b/src/config.rs index 29a389d4..7871b822 100644 --- a/src/config.rs +++ b/src/config.rs @@ -131,6 +131,7 @@ pub(crate) fn fmt_duration(duration: &ConfigValue) -> String { #[cfg(test)] mod tests { use super::*; + use crate::test_macros::test; use std::time::Duration; #[test] diff --git a/src/delimited.rs b/src/delimited.rs index 0994b4f2..c588cdfa 100644 --- a/src/delimited.rs +++ b/src/delimited.rs @@ -184,6 +184,7 @@ where #[cfg(test)] mod tests { + use crate::test_macros::{async_test, test}; use futures::stream::{BoxStream, TryStreamExt}; use super::*; @@ -228,7 +229,7 @@ mod tests { assert!(delimiter.next().is_none()); } - #[tokio::test] + #[async_test] async fn test_delimiter_stream() { let input = vec!["hello\nworld\nbin", "go\ncup", "cakes"]; let input_stream = futures::stream::iter(input.into_iter().map(|s| Ok(Bytes::from(s)))); @@ -244,7 +245,7 @@ mod tests { ] ) } - #[tokio::test] + #[async_test] async fn test_delimiter_unfold_stream() { let input_stream: BoxStream<'static, Result> = futures::stream::unfold( VecDeque::from(["hello\nworld\nbin", "go\ncup", "cakes"]), diff --git a/src/lib.rs b/src/lib.rs index 54d51dd0..16b91521 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2036,6 +2036,7 @@ pub enum Error { source: path::Error, }, + #[cfg(not(target_arch = "wasm32"))] /// Error when `tokio::spawn` failed #[error("Error joining spawned task: {}", source)] JoinError { @@ -2044,6 +2045,15 @@ pub enum Error { source: tokio::task::JoinError, }, + #[cfg(target_arch = "wasm32")] + /// Error when `tokio::spawn` failed + #[error("Error joining spawned task: {}", source)] + JoinError { + /// The wrapped error + #[from] + source: n0_future::task::JoinError, + }, + /// Error when the attempted operation is not supported #[error("Operation not supported: {}", source)] NotSupported { @@ -2138,9 +2148,26 @@ impl From for std::io::Error { } } +/// Configure the test macro to use +#[cfg(test)] +pub mod test_macros { + #[cfg(not(target_arch = "wasm32"))] + pub use test; + + #[cfg(target_arch = "wasm32")] + pub use wasm_bindgen_test::wasm_bindgen_test as test; + + #[cfg(not(target_arch = "wasm32"))] + pub use tokio::test as async_test; + + #[cfg(target_arch = "wasm32")] + pub use wasm_bindgen_test::wasm_bindgen_test as async_test; +} + #[cfg(test)] mod tests { use super::*; + use crate::test_macros::{async_test, test}; use chrono::TimeZone; @@ -2267,7 +2294,7 @@ mod tests { } } - #[tokio::test] + #[async_test] async fn test_list_lifetimes() { let store = memory::InMemory::new(); let mut stream = list_store(&store, "path"); diff --git a/src/limit.rs b/src/limit.rs index 30fe2b65..5bd6c138 100644 --- a/src/limit.rs +++ b/src/limit.rs @@ -247,10 +247,10 @@ mod tests { use crate::memory::InMemory; use futures::stream::StreamExt; use std::pin::Pin; - use std::time::Duration; - use tokio::time::timeout; - #[tokio::test] + use crate::test_macros::*; + + #[async_test] async fn limit_test() { let max_requests = 10; let memory = InMemory::new(); @@ -270,11 +270,14 @@ mod tests { streams.push(stream); } - let t = Duration::from_millis(20); - // Expect to not be able to make another request - let fut = integration.list(None).collect::>(); - assert!(timeout(t, fut).await.is_err()); + #[cfg(not(target_arch = "wasm32"))] + { + // tokio timeout will panic on WASM + let t = std::time::Duration::from_millis(20); + let fut = integration.list(None).collect::>(); + assert!(tokio::time::timeout(t, fut).await.is_err()); + } // Drop one of the streams streams.pop(); diff --git a/src/memory.rs b/src/memory.rs index f026907d..0f50d453 100644 --- a/src/memory.rs +++ b/src/memory.rs @@ -539,11 +539,13 @@ impl MultipartUpload for InMemoryUpload { #[cfg(test)] mod tests { + use crate::test_macros::*; + use crate::{ObjectStoreExt, integration::*}; use super::*; - #[tokio::test] + #[async_test] async fn in_memory_test() { let integration = InMemory::new(); @@ -559,7 +561,7 @@ mod tests { put_get_attributes(&integration).await; } - #[tokio::test] + #[async_test] async fn box_test() { let integration: Box = Box::new(InMemory::new()); @@ -572,7 +574,7 @@ mod tests { stream_get(&integration).await; } - #[tokio::test] + #[async_test] async fn arc_test() { let integration: Arc = Arc::new(InMemory::new()); @@ -585,7 +587,7 @@ mod tests { stream_get(&integration).await; } - #[tokio::test] + #[async_test] async fn unknown_length() { let integration = InMemory::new(); @@ -610,7 +612,7 @@ mod tests { const NON_EXISTENT_NAME: &str = "nonexistentname"; - #[tokio::test] + #[async_test] async fn nonexistent_location() { let integration = InMemory::new(); diff --git a/src/parse.rs b/src/parse.rs index 7ac31100..6ee656e4 100644 --- a/src/parse.rs +++ b/src/parse.rs @@ -241,6 +241,7 @@ where #[cfg(test)] mod tests { use super::*; + use crate::test_macros::test; #[test] fn test_parse() { @@ -415,6 +416,7 @@ mod tests { } } + #[cfg(all(feature = "fs", not(target_arch = "wasm32")))] #[test] fn test_url_spaces() { let url = Url::parse("file:///my file with spaces").unwrap(); diff --git a/src/path/mod.rs b/src/path/mod.rs index e8618db2..ca5353e8 100644 --- a/src/path/mod.rs +++ b/src/path/mod.rs @@ -465,6 +465,7 @@ pub(crate) fn absolute_path_to_url(path: impl AsRef) -> Result< #[cfg(test)] mod tests { use super::*; + use crate::test_macros::test; #[test] fn delimiter_char_is_forward_slash() { diff --git a/src/path/parts.rs b/src/path/parts.rs index 5628d3f4..7491d3b0 100644 --- a/src/path/parts.rs +++ b/src/path/parts.rs @@ -168,6 +168,7 @@ impl<'a> DoubleEndedIterator for PathParts<'a> { #[cfg(test)] mod tests { use super::*; + use crate::test_macros::test; #[test] fn path_part_delimiter_gets_encoded() { diff --git a/src/payload.rs b/src/payload.rs index 055336b6..26633e49 100644 --- a/src/payload.rs +++ b/src/payload.rs @@ -280,6 +280,7 @@ impl From for PutPayload { #[cfg(test)] mod test { use crate::PutPayloadMut; + use crate::test_macros::test; #[test] fn test_put_payload() { diff --git a/src/registry.rs b/src/registry.rs index 47948425..6876e303 100644 --- a/src/registry.rs +++ b/src/registry.rs @@ -17,8 +17,8 @@ //! Map object URLs to [`ObjectStore`] +use crate::ObjectStore; use crate::path::{InvalidPart, Path, PathPart}; -use crate::{ObjectStore, parse_url_opts}; use parking_lot::RwLock; use std::collections::HashMap; use std::sync::Arc; @@ -107,7 +107,7 @@ impl From for crate::Error { } } -/// An [`ObjectStoreRegistry`] that uses [`parse_url_opts`] to create stores based on the environment +/// An [`ObjectStoreRegistry`] that uses [`crate::parse_url_opts`] to create stores based on the environment #[derive(Debug, Default)] pub struct DefaultObjectStoreRegistry { /// Mapping from [`url_key`] to [`PathEntry`] @@ -196,7 +196,14 @@ impl ObjectStoreRegistry for DefaultObjectStoreRegistry { } } - if let Ok((store, path)) = parse_url_opts(to_resolve, std::env::vars()) { + #[cfg(not(target_arch = "wasm32"))] + let parsed = crate::parse_url_opts(to_resolve, std::env::vars()); + + // std::env::vars isn't available on WASM + #[cfg(target_arch = "wasm32")] + let parsed = crate::parse_url(to_resolve); + + if let Ok((store, path)) = parsed { let depth = num_segments(to_resolve.path()) - num_segments(path.as_ref()); let mut map = self.map.write(); @@ -246,6 +253,7 @@ mod tests { use super::*; use crate::memory::InMemory; use crate::prefix::PrefixStore; + use crate::test_macros::test; #[test] fn test_num_segments() { diff --git a/src/tags.rs b/src/tags.rs index fa6e5913..4a93de6a 100644 --- a/src/tags.rs +++ b/src/tags.rs @@ -46,6 +46,7 @@ impl TagSet { #[cfg(test)] mod tests { use super::*; + use crate::test_macros::test; #[test] fn test_tag_set() { diff --git a/src/throttle.rs b/src/throttle.rs index 1fc90d7e..a33e8e62 100644 --- a/src/throttle.rs +++ b/src/throttle.rs @@ -21,6 +21,7 @@ use std::ops::Range; use std::{convert::TryInto, sync::Arc}; use crate::multipart::{MultipartStore, PartId}; +use crate::util::sleep; use crate::{CopyOptions, GetOptions, RenameOptions, UploadPart}; use crate::{ GetResult, GetResultPayload, ListResult, MultipartId, MultipartUpload, ObjectMeta, ObjectStore, @@ -100,13 +101,6 @@ pub struct ThrottleConfig { pub wait_put_per_call: Duration, } -/// Sleep only if non-zero duration -async fn sleep(duration: Duration) { - if !duration.is_zero() { - tokio::time::sleep(duration).await - } -} - /// Store wrapper that wraps an inner store with some `sleep` calls. /// /// This can be used for performance testing. @@ -369,8 +363,9 @@ mod tests { use crate::ObjectStoreExt; use crate::{integration::*, memory::InMemory}; use futures::TryStreamExt; - use tokio::time::Duration; - use tokio::time::Instant; + use web_time::{Duration, Instant}; + + use crate::test_macros::*; const WAIT_TIME: Duration = Duration::from_millis(100); const ZERO: Duration = Duration::from_millis(0); // Duration::default isn't constant @@ -388,7 +383,7 @@ mod tests { }; } - #[tokio::test] + #[async_test] async fn throttle_test() { let inner = InMemory::new(); let store = ThrottledStore::new(inner, ThrottleConfig::default()); @@ -402,7 +397,7 @@ mod tests { multipart(&store, &store).await; } - #[tokio::test] + #[async_test] async fn delete_test() { let inner = InMemory::new(); let store = ThrottledStore::new(inner, ThrottleConfig::default()); @@ -417,9 +412,9 @@ mod tests { assert_bounds!(measure_delete(&store, Some(10)).await, 1); } - #[tokio::test] + #[async_test] // macos github runner is so slow it can't complete within WAIT_TIME*2 - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_arch = "wasm32"))] async fn delete_stream_test() { let inner = InMemory::new(); let store = ThrottledStore::new(inner, ThrottleConfig::default()); @@ -432,9 +427,9 @@ mod tests { assert_bounds!(measure_delete_stream(&store, 10).await, 10); } - #[tokio::test] + #[async_test] // macos github runner is so slow it can't complete within WAIT_TIME*2 - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_arch = "wasm32"))] async fn get_test() { let inner = InMemory::new(); let store = ThrottledStore::new(inner, ThrottleConfig::default()); @@ -461,9 +456,7 @@ mod tests { assert_bounds!(measure_get(&store, Some(2)).await, 3); } - #[tokio::test] - // macos github runner is so slow it can't complete within WAIT_TIME*2 - #[cfg(target_os = "linux")] + #[async_test] async fn list_test() { let inner = InMemory::new(); let store = ThrottledStore::new(inner, ThrottleConfig::default()); @@ -488,9 +481,7 @@ mod tests { assert_bounds!(measure_list(&store, 2).await, 3); } - #[tokio::test] - // macos github runner is so slow it can't complete within WAIT_TIME*2 - #[cfg(target_os = "linux")] + #[async_test] async fn list_with_delimiter_test() { let inner = InMemory::new(); let store = ThrottledStore::new(inner, ThrottleConfig::default()); @@ -515,7 +506,7 @@ mod tests { assert_bounds!(measure_list_with_delimiter(&store, 2).await, 3); } - #[tokio::test] + #[async_test] async fn put_test() { let inner = InMemory::new(); let store = ThrottledStore::new(inner, ThrottleConfig::default()); @@ -595,7 +586,7 @@ mod tests { } #[allow(dead_code)] - #[cfg(target_os = "linux")] + #[cfg(any(target_os = "linux", target_arch = "wasm32"))] async fn measure_get(store: &ThrottledStore, n_bytes: Option) -> Duration { let path = place_test_object(store, n_bytes).await; @@ -605,6 +596,7 @@ mod tests { // need to consume bytes to provoke sleep times let s = match res.unwrap().payload { GetResultPayload::Stream(s) => s, + #[cfg(all(feature = "fs", not(target_arch = "wasm32")))] GetResultPayload::File(_, _) => unimplemented!(), }; diff --git a/src/upload.rs b/src/upload.rs index 33698a46..eab87a73 100644 --- a/src/upload.rs +++ b/src/upload.rs @@ -22,7 +22,7 @@ use async_trait::async_trait; use bytes::Bytes; use futures::future::BoxFuture; use futures::ready; -use tokio::task::JoinSet; +use n0_future::task::JoinSet; /// An upload part request pub type UploadPart = BoxFuture<'static, Result<()>>; @@ -255,7 +255,9 @@ mod tests { use super::*; - #[tokio::test] + use crate::test_macros::*; + + #[async_test] async fn test_concurrency() { let config = ThrottleConfig { wait_put_per_call: Duration::from_millis(1), @@ -298,7 +300,7 @@ mod tests { } } - #[tokio::test] + #[async_test] async fn test_write_multipart() { let mut rng = StdRng::seed_from_u64(42); diff --git a/src/util.rs b/src/util.rs index b7f9182c..eb7f742e 100644 --- a/src/util.rs +++ b/src/util.rs @@ -16,6 +16,7 @@ // under the License. //! Common logic for interacting with remote object stores +use std::time::Duration; use std::{ fmt::Display, ops::{Range, RangeBounds}, @@ -326,6 +327,23 @@ pub(crate) fn hex_encode(bytes: &[u8]) -> String { out } +/// Sleep only if non-zero duration +#[cfg(not(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none"))))] +pub(crate) async fn sleep(duration: Duration) { + if !duration.is_zero() { + tokio::time::sleep(duration).await + } +} + +/// Sleep only if non-zero duration +#[cfg(all(target_arch = "wasm32", any(target_os = "unknown", target_os = "none")))] +pub(crate) async fn sleep(duration: Duration) { + use send_wrapper::SendWrapper; + if !duration.is_zero() { + SendWrapper::new(gloo_timers::future::sleep(duration)).await + } +} + #[cfg(test)] mod tests { use crate::Error; @@ -334,6 +352,8 @@ mod tests { use rand::{Rng, rng}; use std::ops::Range; + use crate::test_macros::{async_test, test}; + /// Calls coalesce_ranges and validates the returned data is correct /// /// Returns the fetched ranges @@ -365,7 +385,7 @@ mod tests { fetches } - #[tokio::test] + #[async_test] async fn test_coalesce_ranges() { let fetches = do_fetch(vec![], 0).await; assert!(fetches.is_empty()); @@ -395,7 +415,7 @@ mod tests { assert_eq!(fetches, vec![0..1, 6..14]); } - #[tokio::test] + #[async_test] async fn test_coalesce_fuzz() { let mut rand = rng(); for _ in 0..100 { diff --git a/tests/get_range_file.rs b/tests/get_range_file.rs index 95027eb2..2ad25864 100644 --- a/tests/get_range_file.rs +++ b/tests/get_range_file.rs @@ -16,6 +16,7 @@ // under the License. //! Tests the default implementation of get_range handles GetResult::File correctly (#4350) +#![cfg(all(feature = "fs", not(target_arch = "wasm32")))] use async_trait::async_trait; use bytes::Bytes; diff --git a/tests/http.rs b/tests/http.rs index f23ef74f..9a210a7b 100644 --- a/tests/http.rs +++ b/tests/http.rs @@ -20,12 +20,17 @@ #[cfg(feature = "http")] use object_store::{GetOptions, GetRange, ObjectStore, http::HttpBuilder, path::Path}; -#[cfg(all(feature = "http", target_arch = "wasm32", target_os = "unknown"))] -use wasm_bindgen_test::*; +#[cfg(feature = "http")] +#[cfg(not(target_arch = "wasm32"))] +use tokio::test as async_test; + +#[cfg(feature = "http")] +#[cfg(target_arch = "wasm32")] +use wasm_bindgen_test::wasm_bindgen_test as async_test; /// Tests that even when reqwest has the `gzip` feature enabled, the HTTP store /// does not error on a missing `Content-Length` header. -#[tokio::test] +#[async_test] #[cfg(feature = "http")] async fn test_http_store_gzip() { let http_store = HttpBuilder::new() @@ -41,20 +46,3 @@ async fn test_http_store_gzip() { .await .unwrap(); } - -#[cfg(all(feature = "http", target_arch = "wasm32", target_os = "unknown"))] -#[wasm_bindgen_test] -async fn basic_wasm_get() { - let http_store = HttpBuilder::new() - .with_url("https://raw.githubusercontent.com/apache/arrow-rs/refs/heads/main") - .build() - .unwrap(); - - let _ = http_store - .get_opts( - &Path::parse("LICENSE.txt").unwrap(), - GetOptions::new().with_range(Some(GetRange::Bounded(0..100))), - ) - .await - .unwrap(); -}