Skip to content

Commit

Permalink
initial support for listing test artifacts
Browse files Browse the repository at this point in the history
  • Loading branch information
DolceTriade committed Jan 5, 2024
1 parent 742b6bd commit 5ec59a2
Show file tree
Hide file tree
Showing 13 changed files with 848 additions and 7 deletions.
4 changes: 4 additions & 0 deletions blade/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ rust_binary(
"@crate//:tokio-stream",
"@crate//:url",
"@crate//:url-escape",
"@crate//:zip",
"@crate__wasm-bindgen-0.2.87//:wasm_bindgen",
"@crate__web-sys-0.3.64//:web_sys",
"@rules_rust//tools/runfiles",
Expand Down Expand Up @@ -87,6 +88,7 @@ rust_shared_library(
"@wasm_crate//:console_log",
"@wasm_crate//:futures",
"@wasm_crate//:futures-util",
"@wasm_crate//:gloo-file",
"@wasm_crate//:gloo-net",
"@wasm_crate//:junit-parser",
"@wasm_crate//:leptos",
Expand All @@ -98,6 +100,7 @@ rust_shared_library(
"@wasm_crate//:url",
"@wasm_crate//:url-escape",
"@wasm_crate//:wasm-bindgen",
"@wasm_crate//:zip",
"@wasm_crate__web-sys-0.3.64//:web_sys",
],
)
Expand Down Expand Up @@ -157,4 +160,5 @@ oci_push(
image = ":blade_image",
remote_tags = ":tags",
repository = "ghcr.io/dolcetriade/blade",
tags = ["noosx"],
)
3 changes: 2 additions & 1 deletion blade/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ pub mod testsummary;
pub mod testrunlist;
pub mod tooltip;
pub mod testresults;
pub mod searchbar;
pub mod searchbar;
pub mod testartifactlist;
2 changes: 1 addition & 1 deletion blade/components/nav.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub fn Nav(
view! {
<nav class="border-gray-200 bg-gray-50 dark:bg-gray-800 dark:border-gray-700">
<div class="flex flex-wrap items-center justify-between mx-auto p-4">
<a href="#" class="flex items-center rtl:space-x-reverse">
<a href="" class="flex items-center rtl:space-x-reverse">
<img class="hover:animate-spin" src=move || logo.get() class="w-14" alt="Logo"/>
<span class="self-center text-4xl font-semibold whitespace-nowrap dark:text-white">
{move || name.get()}
Expand Down
121 changes: 121 additions & 0 deletions blade/components/testartifactlist.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use leptos::*;
use leptos_router::*;

use crate::components::list::*;

#[derive(Debug, Clone)]
#[allow(dead_code)]
struct UndeclaredOutput {
pub name: String,
pub size: String,
pub kind: String,
pub uri: String,
}

#[allow(non_snake_case)]
#[component]
pub fn TestArtifactList() -> impl IntoView {
let test_run = expect_context::<Memo<Option<state::TestRun>>>();
let manifest = create_local_resource(
move || test_run.with(|test_run| test_run.as_ref().map(|test_run| test_run.files.clone())),
move |files| async move {
let files = files?;
let uri = files.get("test.outputs_manifest__MANIFEST")?.uri.clone();
let zip_uri = &files.get("test.outputs__outputs.zip")?.uri;
crate::routes::test::get_artifact(uri)
.await
.ok()
.as_ref()
.and_then(|v| {
let manifest = String::from_utf8_lossy(v);
let lines = manifest.split('\n').collect::<Vec<_>>();
let mut out = vec![];
for l in lines {
if l.is_empty() {
continue;
}
let items = l.split('\t').collect::<Vec<_>>();
let name = items.first()?;
let size = items.get(1)?;
let kind = items.get(2)?;
out.push(UndeclaredOutput {
name: name.to_string(),
size: size.to_string(),
kind: kind.to_string(),
uri: zip_uri.clone(),
});
}
if out.is_empty() {
return None;
}
Some(out)
})
},
);

view! {
<Suspense>
{move || match manifest.with(|manifest| manifest.as_ref().map(|o| o.is_some())) {
Some(true) => {
view! {
<h1 class="font-bold text-lg">Undeclared Outputs</h1>
<List>
<For
each=move || {
manifest.with(|manifest| manifest.clone().flatten().unwrap())
}

key=move |r| r.name.clone()
children=move |r| {
let query = format!(
"../artifact?{}",
url_escape::encode_query(
&format!("uri={}&zip={}", r.uri, r.name),
),
);
view! {
<ListItem hide=Signal::derive(|| false)>
<A href=query>
{format!("{} -- ({} bytes)", r.name, r.size)}
</A>
</ListItem>
}
}
/>

</List>
}
.into_view()
}
_ => view! {}.into_view(),
}}

</Suspense>

<h1 class="font-bold text-lg">Artifacts</h1>
<List>
<For
each=move || {
test_run
.with(|test_run| {
test_run.as_ref().map(|tr| tr.files.clone()).unwrap_or_default()
})
}

key=move |r| r.1.uri.clone()
children=move |r| {
let query = format!(
"../artifact?{}",
url_escape::encode_query(&format!("uri={}", r.1.uri)),
);
view! {
<ListItem hide=Signal::derive(|| false)>
<A href=query>{r.0.clone()}</A>
</ListItem>
}
}
/>

</List>
}
}
1 change: 1 addition & 0 deletions blade/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ pub mod empty;
pub mod invocation;
pub mod summary;
pub mod test;
pub mod artifact;
2 changes: 2 additions & 0 deletions blade/routes/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use crate::routes::empty::Empty;
use crate::routes::invocation::Invocation;
use crate::routes::summary::Summary;
use crate::routes::test::Test;
use crate::routes::artifact::Artifact;
use leptos::*;
use leptos_meta::*;
use leptos_router::*;
Expand All @@ -20,6 +21,7 @@ pub fn App() -> impl IntoView {
<Route path="invocation/:id" view=Invocation>
<Route path="*any" view=Summary/>
<Route path="test" view=Test/>
<Route path="artifact" view=Artifact/>
</Route>
<Route path="*" view=Empty/>
</Routes>
Expand Down
48 changes: 48 additions & 0 deletions blade/routes/artifact.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use std::io::{Cursor, prelude::Read};

use leptos::*;
use leptos_router::*;

use crate::components::shellout::ShellOut;

#[derive(PartialEq, Params, Debug, Clone)]
struct ArtifactParams {
uri: Option<String>,
zip: Option<String>,
}

fn stringify(e: impl std::fmt::Debug) -> String {
format!("{e:#?}")
}

#[component]
pub fn Artifact() -> impl IntoView {
let params = use_query::<ArtifactParams>();
let artifact = create_local_resource(move || params.get(),
move |params| async move {
let uri = params.as_ref().map_err(stringify)?.uri.clone().ok_or("missing params".to_string())?;
let zip = params.as_ref().map_err(stringify)?.zip.as_ref();
let bytes = crate::routes::test::get_artifact(uri).await.map_err(stringify)?;
if let Some(zip) = zip {
let cur = Cursor::new(bytes);
let mut arc = zip::ZipArchive::new(cur).map_err(stringify)?;
let mut file = arc.by_name(zip).map_err(stringify)?;
let mut out = "".to_string();
file.read_to_string(&mut out).map_err(stringify)?;
log::info!("{}", out);
return Ok::<String, String>(out);
}
Ok(String::from_utf8_lossy(&bytes).to_string())
});
view! {
<div class="h-[80vh] flex items-start justify-start justify-items-center overflow-auto overflow-x-auto">
<Suspense fallback=move || view! { <div>Loading...</div> }>
<ShellOut text=match artifact.get() {
Some(Ok(t)) => t,
Some(Err(t)) => t,
None => "RIP".into(),
}/>
</Suspense>
</div>
}
}
2 changes: 2 additions & 0 deletions blade/routes/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use crate::components::shellout::ShellOut;
use crate::components::testresults::TestResults;
use crate::components::testrunlist::TestRunList;
use crate::components::testsummary::TestSummary;
use crate::components::testartifactlist::TestArtifactList;

#[cfg(feature = "ssr")]
use std::sync::Arc;
Expand Down Expand Up @@ -207,6 +208,7 @@ pub fn Test() -> impl IntoView {
_ => view!{ <div>No test output</div> },
}}
</Suspense>
<TestArtifactList />
</Card>
</div>
</div>
Expand Down
Loading

0 comments on commit 5ec59a2

Please sign in to comment.