@@ -4,9 +4,14 @@ pub mod _utils;
44pub use _utils:: * ;
55
66use command_extra:: CommandExtra ;
7+ use maplit:: btreeset;
78use pipe_trait:: Pipe ;
89use pretty_assertions:: assert_eq;
9- use std:: process:: { Command , Output , Stdio } ;
10+ use std:: {
11+ collections:: BTreeSet ,
12+ path:: Path ,
13+ process:: { Command , Output , Stdio } ,
14+ } ;
1015
1116fn stdio ( command : Command ) -> Command {
1217 command
@@ -15,6 +20,21 @@ fn stdio(command: Command) -> Command {
1520 . with_stderr ( Stdio :: piped ( ) )
1621}
1722
23+ #[ cfg( unix) ]
24+ fn fs_permission ( path : impl AsRef < Path > , permission : & ' static str , recursive : bool ) {
25+ let Output { status, stderr, .. } = Command :: new ( "chmod" )
26+ . pipe ( |cmd| if recursive { cmd. with_arg ( "-R" ) } else { cmd } )
27+ . with_arg ( permission)
28+ . with_arg ( path. as_ref ( ) )
29+ . with_stdin ( Stdio :: null ( ) )
30+ . with_stdout ( Stdio :: null ( ) )
31+ . with_stderr ( Stdio :: piped ( ) )
32+ . output ( )
33+ . expect ( "run chmod command" ) ;
34+ inspect_stderr ( & stderr) ;
35+ assert ! ( status. success( ) , "chmod fails {:?}" , status) ;
36+ }
37+
1838#[ test]
1939fn min_ratio_1 ( ) {
2040 let workspace = SampleWorkspace :: default ( ) ;
@@ -64,3 +84,69 @@ fn max_depth_0() {
6484 ) ;
6585 assert_eq ! ( & stdout, & [ ] as & [ u8 ] ) ;
6686}
87+
88+ #[ cfg( unix) ]
89+ #[ test]
90+ fn fs_errors ( ) {
91+ use std:: convert:: TryInto ;
92+
93+ use parallel_disk_usage:: {
94+ bytes_format:: BytesFormat ,
95+ data_tree:: DataTree ,
96+ fs_tree_builder:: FsTreeBuilder ,
97+ os_string_display:: OsStringDisplay ,
98+ reporter:: { ErrorOnlyReporter , ErrorReport } ,
99+ size_getters:: GET_APPARENT_SIZE ,
100+ visualizer:: { ColumnWidthDistribution , Direction , Visualizer } ,
101+ } ;
102+
103+ let workspace = SampleWorkspace :: default ( ) ;
104+ fs_permission ( workspace. join ( "empty-dir" ) , "-r" , false ) ;
105+ fs_permission ( workspace. join ( "nested" ) . join ( "0" ) , "-r" , false ) ;
106+
107+ let Output {
108+ status,
109+ stdout,
110+ stderr,
111+ } = Command :: new ( PDU )
112+ . with_current_dir ( workspace. as_path ( ) )
113+ . with_arg ( "--min-ratio=0" )
114+ . with_arg ( "--total-width=100" )
115+ . pipe ( stdio)
116+ . output ( )
117+ . expect ( "spawn command" ) ;
118+
119+ let stderr = String :: from_utf8 ( stderr) . expect ( "parse stderr as UTF-8" ) ;
120+ let stdout = String :: from_utf8 ( stdout) . expect ( "parse stdout as UTF-8" ) ;
121+ dbg ! ( & status) ;
122+ eprintln ! ( "STDERR+STDOUT:\n {}{}\n " , & stderr, & stdout) ;
123+
124+ let builder = FsTreeBuilder {
125+ root : workspace. to_path_buf ( ) ,
126+ get_data : GET_APPARENT_SIZE ,
127+ reporter : ErrorOnlyReporter :: new ( ErrorReport :: SILENT ) ,
128+ } ;
129+ let mut data_tree: DataTree < OsStringDisplay , _ > = builder. into ( ) ;
130+ data_tree. par_sort_by ( |left, right| left. data ( ) . cmp ( & right. data ( ) ) . reverse ( ) ) ;
131+ * data_tree. name_mut ( ) = OsStringDisplay :: os_string_from ( "." ) ;
132+ let visualizer = Visualizer {
133+ data_tree : & data_tree,
134+ bytes_format : BytesFormat :: MetricUnits ,
135+ direction : Direction :: BottomUp ,
136+ column_width_distribution : ColumnWidthDistribution :: total ( 100 ) ,
137+ max_depth : 10 . try_into ( ) . unwrap ( ) ,
138+ } ;
139+ let expected_stdout = format ! ( "{}" , visualizer) ;
140+ eprintln ! ( "EXPECTED STDOUT:\n {}\n " , & expected_stdout) ;
141+
142+ fs_permission ( workspace. as_path ( ) , "+rwx" , true ) ; // to allow SampleWorkspace destructor to clean itself
143+
144+ let actual_stderr_lines: BTreeSet < _ > = stderr. trim_end ( ) . lines ( ) . collect ( ) ;
145+ let expected_stderr_lines = btreeset ! {
146+ "\r \r [error] read_dir \" ./nested/0\" : Permission denied (os error 13)" ,
147+ "\r \r [error] read_dir \" ./empty-dir\" : Permission denied (os error 13)" ,
148+ } ;
149+ assert_eq ! ( actual_stderr_lines, expected_stderr_lines) ;
150+
151+ assert_eq ! ( stdout, expected_stdout) ;
152+ }
0 commit comments