test(cli): fix snapshot test paths on Windows (#7574)

* test(cli): fix snapshot test paths on Windows

Signed-off-by: WenyXu <wenymedia@gmail.com>

* fix: fix bugs

Signed-off-by: WenyXu <wenymedia@gmail.com>

* chore: styling

Signed-off-by: WenyXu <wenymedia@gmail.com>

---------

Signed-off-by: WenyXu <wenymedia@gmail.com>
This commit is contained in:
Weny Xu
2026-01-16 14:54:24 +08:00
committed by GitHub
parent 593befbc0f
commit 4e35028e28
4 changed files with 68 additions and 11 deletions

1
Cargo.lock generated
View File

@@ -2031,6 +2031,7 @@ dependencies = [
"tempfile",
"tokio",
"tracing-appender",
"url",
]
[[package]]

View File

@@ -72,3 +72,4 @@ common-test-util.workspace = true
common-version.workspace = true
serde.workspace = true
tempfile.workspace = true
url.workspace = true

View File

@@ -288,6 +288,7 @@ fn build_object_store_and_resolve_file_path(
#[cfg(test)]
mod tests {
use std::env;
use std::path::Path;
use std::sync::Arc;
use std::time::Duration;
@@ -300,6 +301,14 @@ mod tests {
use super::*;
use crate::metadata::snapshot::RestoreCommand;
fn create_raftengine_url(path: &std::path::Path) -> String {
let mut path = path.to_string_lossy().replace('\\', "/");
if !path.starts_with('/') {
path = format!("/{}", path);
}
format!("raftengine://{}", path)
}
#[tokio::test]
async fn test_cmd_resolve_file_path() {
common_telemetry::init_default_ut_logging();
@@ -364,25 +373,32 @@ mod tests {
let root = temp_dir.path().display().to_string();
let object_store = new_fs_object_store(&root).unwrap();
setup_backup_file(object_store, "/backup/metadata_snapshot.metadata.fb").await;
let metadata_path = temp_dir.path().join("metadata");
{
let cmd = RestoreCommand::parse_from([
"",
"--file_name",
format!("{}/backup/metadata_snapshot.metadata.fb", root).as_str(),
temp_dir
.path()
.join("backup")
.join("metadata_snapshot.metadata.fb")
.to_str()
.unwrap(),
"--backend",
"raft-engine-store",
"--store-addrs",
format!("raftengine:///{}/metadata", root).as_str(),
&create_raftengine_url(&metadata_path),
]);
let tool = cmd.build().await.unwrap();
tool.do_work().await.unwrap();
}
// Waits for the raft engine release the file lock.
tokio::time::sleep(Duration::from_secs(1)).await;
let kv =
standalone::build_metadata_kvbackend(format!("{}/metadata", root), Default::default())
.unwrap();
let kv = standalone::build_metadata_kvbackend(
metadata_path.display().to_string(),
Default::default(),
)
.unwrap();
let value = kv.get(b"test").await.unwrap().unwrap().value;
assert_eq!(value, b"test");
@@ -393,9 +409,10 @@ mod tests {
common_telemetry::init_default_ut_logging();
let temp_dir = tempfile::tempdir().unwrap();
let root = temp_dir.path().display().to_string();
let metadata_path = temp_dir.path().join("metadata");
{
let kv = standalone::build_metadata_kvbackend(
format!("{}/metadata", root),
metadata_path.to_string_lossy().to_string(),
Default::default(),
)
.unwrap();
@@ -413,11 +430,16 @@ mod tests {
let cmd = SaveCommand::parse_from([
"",
"--file_name",
format!("{}/backup/metadata_snapshot.metadata.fb", root).as_str(),
temp_dir
.path()
.join("backup")
.join("metadata_snapshot.metadata.fb")
.to_str()
.unwrap(),
"--backend",
"raft-engine-store",
"--store-addrs",
format!("raftengine:///{}/metadata", root).as_str(),
&create_raftengine_url(&metadata_path),
]);
let tool = cmd.build().await.unwrap();
tool.do_work().await.unwrap();
@@ -434,4 +456,20 @@ mod tests {
let value = kv_backend.get(b"test").await.unwrap().unwrap().value;
assert_eq!(value, b"test");
}
#[test]
fn test_path() {
let path = "C:\\Users\\user\\AppData\\Local\\Temp\\.tmpuPiVuB\\metadata";
let path = Path::new(path);
let url = create_raftengine_url(path);
assert_eq!(
url,
"raftengine:///C:/Users/user/AppData/Local/Temp/.tmpuPiVuB/metadata"
);
let url = url::Url::parse(&url).unwrap();
assert_eq!(
url.path(),
"/C:/Users/user/AppData/Local/Temp/.tmpuPiVuB/metadata"
);
}
}

View File

@@ -17,7 +17,7 @@ use std::sync::Arc;
use common_config::KvBackendConfig;
use common_error::ext::BoxedError;
use common_meta::kv_backend::KvBackendRef;
use common_telemetry::info;
use common_telemetry::{debug, info};
use log_store::raft_engine::RaftEngineBackend;
use snafu::{ResultExt, ensure};
use url::Url;
@@ -39,6 +39,7 @@ pub fn build_metadata_kvbackend(dir: String, config: KvBackendConfig) -> Result<
/// Builds the metadata kvbackend from a list of URLs.
pub fn build_metadata_kv_from_url(url: &str) -> Result<KvBackendRef> {
debug!("Building metadata kvbackend from url: {}", url);
let url = Url::parse(url).context(ParseUrlSnafu { url })?;
ensure!(
url.scheme() == "raftengine",
@@ -47,5 +48,21 @@ pub fn build_metadata_kv_from_url(url: &str) -> Result<KvBackendRef> {
}
);
build_metadata_kvbackend(url.path().to_string(), Default::default())
let path = normalize_raftengine_path(url.path());
build_metadata_kvbackend(path, Default::default())
}
fn normalize_raftengine_path(path: &str) -> String {
if cfg!(windows) {
let mut path = path.replace('\\', "/");
if let Some(stripped) = path.strip_prefix('/') {
let bytes = stripped.as_bytes();
if bytes.len() >= 2 && bytes[0].is_ascii_alphabetic() && bytes[1] == b':' {
path = stripped.to_string();
}
}
path
} else {
path.to_string()
}
}