1 use test_programs::p3::wasi;
2 use test_programs::p3::wasi::filesystem::types::{
3     Descriptor, DescriptorFlags, DescriptorType, DirectoryEntry, OpenFlags, PathFlags,
4 };
5 
6 struct Component;
7 
8 test_programs::p3::export!(Component);
9 
10 impl test_programs::p3::exports::wasi::cli::run::Guest for Component {
11     async fn run() -> Result<(), ()> {
12         let preopens = wasi::filesystem::preopens::get_directories();
13         let (dir, _) = &preopens[0];
14 
15         test_readdir(dir).await;
16         test_readdir_lots(dir).await;
17         Ok(())
18     }
19 }
20 
21 fn main() {
22     unreachable!()
23 }
24 
25 async fn read_dir(dir: &Descriptor) -> Vec<DirectoryEntry> {
26     let (dirs, result) = dir.read_directory();
27     let mut dirs = dirs.collect().await;
28     result.await.unwrap();
29     dirs.sort_by_key(|d| d.name.clone());
30     dirs
31 }
32 
33 async fn assert_empty_dir(dir: &Descriptor) {
34     let dirs = read_dir(dir).await;
35     assert_eq!(dirs.len(), 0);
36 }
37 
38 async fn test_readdir(dir: &Descriptor) {
39     // Check the behavior in an empty directory
40     assert_empty_dir(dir).await;
41 
42     dir.open_at(
43         PathFlags::empty(),
44         "file".to_string(),
45         OpenFlags::CREATE,
46         DescriptorFlags::READ | DescriptorFlags::WRITE,
47     )
48     .await
49     .unwrap();
50 
51     dir.create_directory_at("nested".to_string()).await.unwrap();
52     let nested = dir
53         .open_at(
54             PathFlags::empty(),
55             "nested".to_string(),
56             OpenFlags::DIRECTORY,
57             DescriptorFlags::empty(),
58         )
59         .await
60         .unwrap();
61 
62     let entries = read_dir(dir).await;
63     assert_eq!(entries.len(), 2);
64     assert_eq!(entries[0].name, "file");
65     assert_eq!(entries[0].type_, DescriptorType::RegularFile);
66     assert_eq!(entries[1].name, "nested");
67     assert_eq!(entries[1].type_, DescriptorType::Directory);
68 
69     assert_empty_dir(&nested).await;
70     drop(nested);
71 
72     dir.unlink_file_at("file".to_string()).await.unwrap();
73     dir.remove_directory_at("nested".to_string()).await.unwrap();
74 }
75 
76 async fn test_readdir_lots(dir: &Descriptor) {
77     for count in 0..1000 {
78         dir.open_at(
79             PathFlags::empty(),
80             format!("file.{count}"),
81             OpenFlags::CREATE,
82             DescriptorFlags::READ | DescriptorFlags::WRITE,
83         )
84         .await
85         .expect("failed to create file");
86     }
87 
88     assert_eq!(read_dir(dir).await.len(), 1000);
89 
90     for count in 0..1000 {
91         dir.unlink_file_at(format!("file.{count}"))
92             .await
93             .expect("removing a file");
94     }
95 }
96