Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Parse recursive stele #57

Merged
merged 5 commits into from
Nov 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,13 @@ jobs:
# (optional) Path to changelog
changelog: CHANGELOG.md
# (required) GitHub token for creating GitHub Releases.
token: ${{ secrets.STELAE_GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
if: ${{ !contains(github.ref_name, '-') }}
# development (pre)release
# we do not need changelog changes
- uses: taiki-e/create-gh-release-action@v1
with:
token: ${{ secrets.STELAE_GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
if: ${{ contains(github.ref_name, '-') }}

upload-assets:
Expand Down Expand Up @@ -61,4 +61,4 @@ jobs:
# When multiple binary names are specified, default archive name or $bin variable cannot be used.
archive: $bin-$target-$tag
# (required) GitHub token for uploading assets to GitHub Releases.
token: ${{ secrets.STELAE_GITHUB_TOKEN }}
token: ${{ secrets.GITHUB_TOKEN }}
6 changes: 0 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,9 @@ jobs:

- name: Install NuShell
uses: hustcer/setup-nu@v3
env:
GITHUB_TOKEN: ${{ secrets.STELAE_GITHUB_TOKEN }}

- name: Install Just
uses: extractions/setup-just@v2
env:
GITHUB_TOKEN: ${{ secrets.STELAE_GITHUB_TOKEN }}

- uses: taiki-e/install-action@v2
with:
Expand All @@ -47,8 +43,6 @@ jobs:

- name: Install Just
uses: extractions/setup-just@v2
env:
GITHUB_TOKEN: ${{ secrets.STELAE_GITHUB_TOKEN }}

- name: Run just lint
run: just lint
16 changes: 13 additions & 3 deletions src/stelae/archive.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,9 @@ impl Archive {
};
archive.set_root(path)?;

archive.traverse_children(&archive.get_root()?.clone())?;
let root = archive.get_root()?;
let mut visited = vec![root.get_qualified_name()];
archive.traverse_children(&root.clone(), &mut visited)?;
Ok(archive)
}

Expand All @@ -109,9 +111,16 @@ impl Archive {
/// Will raise error if unable to traverse the child steles.
/// # Panics
/// If unable to unwrap the parent directory of the current path.
pub fn traverse_children(&mut self, current: &Stele) -> anyhow::Result<()> {
pub fn traverse_children(
&mut self,
current: &Stele,
visited: &mut Vec<String>,
) -> anyhow::Result<()> {
if let Some(dependencies) = current.get_dependencies()? {
for qualified_name in dependencies.sorted_dependencies_names() {
if visited.contains(&qualified_name) {
continue;
}
let parent_dir = self.path.clone();
let (org, name) = get_name_parts(&qualified_name)?;
if fs::metadata(parent_dir.join(&org).join(&name)).is_err() {
Expand All @@ -132,7 +141,8 @@ impl Archive {
name = child.auth_repo.name
))
.or_insert_with(|| child.clone());
self.traverse_children(&child)?;
visited.push(child.get_qualified_name());
self.traverse_children(&child, visited)?;
}
}
Ok(())
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
use crate::{archive_testtools::config::ArchiveType, common};
use crate::{
archive_testtools::{self, config::ArchiveType, utils},
common,
};
use actix_web::test;

#[actix_web::test]
async fn test_resolve_both_guarded_stele_law_html_request_with_full_path_expect_success() {
let archive_path = common::initialize_archive(ArchiveType::Multihost).unwrap();
let app = common::initialize_app(archive_path.path()).await;

for guard_value in ["stele_1/law", "stele_2/law"] {
for guard_value in [
"stele_1/law",
"stele_2/law",
"stele_1_1/law",
"stele_1_2/law",
] {
for request_uri in &["/a/b/c.html", "/a/b/", "/a/b/c/", "/a/d/"] {
let req = test::TestRequest::get()
.insert_header(("X-Current-Documents-Guard", guard_value))
Expand Down Expand Up @@ -53,7 +61,12 @@ async fn test_resolve_guarded_stele_law_html_request_where_header_name_is_incorr
async fn test_resolve_guarded_stele_law_rdf_request_content_expect_rdf_document_retrieved() {
let archive_path = common::initialize_archive(ArchiveType::Multihost).unwrap();
let app = common::initialize_app(archive_path.path()).await;
for guard_value in ["stele_1/law", "stele_2/law"] {
for guard_value in [
"stele_1/law",
"stele_2/law",
"stele_1_1/law",
"stele_1_2/law",
] {
for request_uri in &[
"/_rdf/index.rdf",
"/_rdf/a/b/c.rdf",
Expand All @@ -79,7 +92,46 @@ async fn test_resolve_guarded_stele_law_rdf_request_content_expect_rdf_document_
async fn test_law_other_data_request_content_expect_other_document_retrieved() {
let archive_path = common::initialize_archive(ArchiveType::Multihost).unwrap();
let app = common::initialize_app(archive_path.path()).await;
for guard_value in ["stele_1/law", "stele_2/law"] {
for guard_value in [
"stele_1/law",
"stele_2/law",
"stele_1_1/law",
"stele_1_2/law",
] {
for request_uri in &[
"/_prefix/a/index.html",
"/a/_doc/e/index.html",
"/a/e/_doc/f/index.html",
] {
let req = test::TestRequest::get()
.insert_header(("X-Current-Documents-Guard", guard_value))
.uri(request_uri)
.to_request();
let actual = test::call_and_read_body(&app, req).await;
let expected = "<!DOCTYPE html>";
assert!(
common::blob_to_string(actual.to_vec()).starts_with(expected),
"doesn't start with {expected}"
);
}
}
}

#[actix_web::test]
async fn test_law_other_data_request_content_with_cycle_expect_other_document_retrieved() {
let archive_path = common::initialize_archive_without_bare(ArchiveType::Multihost).unwrap();
// Add a cycle
// stele_1 -> stele_1_1 -> stele_1
// Expect that the cycle is resolved
archive_testtools::add_dependencies(archive_path.path(), "stele_1_1", vec!["stele_1"]).unwrap();
utils::make_all_git_repos_bare_recursive(&archive_path).unwrap();
let app = common::initialize_app(archive_path.path()).await;
for guard_value in [
"stele_1/law",
"stele_2/law",
"stele_1_1/law",
"stele_1_2/law",
] {
for request_uri in &[
"/_prefix/a/index.html",
"/a/_doc/e/index.html",
Expand Down
6 changes: 3 additions & 3 deletions tests/api/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
mod basic_archive_test;
mod multihost_archive_test;
mod multijurisdiction_archive_test;
mod archive_basic_test;
mod archive_multihost_test;
mod archive_multijursidiction_test;
2 changes: 1 addition & 1 deletion tests/archive_testtools/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ pub fn get_basic_test_data_repositories() -> Result<Vec<TestDataRepositoryContex
TestDataRepositoryContext::default_other_paths(),
TestDataRepositoryType::Other("example.json".to_string()),
None,
Some(vec![".*_doc/.*".into(), "_prefix/.*".into()]),
Some(vec![".*/_doc/.*".into(), "_prefix/.*".into()]),
true,
)?,
])
Expand Down
26 changes: 26 additions & 0 deletions tests/archive_testtools/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,32 @@ fn initialize_archive_multihost(td: &TempDir) -> Result<()> {
vec![stele_1_org_name, stele_2_org_name],
)?;

let stele_1_1_org_name = "stele_1_1";

initialize_stele(
td.path().to_path_buf(),
stele_1_1_org_name,
get_basic_test_data_repositories().unwrap().as_slice(),
None,
)
.unwrap();

let stele_1_2_org_name = "stele_1_2";

initialize_stele(
td.path().to_path_buf(),
stele_1_2_org_name,
get_basic_test_data_repositories().unwrap().as_slice(),
None,
)
.unwrap();

// Add stele_1_1 and stele_1_2 as dependencies of stele_1
add_dependencies(
td.path(),
stele_1_org_name,
vec![stele_1_1_org_name, stele_1_2_org_name],
)?;
Ok(())
}

Expand Down
42 changes: 23 additions & 19 deletions tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,33 +56,37 @@ pub async fn initialize_app(
}

pub fn initialize_archive(archive_type: ArchiveType) -> Result<tempfile::TempDir> {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("tests/fixtures/");

let td = Builder::new().tempdir_in(&path).unwrap();

match archive_testtools::initialize_archive_inner(archive_type, &td) {
Ok(_) => {
match initialize_archive_without_bare(archive_type) {
Ok(td) => {
if let Err(err) = utils::make_all_git_repos_bare_recursive(&td) {
return Err(err);
}
Ok(td)
}
Err(err) => {
dbg!(&err);
use std::mem::ManuallyDrop;
let td = ManuallyDrop::new(td);
// TODO: better error handling on testing failure
let error_output_directory = path.clone().join(PathBuf::from("error_output_directory"));
std::fs::remove_dir_all(&error_output_directory).unwrap();
std::fs::rename(td.path(), &error_output_directory)
.expect("Failed to move temp directory");
eprintln!(
Err(err) => Err(err),
}
}

pub fn initialize_archive_without_bare(archive_type: ArchiveType) -> Result<tempfile::TempDir> {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.push("tests/fixtures/");

let td = Builder::new().tempdir_in(&path).unwrap();

if let Err(err) = archive_testtools::initialize_archive_inner(archive_type, &td) {
dbg!(&err);
use std::mem::ManuallyDrop;
let td = ManuallyDrop::new(td);
// TODO: better error handling on testing failure
let error_output_directory = path.clone().join(PathBuf::from("error_output_directory"));
std::fs::remove_dir_all(&error_output_directory).unwrap();
std::fs::rename(td.path(), &error_output_directory).expect("Failed to move temp directory");
eprintln!(
"{}", format!("Failed to remove '{error_output_directory:?}', please try to remove directory by hand. Original error: {err}")
);
Err(err)
}
return Err(err);
}
Ok(td)
}

/// Used to initialize the test environment for git micro-server.
Expand Down
Loading