summaryrefslogtreecommitdiffstats
path: root/src/tools/tidy/src/ui_tests.rs
blob: 806e84025c4a28cb37b5f841f70e6580e27d1bcc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
//! Tidy check to ensure below in UI test directories:
//! - the number of entries in each directory must be less than `ENTRY_LIMIT`
//! - there are no stray `.stderr` files

use ignore::Walk;
use ignore::WalkBuilder;
use std::fs;
use std::path::Path;

const ENTRY_LIMIT: usize = 1000;
// FIXME: The following limits should be reduced eventually.
const ROOT_ENTRY_LIMIT: usize = 939;
const ISSUES_ENTRY_LIMIT: usize = 1998;

fn check_entries(path: &Path, bad: &mut bool) {
    for dir in Walk::new(&path.join("ui")) {
        if let Ok(entry) = dir {
            if entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false) {
                let dir_path = entry.path();
                // Use special values for these dirs.
                let is_root = path.join("ui") == dir_path;
                let is_issues_dir = path.join("ui/issues") == dir_path;
                let limit = if is_root {
                    ROOT_ENTRY_LIMIT
                } else if is_issues_dir {
                    ISSUES_ENTRY_LIMIT
                } else {
                    ENTRY_LIMIT
                };

                let count = WalkBuilder::new(&dir_path)
                    .max_depth(Some(1))
                    .build()
                    .into_iter()
                    .collect::<Vec<_>>()
                    .len()
                    - 1; // remove the dir itself

                if count > limit {
                    tidy_error!(
                        bad,
                        "following path contains more than {} entries, \
                            you should move the test to some relevant subdirectory (current: {}): {}",
                        limit,
                        count,
                        dir_path.display()
                    );
                }
            }
        }
    }
}

pub fn check(path: &Path, bad: &mut bool) {
    check_entries(&path, bad);
    for path in &[&path.join("ui"), &path.join("ui-fulldeps")] {
        crate::walk::walk_no_read(path, &mut |_| false, &mut |entry| {
            let file_path = entry.path();
            if let Some(ext) = file_path.extension() {
                if ext == "stderr" || ext == "stdout" {
                    // Test output filenames have one of the formats:
                    // ```
                    // $testname.stderr
                    // $testname.$mode.stderr
                    // $testname.$revision.stderr
                    // $testname.$revision.$mode.stderr
                    // ```
                    //
                    // For now, just make sure that there is a corresponding
                    // `$testname.rs` file.
                    //
                    // NB: We do not use file_stem() as some file names have multiple `.`s and we
                    // must strip all of them.
                    let testname =
                        file_path.file_name().unwrap().to_str().unwrap().split_once('.').unwrap().0;
                    if !file_path.with_file_name(testname).with_extension("rs").exists() {
                        tidy_error!(bad, "Stray file with UI testing output: {:?}", file_path);
                    }

                    if let Ok(metadata) = fs::metadata(file_path) {
                        if metadata.len() == 0 {
                            tidy_error!(bad, "Empty file with UI testing output: {:?}", file_path);
                        }
                    }
                }
            }
        });
    }
}