998f393ed0
- Implement ArchiveService for repository archive operations - Add BlameService for Git blame functionality - Create BranchService with full branch management capabilities - Integrate CommitService for commit operations and history - Add DiffService for generating diffs and patches - Implement MergeService with conflict resolution features - Add PackService for Git packfile operations - Create TagService for Git tag management - Add TreeService for Git tree operations - Implement comprehensive repository management functions - Add repository statistics and health checking capabilities - Include garbage collection and repacking operations - Add repository configuration management - Implement error handling and status conversion utilities - Add test suite covering all repository operations - Create utility functions for Git command execution - Add streaming response support for large data operations - Implement request resolution and validation helpers
236 lines
6.2 KiB
Rust
236 lines
6.2 KiB
Rust
mod common;
|
|
|
|
use gitks::bare::GitBare;
|
|
use gitks::pb::repository_service_server::RepositoryService;
|
|
use gitks::pb::*;
|
|
use gitks::server::GitksService;
|
|
|
|
fn header(gb: &GitBare) -> RepositoryHeader {
|
|
let parent = gb.bare_dir.parent().unwrap().to_string_lossy().into_owned();
|
|
let name = gb
|
|
.bare_dir
|
|
.file_name()
|
|
.unwrap()
|
|
.to_string_lossy()
|
|
.into_owned();
|
|
RepositoryHeader {
|
|
storage_path: parent,
|
|
relative_path: name,
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
fn req<T>(gb: &GitBare, f: impl FnOnce(RepositoryHeader) -> T) -> tonic::Request<T> {
|
|
tonic::Request::new(f(header(gb)))
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_repository() {
|
|
let (_dir, gb) = common::setup_bare_repo();
|
|
let repo = GitksService
|
|
.get_repository(req(&gb, |r| GetRepositoryRequest {
|
|
repository: Some(r),
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner();
|
|
assert!(repo.bare);
|
|
assert_eq!(repo.object_format, ObjectFormat::Sha1 as i32);
|
|
assert_eq!(repo.default_branch, "main");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_init_and_delete_repository() {
|
|
let dir = tempfile::tempdir().unwrap();
|
|
let storage = dir.path().to_string_lossy().into_owned();
|
|
let hdr = RepositoryHeader {
|
|
storage_path: storage.clone(),
|
|
relative_path: "new-repo".into(),
|
|
..Default::default()
|
|
};
|
|
let svc = GitksService;
|
|
svc.init_repository(tonic::Request::new(InitRepositoryRequest {
|
|
repository: Some(hdr.clone()),
|
|
bare: true,
|
|
..Default::default()
|
|
}))
|
|
.await
|
|
.unwrap();
|
|
assert!(
|
|
svc.repository_exists(tonic::Request::new(RepositoryExistsRequest {
|
|
repository: Some(hdr.clone())
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner()
|
|
.exists
|
|
);
|
|
svc.delete_repository(tonic::Request::new(DeleteRepositoryRequest {
|
|
repository: Some(hdr.clone()),
|
|
}))
|
|
.await
|
|
.unwrap();
|
|
assert!(
|
|
!svc.repository_exists(tonic::Request::new(RepositoryExistsRequest {
|
|
repository: Some(hdr)
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner()
|
|
.exists
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_object_format() {
|
|
let (_dir, gb) = common::setup_bare_repo();
|
|
let resp = GitksService
|
|
.get_object_format(req(&gb, |r| RepositoryObjectFormatRequest {
|
|
repository: Some(r),
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner();
|
|
assert_eq!(resp.object_format, ObjectFormat::Sha1 as i32);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_set_default_branch() {
|
|
let (_dir, gb) = common::setup_bare_repo();
|
|
let h = header(&gb);
|
|
assert_eq!(
|
|
GitksService
|
|
.get_default_branch(tonic::Request::new(GetDefaultBranchRequest {
|
|
repository: Some(h.clone())
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner()
|
|
.name,
|
|
"main"
|
|
);
|
|
GitksService
|
|
.set_default_branch(tonic::Request::new(SetDefaultBranchRequest {
|
|
repository: Some(h.clone()),
|
|
name: "feature".into(),
|
|
}))
|
|
.await
|
|
.unwrap();
|
|
assert_eq!(
|
|
GitksService
|
|
.get_default_branch(tonic::Request::new(GetDefaultBranchRequest {
|
|
repository: Some(h)
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner()
|
|
.name,
|
|
"feature"
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_set_repository_config() {
|
|
let (_dir, gb) = common::setup_bare_repo();
|
|
GitksService
|
|
.set_repository_config(tonic::Request::new(SetRepositoryConfigRequest {
|
|
repository: Some(header(&gb)),
|
|
entries: vec![RepositoryConfigEntry {
|
|
key: "test.key".into(),
|
|
values: vec!["val1".into(), "val2".into()],
|
|
}],
|
|
}))
|
|
.await
|
|
.unwrap();
|
|
let entry = GitksService
|
|
.get_repository_config(tonic::Request::new(GetRepositoryConfigRequest {
|
|
repository: Some(header(&gb)),
|
|
keys: vec!["test.key".into()],
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner()
|
|
.entries
|
|
.into_iter()
|
|
.find(|e| e.key == "test.key")
|
|
.unwrap();
|
|
assert_eq!(entry.values, vec!["val1", "val2"]);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_get_repository_statistics() {
|
|
let (_dir, gb) = common::setup_bare_repo();
|
|
let s = GitksService
|
|
.get_repository_statistics(req(&gb, |r| RepositoryStatisticsRequest {
|
|
repository: Some(r),
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner();
|
|
assert!(s.size_bytes > 0);
|
|
assert!(s.loose_object_count > 0 || s.packed_object_count > 0);
|
|
assert!(s.reference_count >= 2);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_check_repository_health() {
|
|
let (_dir, gb) = common::setup_bare_repo();
|
|
let h = GitksService
|
|
.check_repository_health(tonic::Request::new(RepositoryHealthRequest {
|
|
repository: Some(header(&gb)),
|
|
connectivity_only: true,
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner();
|
|
assert!(h.ok && h.errors.is_empty());
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_garbage_collect() {
|
|
let (_dir, gb) = common::setup_bare_repo();
|
|
assert!(
|
|
GitksService
|
|
.garbage_collect(tonic::Request::new(GarbageCollectRequest {
|
|
repository: Some(header(&gb)),
|
|
..Default::default()
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner()
|
|
.ok
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_repack() {
|
|
let (_dir, gb) = common::setup_bare_repo();
|
|
assert!(
|
|
GitksService
|
|
.repack(tonic::Request::new(RepackRequest {
|
|
repository: Some(header(&gb)),
|
|
..Default::default()
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner()
|
|
.ok
|
|
);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_write_commit_graph() {
|
|
let (_dir, gb) = common::setup_bare_repo();
|
|
assert!(
|
|
GitksService
|
|
.write_commit_graph(tonic::Request::new(WriteCommitGraphRequest {
|
|
repository: Some(header(&gb)),
|
|
..Default::default()
|
|
}))
|
|
.await
|
|
.unwrap()
|
|
.into_inner()
|
|
.ok
|
|
);
|
|
}
|