1#[doc(hidden)]
8pub mod reexport {
9 pub use crate::directory::test_utils::DirentsSameInodeBuilder;
10 pub use fidl_fuchsia_io as fio;
11 pub use futures::stream::StreamExt;
12 pub use zx_status::Status;
13
14 #[cfg(not(target_os = "fuchsia"))]
15 pub use fuchsia_async::emulated_handle::MessageBuf;
16 #[cfg(target_os = "fuchsia")]
17 pub use zx::MessageBuf;
18}
19
20#[macro_export]
31macro_rules! assert_read {
32 ($proxy:expr, $expected:expr) => {{
33 use $crate::test_utils::assertions::reexport::Status;
34
35 let content = $proxy
36 .read($expected.len() as u64)
37 .await
38 .expect("read failed")
39 .map_err(Status::from_raw)
40 .expect("read error");
41
42 assert_eq!(content.as_slice(), $expected.as_bytes());
43 }};
44}
45
46#[macro_export]
48macro_rules! assert_read_err {
49 ($proxy:expr, $expected_status:expr) => {{
50 use $crate::test_utils::assertions::reexport::Status;
51
52 let result = $proxy.read(100).await.expect("read failed").map_err(Status::from_raw);
53
54 assert_eq!(result, Err($expected_status));
55 }};
56}
57
58#[macro_export]
60macro_rules! assert_read_fidl_err_closed {
61 ($proxy:expr) => {{
62 match $proxy.read(100).await {
63 Err(error) if error.is_closed() => (),
64 Err(error) => panic!("read() returned unexpected error: {:?}", error),
65 Ok(result) => {
66 panic!("Read succeeded: {:?}", result)
67 }
68 }
69 }};
70}
71
72#[macro_export]
74macro_rules! assert_read_at {
75 ($proxy:expr, $offset:expr, $expected:expr) => {{
76 use $crate::test_utils::assertions::reexport::Status;
77
78 let content = $proxy
79 .read_at($expected.len() as u64, $offset)
80 .await
81 .expect("read failed")
82 .map_err(Status::from_raw)
83 .expect("read error");
84
85 assert_eq!(content.as_slice(), $expected.as_bytes());
86 }};
87}
88
89#[macro_export]
91macro_rules! assert_read_at_err {
92 ($proxy:expr, $offset:expr, $expected_status:expr) => {{
93 use $crate::test_utils::assertions::reexport::Status;
94
95 let result =
96 $proxy.read_at(100, $offset).await.expect("read failed").map_err(Status::from_raw);
97
98 assert_eq!(result, Err($expected_status));
99 }};
100}
101
102#[macro_export]
104macro_rules! assert_write {
105 ($proxy:expr, $content:expr) => {{
106 use $crate::test_utils::assertions::reexport::Status;
107
108 let len_written = $proxy
109 .write($content.as_bytes())
110 .await
111 .expect("write failed")
112 .map_err(Status::from_raw)
113 .expect("write error");
114
115 assert_eq!(len_written, $content.len() as u64);
116 }};
117}
118
119#[macro_export]
121macro_rules! assert_write_err {
122 ($proxy:expr, $content:expr, $expected_status:expr) => {{
123 use $crate::test_utils::assertions::reexport::Status;
124
125 let result = $proxy
126 .write($content.as_bytes())
127 .await
128 .expect("write failed")
129 .map_err(Status::from_raw);
130
131 assert_eq!(result, Err($expected_status));
132 }};
133}
134
135#[macro_export]
137macro_rules! assert_write_fidl_err_closed {
138 ($proxy:expr, $content:expr) => {
139 match $proxy.write($content.as_bytes()).await {
140 Err(error) if error.is_closed() => (),
141 Err(error) => panic!("write() returned unexpected error: {:?}", error),
142 Ok(result) => {
143 panic!("Write succeeded: {:?}", result)
144 }
145 }
146 };
147}
148
149#[macro_export]
151macro_rules! assert_write_at {
152 ($proxy:expr, $offset:expr, $content:expr) => {{
153 use $crate::test_utils::assertions::reexport::Status;
154
155 let len_written = $proxy
156 .write_at($content.as_bytes(), $offset)
157 .await
158 .expect("write failed")
159 .map_err(Status::from_raw)
160 .expect("write error");
161
162 assert_eq!(len_written, $content.len() as u64);
163 }};
164}
165
166#[macro_export]
168macro_rules! assert_write_at_err {
169 ($proxy:expr, $offset:expr, $content:expr, $expected_status:expr) => {{
170 use $crate::test_utils::assertions::reexport::Status;
171
172 let result = $proxy
173 .write_at($content.as_bytes(), $offset)
174 .await
175 .expect("write failed")
176 .map_err(Status::from_raw);
177
178 assert_eq!(result, Err($expected_status));
179 }};
180}
181
182#[macro_export]
184macro_rules! assert_seek {
185 ($proxy:expr, $pos:expr, $start:ident, $expected:expr) => {{
186 use $crate::test_utils::assertions::reexport::{fio, Status};
187
188 let actual = $proxy
189 .seek(fio::SeekOrigin::$start, $pos)
190 .await
191 .expect("seek failed")
192 .map_err(Status::from_raw);
193
194 assert_eq!(actual, $expected);
195 }};
196 ($proxy:expr, $pos:expr, Start) => {
197 assert_seek!($proxy, $pos, Start, Ok($pos as u64))
198 };
199}
200
201#[macro_export]
203macro_rules! assert_truncate {
204 ($proxy:expr, $length:expr) => {{
205 use $crate::test_utils::assertions::reexport::Status;
206
207 let () = $proxy
208 .resize($length)
209 .await
210 .expect("resize failed")
211 .map_err(Status::from_raw)
212 .expect("resize error");
213 }};
214}
215
216#[macro_export]
218macro_rules! assert_truncate_err {
219 ($proxy:expr, $length:expr, $expected_status:expr) => {{
220 use $crate::test_utils::assertions::reexport::Status;
221
222 let result = $proxy.resize($length).await.expect("resize failed").map_err(Status::from_raw);
223
224 assert_eq!(result, Err($expected_status));
225 }};
226}
227
228#[macro_export]
230macro_rules! assert_get_attr {
231 ($proxy:expr, $expected:expr) => {{
232 use $crate::test_utils::assertions::reexport::Status;
233
234 let (status, attrs) = $proxy.get_attr().await.expect("get_attr failed");
235
236 assert_eq!(Status::from_raw(status), Status::OK);
237 assert_eq!(attrs, $expected);
238 }};
239}
240
241#[macro_export]
243macro_rules! assert_query {
244 ($proxy:expr, $expected:expr) => {
245 let protocol = $proxy.query().await.expect("describe failed");
246 assert_eq!(protocol, $expected.as_bytes());
247 };
248}
249
250#[macro_export]
252macro_rules! assert_close {
253 ($proxy:expr) => {{
254 use $crate::test_utils::assertions::reexport::Status;
255
256 let () = $proxy
257 .close()
258 .await
259 .expect("close failed")
260 .map_err(Status::from_raw)
261 .expect("close error");
262 }};
263}
264
265#[macro_export]
277macro_rules! assert_event {
278 ($proxy:expr, $expected_pattern:pat, $expected_assertion:block) => {{
279 use $crate::test_utils::assertions::reexport::StreamExt;
280
281 let event_stream = $proxy.take_event_stream();
282 match event_stream.into_future().await {
283 (Some(Ok($expected_pattern)), _) => $expected_assertion,
284 (unexpected, _) => {
285 panic!("Unexpected event: {:?}", unexpected);
286 }
287 }
288 }};
289}
290
291#[macro_export]
293macro_rules! open_get_proxy_assert {
294 ($proxy:expr, $flags:expr, $path:expr, $new_proxy_type:ty, $expected_pattern:pat,
295 $expected_assertion:block) => {{
296 use $crate::test_utils::node::open_get_proxy;
297 let new_proxy = open_get_proxy::<$new_proxy_type>($proxy, $flags, $path);
298 assert_event!(new_proxy, $expected_pattern, $expected_assertion);
299 new_proxy
300 }};
301}
302
303#[macro_export]
305macro_rules! open_get_vmo_file_proxy_assert_ok {
306 ($proxy:expr, $flags:expr, $path:expr) => {{
307 use $crate::test_utils::assertions::reexport::{fio, Status};
308
309 open_get_proxy_assert!(
310 $proxy,
311 $flags,
312 $path,
313 fio::FileMarker,
314 fio::FileEvent::OnOpen_ { s, info },
315 {
316 assert_eq!(Status::from_raw(s), Status::OK);
317 let info = *info.expect("Empty fio::NodeInfoDeprecated");
318 assert!(
319 matches!(info, fio::NodeInfoDeprecated::File(fio::FileObject { .. })),
320 "Expected fio::File but got {:?}",
321 info
322 );
323 }
324 )
325 }};
326}
327
328#[macro_export]
330macro_rules! open_as_file_assert_err {
331 ($proxy:expr, $flags:expr, $path:expr, $expected_status:expr) => {{
332 use $crate::test_utils::assertions::reexport::{fio, Status};
333
334 open_get_proxy_assert!(
335 $proxy,
336 $flags,
337 $path,
338 fio::FileMarker,
339 fio::FileEvent::OnOpen_ { s, info },
340 {
341 assert_eq!(Status::from_raw(s), $expected_status);
342 assert_eq!(info, None);
343 }
344 );
345 }};
346}
347
348#[macro_export]
350macro_rules! open_get_directory_proxy_assert_ok {
351 ($proxy:expr, $flags:expr, $path:expr) => {{
352 use $crate::test_utils::assertions::reexport::{fio, Status};
353
354 open_get_proxy_assert!(
355 $proxy,
356 $flags,
357 $path,
358 fio::DirectoryMarker,
359 fio::DirectoryEvent::OnOpen_ { s, info },
360 {
361 assert_eq!(Status::from_raw(s), Status::OK);
362 assert_eq!(
363 info,
364 Some(Box::new(fio::NodeInfoDeprecated::Directory(fio::DirectoryObject))),
365 );
366 }
367 )
368 }};
369}
370
371#[macro_export]
373macro_rules! open_as_directory_assert_err {
374 ($proxy:expr, $flags:expr, $path:expr, $expected_status:expr) => {{
375 use $crate::test_utils::assertions::reexport::{fio, Status};
376
377 open_get_proxy_assert!(
378 $proxy,
379 $flags,
380 $path,
381 fio::DirectoryMarker,
382 fio::DirectoryEvent::OnOpen_ { s, info },
383 {
384 assert_eq!(Status::from_raw(s), $expected_status);
385 assert_eq!(info, None);
386 }
387 );
388 }};
389}
390
391#[macro_export]
392macro_rules! clone_get_proxy_assert {
393 ($proxy:expr, $flags:expr, $new_proxy_type:ty, $expected_pattern:pat,
394 $expected_assertion:block) => {{
395 use $crate::test_utils::node::clone_get_proxy;
396 let new_proxy = clone_get_proxy::<$new_proxy_type, _>($proxy, $flags);
397 assert_event!(new_proxy, $expected_pattern, $expected_assertion);
398 new_proxy
399 }};
400}
401
402#[macro_export]
404macro_rules! clone_get_vmo_file_proxy_assert_ok {
405 ($proxy:expr, $flags:expr) => {{
406 use $crate::test_utils::assertions::reexport::{fio, Status};
407
408 clone_get_proxy_assert!(
409 $proxy,
410 $flags,
411 fio::FileMarker,
412 fio::FileEvent::OnOpen_ { s, info },
413 {
414 assert_eq!(Status::from_raw(s), Status::OK);
415 let info = *info.expect("Empty fio::NodeInfoDeprecated");
416 assert!(
417 matches!(info, fio::NodeInfoDeprecated::File(fio::FileObject { .. }),),
418 "Expected fio::File but got {:?}",
419 info
420 );
421 }
422 )
423 }};
424}
425
426#[macro_export]
428macro_rules! clone_get_vmo_file_proxy_assert_err {
429 ($proxy:expr, $flags:expr) => {{
430 use $crate::test_utils::assertions::reexport::{fio, Status};
431
432 clone_get_proxy_assert!(
433 $proxy,
434 $flags,
435 fio::FileMarker,
436 fio::FileEvent::OnOpen_ { s, info },
437 {
438 assert_eq!(Status::from_raw(s), Status::OK);
439 let info = *info.expect("Empty fio::NodeInfoDeprecated");
440 assert!(
441 matches!(info, fio::NodeInfoDeprecated::Service(fio::Service)),
442 "Expected fio::Service but got {:?}",
443 info
444 );
445 }
446 )
447 }};
448}
449
450#[macro_export]
452macro_rules! clone_as_file_assert_err {
453 ($proxy:expr, $flags:expr, $expected_status:expr) => {{
454 use $crate::test_utils::assertions::reexport::{fio, Status};
455
456 clone_get_proxy_assert!(
457 $proxy,
458 $flags,
459 fio::FileMarker,
460 fio::FileEvent::OnOpen_ { s, info },
461 {
462 assert_eq!(Status::from_raw(s), $expected_status);
463 assert_eq!(info, None);
464 }
465 )
466 }};
467}
468
469#[macro_export]
471macro_rules! clone_get_service_proxy_assert_ok {
472 ($proxy:expr, $flags:expr) => {{
473 use $crate::test_utils::assertions::reexport::{fio, Status};
474
475 clone_get_proxy_assert!(
476 $proxy,
477 $flags,
478 fio::NodeMarker,
479 fio::NodeEvent::OnOpen_ { s, info },
480 {
481 assert_eq!(Status::from_raw(s), Status::OK);
482 assert_eq!(info, Some(Box::new(fio::NodeInfoDeprecated::Service(fio::Service))),);
483 }
484 )
485 }};
486}
487
488#[macro_export]
490macro_rules! clone_get_directory_proxy_assert_ok {
491 ($proxy:expr, $flags:expr) => {{
492 use $crate::test_utils::assertions::reexport::{fio, Status};
493
494 clone_get_proxy_assert!(
495 $proxy,
496 $flags,
497 fio::DirectoryMarker,
498 fio::DirectoryEvent::OnOpen_ { s, info },
499 {
500 assert_eq!(Status::from_raw(s), Status::OK);
501 assert_eq!(
502 info,
503 Some(Box::new(fio::NodeInfoDeprecated::Directory(fio::DirectoryObject))),
504 );
505 }
506 )
507 }};
508}
509
510#[macro_export]
512macro_rules! clone_as_directory_assert_err {
513 ($proxy:expr, $flags:expr, $expected_status:expr) => {{
514 use $crate::test_utils::assertions::reexport::{fio, Status};
515
516 clone_get_proxy_assert!(
517 $proxy,
518 $flags,
519 fio::DirectoryMarker,
520 fio::DirectoryEvent::OnOpen_ { s, info },
521 {
522 assert_eq!(Status::from_raw(s), $expected_status);
523 assert_eq!(info, None);
524 }
525 )
526 }};
527}
528
529#[macro_export]
531macro_rules! assert_read_dirents {
532 ($proxy:expr, $max_bytes:expr, $expected:expr) => {{
533 use $crate::test_utils::assertions::reexport::Status;
534
535 let expected = $expected as Vec<u8>;
536
537 let (status, entries) = $proxy.read_dirents($max_bytes).await.expect("read_dirents failed");
538
539 assert_eq!(Status::from_raw(status), Status::OK);
540 assert!(
541 entries == expected,
542 "Read entries do not match the expectation.\n\
543 Expected entries: {:?}\n\
544 Actual entries: {:?}\n\
545 Expected as UTF-8 lossy: {:?}\n\
546 Received as UTF-8 lossy: {:?}",
547 expected,
548 entries,
549 String::from_utf8_lossy(&expected),
550 String::from_utf8_lossy(&entries),
551 );
552 }};
553}
554
555#[macro_export]
556macro_rules! assert_read_dirents_one_listing {
557 ($proxy:expr, $max_bytes:expr, $( { $type:tt, $name:expr $(,)* } ),* $(,)*) => {{
558 use $crate::test_utils::assertions::reexport::{DirentsSameInodeBuilder, fio};
559
560 let mut expected = DirentsSameInodeBuilder::new(fio::INO_UNKNOWN);
561 expected
562 $(.add(assert_read_dirents_one_listing!(@expand_dirent_type $type), $name))*
563 ;
564
565 assert_read_dirents!($proxy, $max_bytes, expected.into_vec());
566 }};
567
568 (@expand_dirent_type UNKNOWN) => { fio::DirentType::Unknown };
569 (@expand_dirent_type DIRECTORY) => { fio::DirentType::Directory };
570 (@expand_dirent_type BLOCK_DEVICE) => { fio::DirentType::BlockDevice };
571 (@expand_dirent_type FILE) => { fio::DirentType::File };
572 (@expand_dirent_type SERVICE) => { fio::DirentType::Service };
573}
574
575#[macro_export]
576macro_rules! assert_read_dirents_path_one_listing {
577 ($proxy:expr, $path:expr, $max_bytes:expr, $( { $type:tt, $name:expr $(,)* } ),* $(,)*) => {{
578 use $crate::test_utils::assertions::reexport::fio;
579
580 let flags = fio::OpenFlags::DESCRIBE;
581 let path = open_get_directory_proxy_assert_ok!($proxy, flags, $path);
582
583 assert_read_dirents_one_listing!(path, $max_bytes, $( { $type, $name }, )*);
584 assert_close!(path);
585 }};
586}
587
588#[macro_export]
590macro_rules! assert_read_dirents_err {
591 ($proxy:expr, $max_bytes:expr, $expected_status:expr) => {{
592 use $crate::test_utils::assertions::reexport::Status;
593
594 let (status, entries) = $proxy.read_dirents($max_bytes).await.expect("read_dirents failed");
595
596 assert_eq!(Status::from_raw(status), $expected_status);
597 assert!(
598 entries.len() == 0,
599 "`read_dirents` returned non-empty list of entries along with an error.\n\
600 Got {} entries.\n\
601 Content: {:?}\n\
602 Content as UTF-8 lossy: {:?}",
603 entries.len(),
604 entries,
605 String::from_utf8_lossy(&entries),
606 );
607 }};
608}
609
610#[macro_export]
611macro_rules! assert_channel_closed {
612 ($channel:expr) => {{
613 use $crate::test_utils::assertions::reexport::{MessageBuf, Status};
614
615 let channel = &$channel;
617
618 let mut msg = MessageBuf::new();
619 match channel.recv_msg(&mut msg).await {
620 Ok(()) => panic!(
621 "'{}' received a message, instead of been closed: {:?}",
622 stringify!($channel),
623 msg.bytes(),
624 ),
625 Err(Status::PEER_CLOSED) => (),
626 Err(status) => panic!("'{}' closed with status: {}", stringify!($channel), status),
627 }
628 }};
629}
630
631#[macro_export]
632macro_rules! assert_get_vmo {
633 ($proxy:expr, $flags:expr) => {{
634 use $crate::test_utils::assertions::reexport::Status;
635 $proxy
636 .get_backing_memory($flags)
637 .await
638 .expect("`get_backing_memory()` failed")
639 .map_err(Status::from_raw)
640 .expect("`get_backing_memory` error")
641 }};
642}
643
644#[macro_export]
645macro_rules! assert_get_vmo_err {
646 ($proxy:expr, $flags:expr, $expected_status:expr) => {{
647 use $crate::test_utils::assertions::reexport::Status;
648
649 let result = $proxy
650 .get_backing_memory($flags)
651 .await
652 .expect("`get_backing_memory()` failed")
653 .map_err(Status::from_raw);
654
655 assert_eq!(result, Err($expected_status));
656 }};
657}
658
659#[macro_export]
661macro_rules! assert_unlink {
662 ($proxy:expr, $path:expr) => {{
663 $proxy
664 .unlink($path, &fio::UnlinkOptions::default())
665 .await
666 .expect("fidl failed")
667 .expect("unlink failed");
668 }};
669}
670
671#[macro_export]
673macro_rules! assert_unlink_err {
674 ($proxy:expr, $path:expr, $expected_status:expr) => {{
675 use $crate::test_utils::assertions::reexport::{fio, Status};
676
677 assert_eq!(
678 Status::from_raw(
679 $proxy
680 .unlink($path, &fio::UnlinkOptions::default())
681 .await
682 .expect("fidl failed")
683 .expect_err("unlink succeeded")
684 ),
685 $expected_status
686 );
687 }};
688}
689
690#[macro_export]
692macro_rules! assert_get_token {
693 ($proxy:expr) => {{
694 use $crate::test_utils::assertions::reexport::Status;
695
696 let (status, o_token) = $proxy.get_token().await.expect("get_token failed");
697
698 assert_eq!(Status::from_raw(status), Status::OK);
699 match o_token {
700 None => panic!("`get_token` returned Status::OK, but no token"),
701 Some(token) => token,
702 }
703 }};
704}
705
706#[macro_export]
708macro_rules! assert_get_token_err {
709 ($proxy:expr, $expected_status:expr) => {{
710 use $crate::test_utils::assertions::reexport::Status;
711
712 let (status, token) = $proxy.get_token().await.expect("get_token failed");
713
714 assert_eq!(Status::from_raw(status), $expected_status);
715 assert!(
716 token.is_none(),
717 "`get_token` returned a token along with an error code.\n\
718 token: {:?}",
719 token
720 );
721 }};
722}
723
724#[macro_export]
726macro_rules! assert_rename {
727 ($proxy:expr, $src:expr, $dst_parent_token:expr, $dst:expr) => {{
728 let status = $proxy.rename($src, $dst_parent_token, $dst).await.expect("rename failed");
729
730 assert!(status.is_ok());
731 }};
732}
733
734#[macro_export]
736macro_rules! assert_rename_err {
737 ($proxy:expr, $src:expr, $dst_parent_token:expr, $dst:expr, $expected_status:expr) => {{
738 use $crate::test_utils::assertions::reexport::Status;
739
740 let status = $proxy.rename($src, $dst_parent_token, $dst).await.expect("rename failed");
741
742 assert!(status.is_err());
743 assert_eq!(status.err().unwrap(), $expected_status.into_raw());
744 }};
745}
746
747#[macro_export]
749macro_rules! assert_link_err {
750 ($proxy:expr, $src:expr, $dst_parent_token:expr, $dst:expr, $expected_status:expr) => {{
751 use $crate::test_utils::assertions::reexport::Status;
752
753 let status = $proxy.link($src, $dst_parent_token, $dst).await.expect("link failed");
754
755 assert_eq!(Status::from_raw(status), $expected_status);
756 }};
757}
758
759#[macro_export]
761macro_rules! assert_get_attributes {
762 ($proxy:expr, $requested_attributes:expr, $expected:expr) => {{
763 use $crate::test_utils::assertions::reexport::Status;
764
765 let (mutable_attributes, immutable_attributes) = $proxy
766 .get_attributes($requested_attributes)
767 .await
768 .expect("get_attributes failed")
769 .map_err(Status::from_raw)
770 .expect("get_attributes error");
771
772 assert_eq!(mutable_attributes, $expected.mutable_attributes);
773 assert_eq!(immutable_attributes, $expected.immutable_attributes);
774 }};
775}