vfs/test_utils/
assertions.rs

1// Copyright 2019 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Assertion helpers common to both file and directory tests.
6
7#[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// All of the macros in this file should be async functions.  There are two reasons they are not:
21//   1. It is shorter to write (`assert_read!(...)` instead of `assert_read(...).await`).
22//   2. Until we get proper backtraces we only see the line number of the line with the assertion.
23//      So macros produce better error messages.
24//
25// As soon as the second item is fixed, we should start migrating to functions.  We may consider
26// still using "thin" macro wrappers to remove the repetition of `await`. Also, https://fxbug.dev/42109299 is tracking
27// compile time degradation due to repetition macros are introducing.
28
29// See comment at the top of the file for why this is a macro.
30#[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// See comment at the top of the file for why this is a macro.
47#[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// See comment at the top of the file for why this is a macro.
59#[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// See comment at the top of the file for why this is a macro.
73#[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// See comment at the top of the file for why this is a macro.
90#[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// See comment at the top of the file for why this is a macro.
103#[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// See comment at the top of the file for why this is a macro.
120#[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// See comment at the top of the file for why this is a macro.
136#[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// See comment at the top of the file for why this is a macro.
150#[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// See comment at the top of the file for why this is a macro.
167#[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// See comment at the top of the file for why this is a macro.
183#[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// See comment at the top of the file for why this is a macro.
202#[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// See comment at the top of the file for why this is a macro.
217#[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// See comment at the top of the file for why this is a macro.
229#[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// See comment at the top of the file for why this is a macro.
242#[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// See comment at the top of the file for why this is a macro.
270#[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// See comment at the top of the file for why this is a macro.
279#[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// PartialEq is not defined for FileEvent for the moment.
294// Because of that I can not write a macro that would just accept a FileEvent instance to
295// compare against:
296//
297//     assert_event!(proxy, FileEvent::OnOpen_ {
298//         s: Status::SHOULD_WAIT.into_raw(),
299//         info: Some(Box::new(NodeInfoDeprecated::{File,Directory} { ... })),
300//     });
301//
302// Instead, I need to split the assertion into a pattern and then additional assertions on what
303// the pattern have matched.
304#[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// See comment at the top of the file for why this is a macro.
320#[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// See comment at the top of the file for why this is a macro.
332#[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// See comment at the top of the file for why this is a macro.
357#[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// See comment at the top of the file for why this is a macro.
377#[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// See comment at the top of the file for why this is a macro.
400#[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// See comment at the top of the file for why this is a macro.
431#[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// See comment at the top of the file for why this is a macro.
455#[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// See comment at the top of the file for why this is a macro.
479#[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// See comment at the top of the file for why this is a macro.
498#[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// See comment at the top of the file for why this is a macro.
517#[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// See comment at the top of the file for why this is a macro.
539#[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// See comment at the top of the file for why this is a macro.
558#[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// See comment at the top of the file for why this is a macro.
617#[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        // Allows $channel to be a temporary.
644        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// See comment at the top of the file for why this is a macro.
688#[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// See comment at the top of the file for why this is a macro.
700#[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// See comment at the top of the file for why this is a macro.
719#[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// See comment at the top of the file for why this is a macro.
735#[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// See comment at the top of the file for why this is a macro.
753#[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// See comment at the top of the file for why this is a macro.
763#[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// See comment at the top of the file for why this is a macro.
776#[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// See comment at the top of the file for why this is a macro.
788#[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}