mirror of
https://github.com/anthonyoteri/dredge.git
synced 2026-06-05 15:26:53 -04:00
Merge pull request #37 from anthonyoteri/additional-test-cases
Additional test coverage
This commit is contained in:
+42
@@ -160,3 +160,45 @@ pub fn parse_response_status(response: &reqwest::Response) -> Result<(), ApiErro
|
|||||||
)),
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use http::header::HeaderValue;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// Test parsing a valid RFC5988 header value.
|
||||||
|
///
|
||||||
|
/// Attempt to parse a valid RFC5988 header value, and ensure that the
|
||||||
|
/// parsed URL was returned as expected.
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_parse_rfc5988_valid() {
|
||||||
|
// Mock a valid RFC5988 header value
|
||||||
|
let valid_header_value =
|
||||||
|
HeaderValue::from_str(r#"<https://example.com/related>; rel="related""#)
|
||||||
|
.expect("Failed to create valid header value");
|
||||||
|
|
||||||
|
// Call the parse_rfc5988 function with the valid header value
|
||||||
|
let result = parse_rfc5988(Some(&valid_header_value)).unwrap();
|
||||||
|
|
||||||
|
// Assert that the function returned the expected URL as Some(String)
|
||||||
|
assert_eq!(result, Some(String::from("https://example.com/related")));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test parsing an invalid RFC5988 header value.
|
||||||
|
///
|
||||||
|
/// Attempt to parse an invalid string as RFC5988, ensuring that the `None`
|
||||||
|
/// variant is returned.
|
||||||
|
#[async_std::test]
|
||||||
|
async fn test_parse_rfc5988_invalid() {
|
||||||
|
// Mock a valid RFC5988 header value
|
||||||
|
let invalid_header_value = HeaderValue::from_str(r#"invalid header value"#)
|
||||||
|
.expect("Failed to create valid header value");
|
||||||
|
|
||||||
|
// Call the parse_rfc5988 function with the valid header value
|
||||||
|
let result = parse_rfc5988(Some(&invalid_header_value)).unwrap();
|
||||||
|
|
||||||
|
// Assert that the function returned the expected URL as Some(String)
|
||||||
|
assert_eq!(result, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+156
-2
@@ -26,7 +26,7 @@ use clap::ValueEnum;
|
|||||||
|
|
||||||
/// Dredge is a command line tool for working with the Docker Registry
|
/// Dredge is a command line tool for working with the Docker Registry
|
||||||
/// V2 API.
|
/// V2 API.
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser, PartialEq, Eq)]
|
||||||
#[command(name = "dredge", version, author)]
|
#[command(name = "dredge", version, author)]
|
||||||
#[command(about, long_about)]
|
#[command(about, long_about)]
|
||||||
pub(crate) struct Cli {
|
pub(crate) struct Cli {
|
||||||
@@ -71,7 +71,7 @@ impl From<LogLevel> for log::LevelFilter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Subcommand)]
|
#[derive(Debug, Subcommand, PartialEq, Eq)]
|
||||||
pub enum Commands {
|
pub enum Commands {
|
||||||
/// Fetch the list of available repositories from the catalog.
|
/// Fetch the list of available repositories from the catalog.
|
||||||
Catalog,
|
Catalog,
|
||||||
@@ -95,3 +95,157 @@ pub enum Commands {
|
|||||||
/// Perform a simple version check towards the Docker Registry API
|
/// Perform a simple version check towards the Docker Registry API
|
||||||
Check,
|
Check,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// Test that given the --log-level option, ensure that the corresponding
|
||||||
|
/// `LogLevel` variant is set.
|
||||||
|
#[test]
|
||||||
|
fn test_log_level_option_off() {
|
||||||
|
let args = vec!["dredge", "--log-level=off", "registry.local", "check"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.log_level, LogLevel::Off);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the --log-level option, ensure that the corresponding
|
||||||
|
/// `LogLevel` variant is set.
|
||||||
|
#[test]
|
||||||
|
fn test_log_level_option_trace() {
|
||||||
|
let args = vec!["dredge", "--log-level=trace", "registry.local", "check"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.log_level, LogLevel::Trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the --log-level option, ensure that the corresponding
|
||||||
|
/// `LogLevel` variant is set.
|
||||||
|
#[test]
|
||||||
|
fn test_log_level_option_debug() {
|
||||||
|
let args = vec!["dredge", "--log-level=debug", "registry.local", "check"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.log_level, LogLevel::Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the --log-level option, ensure that the corresponding
|
||||||
|
/// `LogLevel` variant is set.
|
||||||
|
#[test]
|
||||||
|
fn test_log_level_option_info() {
|
||||||
|
let args = vec!["dredge", "--log-level=info", "registry.local", "check"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.log_level, LogLevel::Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the --log-level option, ensure that the corresponding
|
||||||
|
/// `LogLevel` variant is set.
|
||||||
|
#[test]
|
||||||
|
fn test_log_level_option_warn() {
|
||||||
|
let args = vec!["dredge", "--log-level=warn", "registry.local", "check"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.log_level, LogLevel::Warn);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the --log-level option, ensure that the corresponding
|
||||||
|
/// `LogLevel` variant is set.
|
||||||
|
#[test]
|
||||||
|
fn test_log_level_option_error() {
|
||||||
|
let args = vec!["dredge", "--log-level=error", "registry.local", "check"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.log_level, LogLevel::Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the <REGISTRY> argument and the "catalog" command,
|
||||||
|
/// ensure that the expected values are received.
|
||||||
|
#[test]
|
||||||
|
fn test_catalog_command() {
|
||||||
|
let args = vec!["dredge", "registry.local", "catalog"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.registry, String::from("registry.local"));
|
||||||
|
assert_eq!(cli.command, Commands::Catalog);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the <REGISTRY> argument and the "tags" command with a
|
||||||
|
/// specific image name, the expected values are received.
|
||||||
|
#[test]
|
||||||
|
fn test_tags_command() {
|
||||||
|
let args = vec!["dredge", "registry.local", "tags", "foobar"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.registry, *"registry.local");
|
||||||
|
assert_eq!(
|
||||||
|
cli.command,
|
||||||
|
Commands::Tags {
|
||||||
|
name: String::from("foobar")
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the <REGSITRY> argument and the "show" command with
|
||||||
|
/// an image name but no tag, the expected values are received.
|
||||||
|
#[test]
|
||||||
|
fn test_show_command() {
|
||||||
|
let args = vec!["dredge", "registry.local", "show", "foo"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.registry, *"registry.local");
|
||||||
|
assert_eq!(
|
||||||
|
cli.command,
|
||||||
|
Commands::Show {
|
||||||
|
image: String::from("foo"),
|
||||||
|
tag: None,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the <REGSITRY> argument and the "show" command with
|
||||||
|
/// both an image and tag, the expected values are received.
|
||||||
|
#[test]
|
||||||
|
fn test_show_command_with_optional_tag() {
|
||||||
|
let args = vec!["dredge", "registry.local", "show", "foo", "bar"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.registry, *"registry.local");
|
||||||
|
assert_eq!(
|
||||||
|
cli.command,
|
||||||
|
Commands::Show {
|
||||||
|
image: String::from("foo"),
|
||||||
|
tag: Some(String::from("bar")),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the <REGISTRY> argument and the "delete" command, with
|
||||||
|
/// both an image and tag, the expected values are received.
|
||||||
|
#[test]
|
||||||
|
fn test_delete_command() {
|
||||||
|
let args = vec!["dredge", "registry.local", "delete", "foo", "bar"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.registry, *"registry.local");
|
||||||
|
assert_eq!(
|
||||||
|
cli.command,
|
||||||
|
Commands::Delete {
|
||||||
|
image: String::from("foo"),
|
||||||
|
tag: String::from("bar"),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given the <REGISTRY> argument and the "check" command, the
|
||||||
|
/// expected values are received.
|
||||||
|
#[test]
|
||||||
|
fn test_check_command() {
|
||||||
|
let args = vec!["dredge", "registry.local", "check"];
|
||||||
|
let cli = Cli::parse_from(args);
|
||||||
|
|
||||||
|
assert_eq!(cli.registry, *"registry.local");
|
||||||
|
assert_eq!(cli.command, Commands::Check);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
+75
-4
@@ -16,8 +16,9 @@
|
|||||||
|
|
||||||
#![deny(clippy::pedantic)]
|
#![deny(clippy::pedantic)]
|
||||||
|
|
||||||
use clap::Parser;
|
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
|
use clap::Parser;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::cli::Cli;
|
use crate::cli::Cli;
|
||||||
@@ -47,9 +48,12 @@ const LATEST: &str = "latest";
|
|||||||
fn parse_registry_arg(host: &str) -> Result<Url, DredgeError> {
|
fn parse_registry_arg(host: &str) -> Result<Url, DredgeError> {
|
||||||
log::trace!("make_registry_url(host: {host})");
|
log::trace!("make_registry_url(host: {host})");
|
||||||
|
|
||||||
Url::parse(host)
|
let mut host = String::from(host);
|
||||||
.or_else(|_| Url::parse(&format!("https://{host}")))
|
if !host.starts_with("http://") && !host.starts_with("https://") {
|
||||||
.or(Err(DredgeError::RegistryUrlError(host.to_string())))
|
host = format!("https://{host}");
|
||||||
|
}
|
||||||
|
|
||||||
|
Url::parse(&host).or(Err(DredgeError::RegistryUrlError(host.to_string())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_std::main]
|
#[async_std::main]
|
||||||
@@ -87,3 +91,70 @@ async fn main() -> Result<(), DredgeError> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
/// Test that given a valid URL in the <REGISTRY> argument, we return the
|
||||||
|
/// same URL from `parse_registry_arg()`
|
||||||
|
#[test]
|
||||||
|
fn test_parse_valid_url_registry_arg() {
|
||||||
|
let host = "https://example.com/registry";
|
||||||
|
let result = parse_registry_arg(host);
|
||||||
|
|
||||||
|
// Check if the result is Ok and contains the expected URL
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let url = result.unwrap();
|
||||||
|
assert_eq!(url.scheme(), "https");
|
||||||
|
assert_eq!(url.host_str(), Some("example.com"));
|
||||||
|
assert_eq!(url.path(), "/registry");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given only an FQDN for a specific host in the <REGISTRY>
|
||||||
|
/// argument, we return an HTTPS url with that FQDN as the host.
|
||||||
|
#[test]
|
||||||
|
fn test_parse_valid_fqdn_registry_arg() {
|
||||||
|
let host = "example.com";
|
||||||
|
let result = parse_registry_arg(host);
|
||||||
|
|
||||||
|
// Check if the result is Ok and contains the expected URL
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let url = result.unwrap();
|
||||||
|
assert_eq!(url.scheme(), "https");
|
||||||
|
assert_eq!(url.host_str(), Some("example.com"));
|
||||||
|
assert_eq!(url.path(), "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given an FQDN with port for a specific host in the <REGISTRY>
|
||||||
|
/// argument, we return an HTTPS url with that FQDN as the host and the
|
||||||
|
/// given port as the parsed port number.
|
||||||
|
#[test]
|
||||||
|
fn test_parse_valid_fqdn_registry_arg_alt_port() {
|
||||||
|
let host = "example.com:5123";
|
||||||
|
let result = parse_registry_arg(host);
|
||||||
|
|
||||||
|
// Check if the result is Ok and contains the expected URL
|
||||||
|
assert!(result.is_ok());
|
||||||
|
let url = result.unwrap();
|
||||||
|
assert_eq!(url.scheme(), "https");
|
||||||
|
assert_eq!(url.host_str(), Some("example.com"));
|
||||||
|
assert_eq!(url.port(), Some(5123));
|
||||||
|
assert_eq!(url.path(), "/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test that given an arbitrary string which can not be parsed as a valid
|
||||||
|
/// URL or FQDN, we return the `RegistryUrlError` variant.
|
||||||
|
#[test]
|
||||||
|
fn test_parse_invalid_registry_arg() {
|
||||||
|
let host = "///"; // This is not a valid URL
|
||||||
|
let result = parse_registry_arg(host);
|
||||||
|
|
||||||
|
// Check if result is Err and matches the expected error variant.
|
||||||
|
assert!(result.is_err());
|
||||||
|
match result {
|
||||||
|
Err(DredgeError::RegistryUrlError(_)) => {} // Expected error variant,
|
||||||
|
_ => panic!("Expected RegistryUrlError, got a different error"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user