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_get_attr_path {
244 ($proxy:expr, $flags:expr, $path:expr, $expected:expr) => {{
245 use $crate::test_utils::assertions::reexport::{fio, Status};
246
247 let proxy = open_get_proxy_assert!(
248 $proxy,
249 $flags,
250 $path,
251 fio::DirectoryMarker,
252 fio::DirectoryEvent::OnOpen_ { s, info },
253 {
254 assert_eq!(Status::from_raw(s), Status::OK);
255 assert_eq!(
256 info,
257 Some(Box::new(fio::NodeInfoDeprecated::Directory(fio::DirectoryObject)))
258 );
259 }
260 );
261
262 let (status, attrs) = proxy.get_attr().await.expect("get_attr failed");
263
264 assert_eq!(Status::from_raw(status), Status::OK);
265 assert_eq!(attrs, $expected);
266 }};
267}
268
269#[macro_export]
271macro_rules! assert_query {
272 ($proxy:expr, $expected:expr) => {
273 let protocol = $proxy.query().await.expect("describe failed");
274 assert_eq!(protocol, $expected.as_bytes());
275 };
276}
277
278#[macro_export]
280macro_rules! assert_close {
281 ($proxy:expr) => {{
282 use $crate::test_utils::assertions::reexport::Status;
283
284 let () = $proxy
285 .close()
286 .await
287 .expect("close failed")
288 .map_err(Status::from_raw)
289 .expect("close error");
290 }};
291}
292
293#[macro_export]
305macro_rules! assert_event {
306 ($proxy:expr, $expected_pattern:pat, $expected_assertion:block) => {{
307 use $crate::test_utils::assertions::reexport::StreamExt;
308
309 let event_stream = $proxy.take_event_stream();
310 match event_stream.into_future().await {
311 (Some(Ok($expected_pattern)), _) => $expected_assertion,
312 (unexpected, _) => {
313 panic!("Unexpected event: {:?}", unexpected);
314 }
315 }
316 }};
317}
318
319#[macro_export]
321macro_rules! open_get_proxy_assert {
322 ($proxy:expr, $flags:expr, $path:expr, $new_proxy_type:ty, $expected_pattern:pat,
323 $expected_assertion:block) => {{
324 use $crate::test_utils::node::open_get_proxy;
325 let new_proxy = open_get_proxy::<$new_proxy_type>($proxy, $flags, $path);
326 assert_event!(new_proxy, $expected_pattern, $expected_assertion);
327 new_proxy
328 }};
329}
330
331#[macro_export]
333macro_rules! open_get_vmo_file_proxy_assert_ok {
334 ($proxy:expr, $flags:expr, $path:expr) => {{
335 use $crate::test_utils::assertions::reexport::{fio, Status};
336
337 open_get_proxy_assert!(
338 $proxy,
339 $flags,
340 $path,
341 fio::FileMarker,
342 fio::FileEvent::OnOpen_ { s, info },
343 {
344 assert_eq!(Status::from_raw(s), Status::OK);
345 let info = *info.expect("Empty fio::NodeInfoDeprecated");
346 assert!(
347 matches!(info, fio::NodeInfoDeprecated::File(fio::FileObject { .. })),
348 "Expected fio::File but got {:?}",
349 info
350 );
351 }
352 )
353 }};
354}
355
356#[macro_export]
358macro_rules! open_as_file_assert_err {
359 ($proxy:expr, $flags:expr, $path:expr, $expected_status:expr) => {{
360 use $crate::test_utils::assertions::reexport::{fio, Status};
361
362 open_get_proxy_assert!(
363 $proxy,
364 $flags,
365 $path,
366 fio::FileMarker,
367 fio::FileEvent::OnOpen_ { s, info },
368 {
369 assert_eq!(Status::from_raw(s), $expected_status);
370 assert_eq!(info, None);
371 }
372 );
373 }};
374}
375
376#[macro_export]
378macro_rules! open_get_directory_proxy_assert_ok {
379 ($proxy:expr, $flags:expr, $path:expr) => {{
380 use $crate::test_utils::assertions::reexport::{fio, Status};
381
382 open_get_proxy_assert!(
383 $proxy,
384 $flags,
385 $path,
386 fio::DirectoryMarker,
387 fio::DirectoryEvent::OnOpen_ { s, info },
388 {
389 assert_eq!(Status::from_raw(s), Status::OK);
390 assert_eq!(
391 info,
392 Some(Box::new(fio::NodeInfoDeprecated::Directory(fio::DirectoryObject))),
393 );
394 }
395 )
396 }};
397}
398
399#[macro_export]
401macro_rules! open_as_directory_assert_err {
402 ($proxy:expr, $flags:expr, $path:expr, $expected_status:expr) => {{
403 use $crate::test_utils::assertions::reexport::{fio, Status};
404
405 open_get_proxy_assert!(
406 $proxy,
407 $flags,
408 $path,
409 fio::DirectoryMarker,
410 fio::DirectoryEvent::OnOpen_ { s, info },
411 {
412 assert_eq!(Status::from_raw(s), $expected_status);
413 assert_eq!(info, None);
414 }
415 );
416 }};
417}
418
419#[macro_export]
420macro_rules! clone_get_proxy_assert {
421 ($proxy:expr, $flags:expr, $new_proxy_type:ty, $expected_pattern:pat,
422 $expected_assertion:block) => {{
423 use $crate::test_utils::node::clone_get_proxy;
424 let new_proxy = clone_get_proxy::<$new_proxy_type, _>($proxy, $flags);
425 assert_event!(new_proxy, $expected_pattern, $expected_assertion);
426 new_proxy
427 }};
428}
429
430#[macro_export]
432macro_rules! clone_get_vmo_file_proxy_assert_ok {
433 ($proxy:expr, $flags:expr) => {{
434 use $crate::test_utils::assertions::reexport::{fio, Status};
435
436 clone_get_proxy_assert!(
437 $proxy,
438 $flags,
439 fio::FileMarker,
440 fio::FileEvent::OnOpen_ { s, info },
441 {
442 assert_eq!(Status::from_raw(s), Status::OK);
443 let info = *info.expect("Empty fio::NodeInfoDeprecated");
444 assert!(
445 matches!(info, fio::NodeInfoDeprecated::File(fio::FileObject { .. }),),
446 "Expected fio::File but got {:?}",
447 info
448 );
449 }
450 )
451 }};
452}
453
454#[macro_export]
456macro_rules! clone_get_vmo_file_proxy_assert_err {
457 ($proxy:expr, $flags:expr) => {{
458 use $crate::test_utils::assertions::reexport::{fio, Status};
459
460 clone_get_proxy_assert!(
461 $proxy,
462 $flags,
463 fio::FileMarker,
464 fio::FileEvent::OnOpen_ { s, info },
465 {
466 assert_eq!(Status::from_raw(s), Status::OK);
467 let info = *info.expect("Empty fio::NodeInfoDeprecated");
468 assert!(
469 matches!(info, fio::NodeInfoDeprecated::Service(fio::Service)),
470 "Expected fio::Service but got {:?}",
471 info
472 );
473 }
474 )
475 }};
476}
477
478#[macro_export]
480macro_rules! clone_as_file_assert_err {
481 ($proxy:expr, $flags:expr, $expected_status:expr) => {{
482 use $crate::test_utils::assertions::reexport::{fio, Status};
483
484 clone_get_proxy_assert!(
485 $proxy,
486 $flags,
487 fio::FileMarker,
488 fio::FileEvent::OnOpen_ { s, info },
489 {
490 assert_eq!(Status::from_raw(s), $expected_status);
491 assert_eq!(info, None);
492 }
493 )
494 }};
495}
496
497#[macro_export]
499macro_rules! clone_get_service_proxy_assert_ok {
500 ($proxy:expr, $flags:expr) => {{
501 use $crate::test_utils::assertions::reexport::{fio, Status};
502
503 clone_get_proxy_assert!(
504 $proxy,
505 $flags,
506 fio::NodeMarker,
507 fio::NodeEvent::OnOpen_ { s, info },
508 {
509 assert_eq!(Status::from_raw(s), Status::OK);
510 assert_eq!(info, Some(Box::new(fio::NodeInfoDeprecated::Service(fio::Service))),);
511 }
512 )
513 }};
514}
515
516#[macro_export]
518macro_rules! clone_get_directory_proxy_assert_ok {
519 ($proxy:expr, $flags:expr) => {{
520 use $crate::test_utils::assertions::reexport::{fio, Status};
521
522 clone_get_proxy_assert!(
523 $proxy,
524 $flags,
525 fio::DirectoryMarker,
526 fio::DirectoryEvent::OnOpen_ { s, info },
527 {
528 assert_eq!(Status::from_raw(s), Status::OK);
529 assert_eq!(
530 info,
531 Some(Box::new(fio::NodeInfoDeprecated::Directory(fio::DirectoryObject))),
532 );
533 }
534 )
535 }};
536}
537
538#[macro_export]
540macro_rules! clone_as_directory_assert_err {
541 ($proxy:expr, $flags:expr, $expected_status:expr) => {{
542 use $crate::test_utils::assertions::reexport::{fio, Status};
543
544 clone_get_proxy_assert!(
545 $proxy,
546 $flags,
547 fio::DirectoryMarker,
548 fio::DirectoryEvent::OnOpen_ { s, info },
549 {
550 assert_eq!(Status::from_raw(s), $expected_status);
551 assert_eq!(info, None);
552 }
553 )
554 }};
555}
556
557#[macro_export]
559macro_rules! assert_read_dirents {
560 ($proxy:expr, $max_bytes:expr, $expected:expr) => {{
561 use $crate::test_utils::assertions::reexport::Status;
562
563 let expected = $expected as Vec<u8>;
564
565 let (status, entries) = $proxy.read_dirents($max_bytes).await.expect("read_dirents failed");
566
567 assert_eq!(Status::from_raw(status), Status::OK);
568 assert!(
569 entries == expected,
570 "Read entries do not match the expectation.\n\
571 Expected entries: {:?}\n\
572 Actual entries: {:?}\n\
573 Expected as UTF-8 lossy: {:?}\n\
574 Received as UTF-8 lossy: {:?}",
575 expected,
576 entries,
577 String::from_utf8_lossy(&expected),
578 String::from_utf8_lossy(&entries),
579 );
580 }};
581}
582
583#[macro_export]
584macro_rules! assert_read_dirents_one_listing {
585 ($proxy:expr, $max_bytes:expr, $( { $type:tt, $name:expr $(,)* } ),* $(,)*) => {{
586 use $crate::test_utils::assertions::reexport::{DirentsSameInodeBuilder, fio};
587
588 let mut expected = DirentsSameInodeBuilder::new(fio::INO_UNKNOWN);
589 expected
590 $(.add(assert_read_dirents_one_listing!(@expand_dirent_type $type), $name))*
591 ;
592
593 assert_read_dirents!($proxy, $max_bytes, expected.into_vec());
594 }};
595
596 (@expand_dirent_type UNKNOWN) => { fio::DirentType::Unknown };
597 (@expand_dirent_type DIRECTORY) => { fio::DirentType::Directory };
598 (@expand_dirent_type BLOCK_DEVICE) => { fio::DirentType::BlockDevice };
599 (@expand_dirent_type FILE) => { fio::DirentType::File };
600 (@expand_dirent_type SERVICE) => { fio::DirentType::Service };
601}
602
603#[macro_export]
604macro_rules! assert_read_dirents_path_one_listing {
605 ($proxy:expr, $path:expr, $max_bytes:expr, $( { $type:tt, $name:expr $(,)* } ),* $(,)*) => {{
606 use $crate::test_utils::assertions::reexport::fio;
607
608 let flags = fio::OpenFlags::DESCRIBE;
609 let path = open_get_directory_proxy_assert_ok!($proxy, flags, $path);
610
611 assert_read_dirents_one_listing!(path, $max_bytes, $( { $type, $name }, )*);
612 assert_close!(path);
613 }};
614}
615
616#[macro_export]
618macro_rules! assert_read_dirents_err {
619 ($proxy:expr, $max_bytes:expr, $expected_status:expr) => {{
620 use $crate::test_utils::assertions::reexport::Status;
621
622 let (status, entries) = $proxy.read_dirents($max_bytes).await.expect("read_dirents failed");
623
624 assert_eq!(Status::from_raw(status), $expected_status);
625 assert!(
626 entries.len() == 0,
627 "`read_dirents` returned non-empty list of entries along with an error.\n\
628 Got {} entries.\n\
629 Content: {:?}\n\
630 Content as UTF-8 lossy: {:?}",
631 entries.len(),
632 entries,
633 String::from_utf8_lossy(&entries),
634 );
635 }};
636}
637
638#[macro_export]
639macro_rules! assert_channel_closed {
640 ($channel:expr) => {{
641 use $crate::test_utils::assertions::reexport::{MessageBuf, Status};
642
643 let channel = &$channel;
645
646 let mut msg = MessageBuf::new();
647 match channel.recv_msg(&mut msg).await {
648 Ok(()) => panic!(
649 "'{}' received a message, instead of been closed: {:?}",
650 stringify!($channel),
651 msg.bytes(),
652 ),
653 Err(Status::PEER_CLOSED) => (),
654 Err(status) => panic!("'{}' closed with status: {}", stringify!($channel), status),
655 }
656 }};
657}
658
659#[macro_export]
660macro_rules! assert_get_vmo {
661 ($proxy:expr, $flags:expr) => {{
662 use $crate::test_utils::assertions::reexport::Status;
663 $proxy
664 .get_backing_memory($flags)
665 .await
666 .expect("`get_backing_memory()` failed")
667 .map_err(Status::from_raw)
668 .expect("`get_backing_memory` error")
669 }};
670}
671
672#[macro_export]
673macro_rules! assert_get_vmo_err {
674 ($proxy:expr, $flags:expr, $expected_status:expr) => {{
675 use $crate::test_utils::assertions::reexport::Status;
676
677 let result = $proxy
678 .get_backing_memory($flags)
679 .await
680 .expect("`get_backing_memory()` failed")
681 .map_err(Status::from_raw);
682
683 assert_eq!(result, Err($expected_status));
684 }};
685}
686
687#[macro_export]
689macro_rules! assert_unlink {
690 ($proxy:expr, $path:expr) => {{
691 $proxy
692 .unlink($path, &fio::UnlinkOptions::default())
693 .await
694 .expect("fidl failed")
695 .expect("unlink failed");
696 }};
697}
698
699#[macro_export]
701macro_rules! assert_unlink_err {
702 ($proxy:expr, $path:expr, $expected_status:expr) => {{
703 use $crate::test_utils::assertions::reexport::{fio, Status};
704
705 assert_eq!(
706 Status::from_raw(
707 $proxy
708 .unlink($path, &fio::UnlinkOptions::default())
709 .await
710 .expect("fidl failed")
711 .expect_err("unlink succeeded")
712 ),
713 $expected_status
714 );
715 }};
716}
717
718#[macro_export]
720macro_rules! assert_get_token {
721 ($proxy:expr) => {{
722 use $crate::test_utils::assertions::reexport::Status;
723
724 let (status, o_token) = $proxy.get_token().await.expect("get_token failed");
725
726 assert_eq!(Status::from_raw(status), Status::OK);
727 match o_token {
728 None => panic!("`get_token` returned Status::OK, but no token"),
729 Some(token) => token,
730 }
731 }};
732}
733
734#[macro_export]
736macro_rules! assert_get_token_err {
737 ($proxy:expr, $expected_status:expr) => {{
738 use $crate::test_utils::assertions::reexport::Status;
739
740 let (status, token) = $proxy.get_token().await.expect("get_token failed");
741
742 assert_eq!(Status::from_raw(status), $expected_status);
743 assert!(
744 token.is_none(),
745 "`get_token` returned a token along with an error code.\n\
746 token: {:?}",
747 token
748 );
749 }};
750}
751
752#[macro_export]
754macro_rules! assert_rename {
755 ($proxy:expr, $src:expr, $dst_parent_token:expr, $dst:expr) => {{
756 let status = $proxy.rename($src, $dst_parent_token, $dst).await.expect("rename failed");
757
758 assert!(status.is_ok());
759 }};
760}
761
762#[macro_export]
764macro_rules! assert_rename_err {
765 ($proxy:expr, $src:expr, $dst_parent_token:expr, $dst:expr, $expected_status:expr) => {{
766 use $crate::test_utils::assertions::reexport::Status;
767
768 let status = $proxy.rename($src, $dst_parent_token, $dst).await.expect("rename failed");
769
770 assert!(status.is_err());
771 assert_eq!(status.err().unwrap(), $expected_status.into_raw());
772 }};
773}
774
775#[macro_export]
777macro_rules! assert_link_err {
778 ($proxy:expr, $src:expr, $dst_parent_token:expr, $dst:expr, $expected_status:expr) => {{
779 use $crate::test_utils::assertions::reexport::Status;
780
781 let status = $proxy.link($src, $dst_parent_token, $dst).await.expect("link failed");
782
783 assert_eq!(Status::from_raw(status), $expected_status);
784 }};
785}
786
787#[macro_export]
789macro_rules! assert_get_attributes {
790 ($proxy:expr, $requested_attributes:expr, $expected:expr) => {{
791 use $crate::test_utils::assertions::reexport::Status;
792
793 let (mutable_attributes, immutable_attributes) = $proxy
794 .get_attributes($requested_attributes)
795 .await
796 .expect("get_attributes failed")
797 .map_err(Status::from_raw)
798 .expect("get_attributes error");
799
800 assert_eq!(mutable_attributes, $expected.mutable_attributes);
801 assert_eq!(immutable_attributes, $expected.immutable_attributes);
802 }};
803}