1use anyhow::{Context, Result};
2use rand::Rng;
3use std::io::{BufRead, BufReader, BufWriter, Write};
4use std::{fs::File, path::PathBuf};
5use structopt::StructOpt;
6
7#[derive(Debug, StructOpt)]
11pub struct MockDeqp {
12 #[structopt(long, help = "Path to the caselist file")]
13 deqp_caselist_file: Option<PathBuf>,
14
15 #[structopt(long, default_value = "", help = "individual deqp case")]
16 deqp_case: String,
17
18 #[structopt(long, help = "Path to the QPA log output")]
19 deqp_log_filename: PathBuf,
20
21 #[structopt(long)]
22 #[allow(dead_code)]
23 deqp_log_flush: bool,
24
25 #[structopt(long, default_value = "", help = "Path to the .shader_cache output")]
26 #[allow(dead_code)]
27 deqp_shadercache_filename: PathBuf,
28
29 #[structopt(long)]
30 #[allow(dead_code)]
31 deqp_shadercache_truncate: bool,
32
33 #[structopt(long)]
34 all_pass: bool,
35}
36
37pub fn mock_deqp(mock: &MockDeqp) -> Result<()> {
38 let tests = if let Some(path) = &mock.deqp_caselist_file {
39 let file =
40 File::open(path).with_context(|| format!("Opening {:?}", &mock.deqp_caselist_file))?;
41
42 BufReader::new(file)
43 .lines()
44 .collect::<std::result::Result<Vec<String>, std::io::Error>>()
45 .context("reading test caselist")?
46 } else {
47 mock.deqp_case.split(',').map(|x| x.to_string()).collect()
48 };
49
50 let qpa = File::create(&mock.deqp_log_filename).context("Creating QPA file")?;
51 let mut qpa_writer = BufWriter::new(&qpa);
52
53 let qpa_header = if tests[0].contains("dEQP-GLES2") {
55 r#"
56#sessionInfo releaseName git-39e5966401d69eba352d71404827230b90d3063b
57#sessionInfo releaseId 0x39e59664
58#sessionInfo targetName "Surfaceless"
59#sessionInfo vendor "Mesa/X.org"
60#sessionInfo renderer "llvmpipe (LLVM 11.0.1, 256 bits)"
61#sessionInfo commandLineParameters "--deqp-log-images=enable --deqp-log-filename=/home/anholt/TestResults.qpa --deqp-surface-type=pbuffer --deqp-surface-width=256 --deqp-surface-height=256 --deqp-gl-config-name=rgba8888d24s8ms0 --deqp-case=dEQP-GLES2.info.version"
62
63#beginSession
64"#
65 } else {
66 r#"
67#sessionInfo releaseName git-39e5966401d69eba352d71404827230b90d3063b
68#sessionInfo releaseId 0x39e59664
69#sessionInfo targetName "Surfaceless"
70#sessionInfo vendorID 0x1002
71#sessionInfo deviceID 0x687f
72#sessionInfo commandLineParameters "--deqp-log-images=enable --deqp-log-filename=/home/anholt/TestResults.qpa --deqp-surface-type=pbuffer --deqp-surface-width=256 --deqp-surface-height=256 --deqp-gl-config-name=rgba8888d24s8ms0 --deqp-case=dEQP-VK.info.device"
73
74#beginSession
75"#
76 };
77 qpa_writer
78 .write(qpa_header.as_bytes())
79 .context("writing QPA header")?;
80
81 for test_name in tests {
82 if test_name.contains("dEQP-GLES2.test.m.")
84 || test_name.contains("KHR-Single-GLES31.info.renderer")
85 || test_name.contains("KHR-Single-GLES31.info.version")
86 || test_name.contains("KHR-Single-GLES31.info.extensions")
87 {
88 continue;
89 }
90
91 println!("Test case '{}'..", test_name);
92 writeln!(qpa_writer, "#beginTestCaseResult {}", test_name)
93 .context("writing QPA test start")?;
94
95 if test_name.contains(".timeout.") {
96 #[allow(clippy::empty_loop)]
99 loop {}
100 }
101
102 if test_name.contains(".p.") || mock.all_pass {
103 println!(" Pass (success case)");
104 } else if test_name.contains(".f.") {
105 println!(" Fail (failure case)");
106 } else if test_name.contains(".flaky") {
107 if rand::thread_rng().gen::<bool>() {
108 println!(" Fail (failure case)");
109 } else {
110 println!(" Pass (success)");
111 }
112 } else if test_name.contains(".s.") {
113 println!(" NotSupported (skip case)");
114 } else if test_name.contains(".c.") {
115 break;
119 } else if test_name == "dEQP-GLES2.info.renderer" {
120 qpa_writer
121 .write(include_bytes!("test_data/deqp-gles2-renderer.xml"))
122 .context("writing QPA XML")?;
123 println!(" Pass (success case)");
124 } else if test_name == "dEQP-GLES2.info.version" {
125 qpa_writer
126 .write(include_bytes!("test_data/deqp-gles2-version.xml"))
127 .context("writing QPA XML")?;
128 println!(" Pass (success case)");
129 } else if test_name == "dEQP-GLES2.info.extensions" {
130 qpa_writer
131 .write(include_bytes!("test_data/deqp-gles2-extensions.xml"))
132 .context("writing QPA XML")?;
133 println!(" Pass (success case)");
134 } else if test_name == "dEQP-VK.info.device" {
135 qpa_writer
136 .write(include_bytes!("test_data/deqp-vk-info-device.xml"))
137 .context("writing QPA XML")?;
138 println!(" Pass (success case)");
139 } else {
140 unimplemented!("unknown mock test name {}", test_name)
141 }
142
143 writeln!(qpa_writer, "\n#endTestCaseResult").context("writing QPA test end")?;
144 }
145
146 writeln!(
147 qpa_writer,
148 r#"
149#endTestsCasesTime
150
151#endSession
152"#
153 )
154 .context("writing QPA footer")?;
155
156 Ok(())
157}