Skip to content

Commit 9211605

Browse files
committed
Copy over interesting unit tests from the sandbox implementation
1 parent b299879 commit 9211605

File tree

1 file changed

+222
-14
lines changed

1 file changed

+222
-14
lines changed

compiler/base/orchestrator/src/coordinator.rs

Lines changed: 222 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1732,30 +1732,41 @@ mod tests {
17321732
Ok(())
17331733
}
17341734

1735+
const ADD_CODE: &str = r#"pub fn add(a: u8, b: u8) -> u8 { a + b }"#;
1736+
1737+
const ARBITRARY_ASSEMBLY_REQUEST: CompileRequest = CompileRequest {
1738+
target: CompileTarget::Assembly(
1739+
DEFAULT_ASSEMBLY_FLAVOR,
1740+
DEFAULT_ASSEMBLY_DEMANGLE,
1741+
DEFAULT_ASSEMBLY_PROCESS,
1742+
),
1743+
channel: Channel::Beta,
1744+
crate_type: CrateType::Library(LibraryType::Lib),
1745+
mode: Mode::Release,
1746+
edition: Edition::Rust2018,
1747+
tests: false,
1748+
backtrace: false,
1749+
code: String::new(),
1750+
};
1751+
1752+
const DEFAULT_ASSEMBLY_FLAVOR: AssemblyFlavor = AssemblyFlavor::Intel;
1753+
const DEFAULT_ASSEMBLY_DEMANGLE: DemangleAssembly = DemangleAssembly::Demangle;
1754+
const DEFAULT_ASSEMBLY_PROCESS: ProcessAssembly = ProcessAssembly::Filter;
1755+
17351756
#[tokio::test]
17361757
#[snafu::report]
17371758
async fn compile_assembly() -> Result<()> {
17381759
let coordinator = new_coordinator().await;
17391760

17401761
let req = CompileRequest {
1741-
target: CompileTarget::Assembly(
1742-
AssemblyFlavor::Intel,
1743-
DemangleAssembly::Demangle,
1744-
ProcessAssembly::Filter,
1745-
),
1746-
channel: Channel::Beta,
1747-
crate_type: CrateType::Library(LibraryType::Lib),
1748-
mode: Mode::Release,
1749-
edition: Edition::Rust2018,
1750-
tests: false,
1751-
backtrace: false,
1752-
code: r#"pub fn add(a: u8, b: u8) -> u8 { a + b }"#.into(),
1762+
code: ADD_CODE.into(),
1763+
..ARBITRARY_ASSEMBLY_REQUEST
17531764
};
17541765

17551766
let response = coordinator.compile(req).with_timeout().await.unwrap();
17561767

1757-
//#[cfg(target_arch = "x86_64")]
1758-
//let asm = "";
1768+
#[cfg(target_arch = "x86_64")]
1769+
let asm = "eax, [rsi + rdi]";
17591770

17601771
#[cfg(target_arch = "aarch64")]
17611772
let asm = "w0, w1, w0";
@@ -1768,6 +1779,109 @@ mod tests {
17681779
Ok(())
17691780
}
17701781

1782+
#[tokio::test]
1783+
#[snafu::report]
1784+
// Assembly flavor only makes sense when targeting x86(_64): this
1785+
// test will always fail on aarch64.
1786+
async fn compile_assembly_flavor() -> Result<()> {
1787+
let cases = [
1788+
(AssemblyFlavor::Att, "(%rsi,%rdi), %eax"),
1789+
(AssemblyFlavor::Intel, "eax, [rsi + rdi]"),
1790+
];
1791+
1792+
for (flavor, expected) in cases {
1793+
let coordinator = new_coordinator().await;
1794+
1795+
let req = CompileRequest {
1796+
target: CompileTarget::Assembly(
1797+
flavor,
1798+
DEFAULT_ASSEMBLY_DEMANGLE,
1799+
DEFAULT_ASSEMBLY_PROCESS,
1800+
),
1801+
code: ADD_CODE.into(),
1802+
..ARBITRARY_ASSEMBLY_REQUEST
1803+
};
1804+
1805+
let response = coordinator.compile(req).with_timeout().await.unwrap();
1806+
1807+
assert!(response.success, "stderr: {}", response.stderr);
1808+
assert_contains!(response.code, expected);
1809+
1810+
coordinator.shutdown().await?;
1811+
}
1812+
Ok(())
1813+
}
1814+
1815+
#[tokio::test]
1816+
#[snafu::report]
1817+
// The demangling expects Linux-style symbols, not macOS: this
1818+
// test will always fail on macOS.
1819+
async fn compile_assembly_demangle() -> Result<()> {
1820+
let cases = [
1821+
(DemangleAssembly::Mangle, "10playground3add"),
1822+
(DemangleAssembly::Demangle, "playground::add"),
1823+
];
1824+
1825+
for (mangle, expected) in cases {
1826+
let coordinator = new_coordinator().await;
1827+
1828+
let req = CompileRequest {
1829+
target: CompileTarget::Assembly(
1830+
DEFAULT_ASSEMBLY_FLAVOR,
1831+
mangle,
1832+
DEFAULT_ASSEMBLY_PROCESS,
1833+
),
1834+
code: ADD_CODE.into(),
1835+
..ARBITRARY_ASSEMBLY_REQUEST
1836+
};
1837+
1838+
let response = coordinator.compile(req).with_timeout().await.unwrap();
1839+
1840+
assert!(response.success, "stderr: {}", response.stderr);
1841+
assert_contains!(response.code, expected);
1842+
1843+
coordinator.shutdown().await?;
1844+
}
1845+
1846+
Ok(())
1847+
}
1848+
1849+
#[tokio::test]
1850+
#[snafu::report]
1851+
async fn compile_assembly_process() -> Result<()> {
1852+
let cases = [
1853+
(ProcessAssembly::Raw, true),
1854+
(ProcessAssembly::Filter, false),
1855+
];
1856+
1857+
for (process, expected) in cases {
1858+
let coordinator = new_coordinator().await;
1859+
1860+
let req = CompileRequest {
1861+
target: CompileTarget::Assembly(
1862+
DEFAULT_ASSEMBLY_FLAVOR,
1863+
DEFAULT_ASSEMBLY_DEMANGLE,
1864+
process,
1865+
),
1866+
code: ADD_CODE.into(),
1867+
..ARBITRARY_ASSEMBLY_REQUEST
1868+
};
1869+
1870+
let response = coordinator.compile(req).with_timeout().await.unwrap();
1871+
1872+
assert!(response.success, "stderr: {}", response.stderr);
1873+
if expected {
1874+
assert_contains!(response.code, ".cfi_startproc");
1875+
} else {
1876+
assert_not_contains!(response.code, ".cfi_startproc");
1877+
}
1878+
1879+
coordinator.shutdown().await?;
1880+
}
1881+
1882+
Ok(())
1883+
}
1884+
17711885
const SUBTRACT_CODE: &str = r#"pub fn sub(a: u8, b: u8) -> u8 { a - b }"#;
17721886

17731887
const ARBITRARY_HIR_REQUEST: CompileRequest = CompileRequest {
@@ -1934,6 +2048,100 @@ mod tests {
19342048
Ok(())
19352049
}
19362050

2051+
fn new_execution_limited_request() -> ExecuteRequest {
2052+
ExecuteRequest {
2053+
channel: Channel::Stable,
2054+
mode: Mode::Debug,
2055+
edition: Edition::Rust2021,
2056+
crate_type: CrateType::Binary,
2057+
tests: false,
2058+
backtrace: false,
2059+
code: Default::default(),
2060+
}
2061+
}
2062+
2063+
#[tokio::test]
2064+
#[snafu::report]
2065+
async fn network_connections_are_disabled() -> Result<()> {
2066+
// The limits are only applied to the container
2067+
let coordinator = Coordinator::new_docker().await;
2068+
2069+
let req = ExecuteRequest {
2070+
code: r#"
2071+
fn main() {
2072+
match ::std::net::TcpStream::connect("google.com:80") {
2073+
Ok(_) => println!("Able to connect to the outside world"),
2074+
Err(e) => println!("Failed to connect {}, {:?}", e, e),
2075+
}
2076+
}
2077+
"#
2078+
.into(),
2079+
..new_execution_limited_request()
2080+
};
2081+
2082+
let res = coordinator.execute(req).with_timeout().await.unwrap();
2083+
2084+
assert_contains!(res.stdout, "Failed to connect");
2085+
2086+
Ok(())
2087+
}
2088+
2089+
#[tokio::test]
2090+
#[snafu::report]
2091+
async fn memory_usage_is_limited() -> Result<()> {
2092+
// The limits are only applied to the container
2093+
let coordinator = Coordinator::new_docker().await;
2094+
2095+
let req = ExecuteRequest {
2096+
code: r#"
2097+
fn main() {
2098+
let gigabyte = 1024 * 1024 * 1024;
2099+
let mut big = vec![0u8; 1 * gigabyte];
2100+
for i in &mut big { *i += 1; }
2101+
}
2102+
"#
2103+
.into(),
2104+
..new_execution_limited_request()
2105+
};
2106+
2107+
let res = coordinator.execute(req).with_timeout().await.unwrap();
2108+
2109+
assert!(!res.success);
2110+
// TODO: We need to actually inform the user about this somehow. The UI is blank.
2111+
// assert_contains!(res.stdout, "Killed");
2112+
2113+
Ok(())
2114+
}
2115+
2116+
#[tokio::test]
2117+
#[snafu::report]
2118+
async fn number_of_pids_is_limited() -> Result<()> {
2119+
// The limits are only applied to the container
2120+
let coordinator = Coordinator::new_docker().await;
2121+
2122+
let req = ExecuteRequest {
2123+
code: r##"
2124+
fn main() {
2125+
::std::process::Command::new("sh").arg("-c").arg(r#"
2126+
z() {
2127+
z&
2128+
z
2129+
}
2130+
z
2131+
"#).status().unwrap();
2132+
}
2133+
"##
2134+
.into(),
2135+
..new_execution_limited_request()
2136+
};
2137+
2138+
let res = coordinator.execute(req).with_timeout().await.unwrap();
2139+
2140+
assert_contains!(res.stderr, "Cannot fork");
2141+
2142+
Ok(())
2143+
}
2144+
19372145
trait TimeoutExt: Future + Sized {
19382146
#[allow(clippy::type_complexity)]
19392147
fn with_timeout(

0 commit comments

Comments
 (0)