Replace lexical Rust fragments with real modules

This commit is contained in:
ms2k 2026-07-19 05:12:57 +09:00
commit 247819250b
2 changed files with 3302 additions and 2671 deletions

View file

@ -827,4 +827,5 @@ fn hex(bytes: &[u8]) -> String {
)
}
include!("transport/tests.rs");
#[cfg(test)]
mod tests;

View file

@ -1,193 +1,190 @@
#[cfg(test)]
mod tests {
use std::io::{Read, Write};
use std::net::TcpListener;
use std::os::unix::fs::PermissionsExt;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration;
use std::io::{Read, Write};
use std::net::TcpListener;
use std::os::unix::fs::PermissionsExt;
use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering};
use std::time::Duration;
use oci_client::client::ClientProtocol;
use oci_client::client::ClientProtocol;
use super::*;
use super::*;
#[test]
fn atomic_layout_write_accepts_a_root_level_destination() {
#[test]
fn atomic_layout_write_accepts_a_root_level_destination() {
let tree = tempfile::tempdir().unwrap();
let root = File::open(tree.path()).unwrap();
write_relative_atomic(&root, Path::new("oci-layout"), b"layout").unwrap();
assert_eq!(
std::fs::read(tree.path().join("oci-layout")).unwrap(),
b"layout"
);
}
#[test]
fn confined_read_open_uses_an_empty_creation_mode() {
let tree = tempfile::tempdir().unwrap();
let root = File::open(tree.path()).unwrap();
let error = open_relative_file(&root, Path::new("absent"), OFlags::RDONLY).unwrap_err();
assert_eq!(error.kind(), std::io::ErrorKind::NotFound);
}
#[test]
fn preexisting_transport_parents_require_exact_private_mode() {
for name in ["image-transports", "blobs", "sha256"] {
let tree = tempfile::tempdir().unwrap();
let root = File::open(tree.path()).unwrap();
write_relative_atomic(&root, Path::new("oci-layout"), b"layout").unwrap();
assert_eq!(
std::fs::read(tree.path().join("oci-layout")).unwrap(),
b"layout"
);
}
#[test]
fn confined_read_open_uses_an_empty_creation_mode() {
let tree = tempfile::tempdir().unwrap();
let root = File::open(tree.path()).unwrap();
let error = open_relative_file(&root, Path::new("absent"), OFlags::RDONLY).unwrap_err();
assert_eq!(error.kind(), std::io::ErrorKind::NotFound);
}
#[test]
fn preexisting_transport_parents_require_exact_private_mode() {
for name in ["image-transports", "blobs", "sha256"] {
let tree = tempfile::tempdir().unwrap();
std::fs::create_dir(tree.path().join(name)).unwrap();
std::fs::set_permissions(
tree.path().join(name),
std::fs::Permissions::from_mode(0o777),
)
.unwrap();
let parent = File::open(tree.path()).unwrap();
assert!(
create_directory(&parent, name).is_err(),
"accepted wrong mode for {name}"
);
}
}
#[test]
fn refuses_mismatched_and_incomplete_platforms() {
std::fs::create_dir(tree.path().join(name)).unwrap();
std::fs::set_permissions(
tree.path().join(name),
std::fs::Permissions::from_mode(0o777),
)
.unwrap();
let parent = File::open(tree.path()).unwrap();
assert!(
verify_platform(
r#"{"os":"linux","architecture":"amd64"}"#,
&Platform::linux("amd64")
)
.is_ok()
);
assert!(
verify_platform(
r#"{"os":"linux","architecture":"arm64"}"#,
&Platform::linux("amd64")
)
.is_err()
);
assert!(
verify_platform(
r#"{"os":"linux","architecture":"amd64","variant":"v2"}"#,
&Platform::linux("amd64")
)
.is_err()
);
assert!(verify_platform(r#"{"architecture":"amd64"}"#, &Platform::linux("amd64")).is_err());
}
#[test]
fn incomplete_authentication_refuses_without_layout_or_secret_disclosure() {
let runtime = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
let temp = tempfile::tempdir().unwrap();
let result = runtime.block_on(OciRegistryTransport.pull_with_config(
"registry.invalid/private/image:latest",
&RegistryCredentials::Basic {
username: "developer".to_owned(),
password: String::new(),
},
&Platform::linux("amd64"),
&temp.path().join("layout"),
ClientConfig::default(),
));
let error = result.unwrap_err();
assert!(matches!(error, PreparedLowerError::Authentication { .. }));
let error = error.to_string();
assert!(error.contains("credentials are incomplete"));
assert!(!error.contains("developer"));
assert!(!temp.path().join("layout").exists());
assert_eq!(
format!(
"{:?}",
RegistryCredentials::Bearer("not-a-real-token".to_owned())
),
"Bearer(\"[redacted]\")"
create_directory(&parent, name).is_err(),
"accepted wrong mode for {name}"
);
}
}
#[test]
fn registry_authentication_failure_refuses_before_layout_creation() {
let listener = match TcpListener::bind("127.0.0.1:0") {
Ok(listener) => listener,
Err(error) if error.kind() == std::io::ErrorKind::PermissionDenied => return,
Err(error) => panic!("binding test registry: {error}"),
};
let address = listener.local_addr().unwrap();
listener.set_nonblocking(true).unwrap();
let stop = Arc::new(AtomicBool::new(false));
let server_stop = Arc::clone(&stop);
let server = std::thread::spawn(move || {
while !server_stop.load(Ordering::Relaxed) {
match listener.accept() {
Ok((mut stream, _)) => {
let mut request = [0; 4096];
assert!(stream.read(&mut request).unwrap() > 0);
stream
#[test]
fn refuses_mismatched_and_incomplete_platforms() {
assert!(
verify_platform(
r#"{"os":"linux","architecture":"amd64"}"#,
&Platform::linux("amd64")
)
.is_ok()
);
assert!(
verify_platform(
r#"{"os":"linux","architecture":"arm64"}"#,
&Platform::linux("amd64")
)
.is_err()
);
assert!(
verify_platform(
r#"{"os":"linux","architecture":"amd64","variant":"v2"}"#,
&Platform::linux("amd64")
)
.is_err()
);
assert!(verify_platform(r#"{"architecture":"amd64"}"#, &Platform::linux("amd64")).is_err());
}
#[test]
fn incomplete_authentication_refuses_without_layout_or_secret_disclosure() {
let runtime = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
let temp = tempfile::tempdir().unwrap();
let result = runtime.block_on(OciRegistryTransport.pull_with_config(
"registry.invalid/private/image:latest",
&RegistryCredentials::Basic {
username: "developer".to_owned(),
password: String::new(),
},
&Platform::linux("amd64"),
&temp.path().join("layout"),
ClientConfig::default(),
));
let error = result.unwrap_err();
assert!(matches!(error, PreparedLowerError::Authentication { .. }));
let error = error.to_string();
assert!(error.contains("credentials are incomplete"));
assert!(!error.contains("developer"));
assert!(!temp.path().join("layout").exists());
assert_eq!(
format!(
"{:?}",
RegistryCredentials::Bearer("not-a-real-token".to_owned())
),
"Bearer(\"[redacted]\")"
);
}
#[test]
fn registry_authentication_failure_refuses_before_layout_creation() {
let listener = match TcpListener::bind("127.0.0.1:0") {
Ok(listener) => listener,
Err(error) if error.kind() == std::io::ErrorKind::PermissionDenied => return,
Err(error) => panic!("binding test registry: {error}"),
};
let address = listener.local_addr().unwrap();
listener.set_nonblocking(true).unwrap();
let stop = Arc::new(AtomicBool::new(false));
let server_stop = Arc::clone(&stop);
let server = std::thread::spawn(move || {
while !server_stop.load(Ordering::Relaxed) {
match listener.accept() {
Ok((mut stream, _)) => {
let mut request = [0; 4096];
assert!(stream.read(&mut request).unwrap() > 0);
stream
.write_all(
b"HTTP/1.1 401 Unauthorized\r\nContent-Length: 0\r\nConnection: close\r\n\r\n",
)
.unwrap();
}
Err(error) if error.kind() == std::io::ErrorKind::WouldBlock => {
std::thread::sleep(Duration::from_millis(1));
}
Err(error) => panic!("accepting test registry request: {error}"),
}
Err(error) if error.kind() == std::io::ErrorKind::WouldBlock => {
std::thread::sleep(Duration::from_millis(1));
}
Err(error) => panic!("accepting test registry request: {error}"),
}
});
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
let temp = tempfile::tempdir().unwrap();
let result = runtime.block_on(OciRegistryTransport.pull_with_config(
&format!("{address}/private/image:latest"),
&RegistryCredentials::Basic {
username: "wrong".to_owned(),
password: "wrong".to_owned(),
},
&Platform::linux("amd64"),
&temp.path().join("layout"),
ClientConfig {
protocol: ClientProtocol::Http,
..ClientConfig::default()
},
));
assert!(
matches!(result, Err(PreparedLowerError::Authentication { .. })),
"{result:?}"
);
assert!(!temp.path().join("layout").exists());
stop.store(true, Ordering::Relaxed);
server.join().unwrap();
}
}
});
let runtime = tokio::runtime::Builder::new_current_thread()
.enable_all()
.build()
.unwrap();
let temp = tempfile::tempdir().unwrap();
let result = runtime.block_on(OciRegistryTransport.pull_with_config(
&format!("{address}/private/image:latest"),
&RegistryCredentials::Basic {
username: "wrong".to_owned(),
password: "wrong".to_owned(),
},
&Platform::linux("amd64"),
&temp.path().join("layout"),
ClientConfig {
protocol: ClientProtocol::Http,
..ClientConfig::default()
},
));
assert!(
matches!(result, Err(PreparedLowerError::Authentication { .. })),
"{result:?}"
);
assert!(!temp.path().join("layout").exists());
stop.store(true, Ordering::Relaxed);
server.join().unwrap();
}
#[test]
fn registry_failures_map_to_stable_caller_categories() {
assert!(matches!(
distribution_error(
OciDistributionError::AuthenticationFailure("denied".into()),
"pull"
),
PreparedLowerError::Authentication { .. }
));
assert!(matches!(
distribution_error(
OciDistributionError::ImageIndexParsingNoPlatformResolverError,
"pull"
),
PreparedLowerError::PlatformSelection { .. }
));
assert!(matches!(
distribution_error(
OciDistributionError::ManifestParsingError("invalid".into()),
"pull"
),
PreparedLowerError::ManifestSelection { .. }
));
assert!(matches!(
distribution_error(OciDistributionError::GenericError(None), "pull"),
PreparedLowerError::Transport { .. }
));
}
#[test]
fn registry_failures_map_to_stable_caller_categories() {
assert!(matches!(
distribution_error(
OciDistributionError::AuthenticationFailure("denied".into()),
"pull"
),
PreparedLowerError::Authentication { .. }
));
assert!(matches!(
distribution_error(
OciDistributionError::ImageIndexParsingNoPlatformResolverError,
"pull"
),
PreparedLowerError::PlatformSelection { .. }
));
assert!(matches!(
distribution_error(
OciDistributionError::ManifestParsingError("invalid".into()),
"pull"
),
PreparedLowerError::ManifestSelection { .. }
));
assert!(matches!(
distribution_error(OciDistributionError::GenericError(None), "pull"),
PreparedLowerError::Transport { .. }
));
}