Skip to content

Commit 43d2d65

Browse files
authored
feat: Update testoperator dispatch for validation, version metric (spiceai#5349)
* feat: Update testoperator dispatch for validation, version metric * fix: Spiced version in test framework * fix: Print stderr if test framework fails spiced version * chore: Clippy
1 parent 4fdc81f commit 43d2d65

14 files changed

Lines changed: 126 additions & 3 deletions

File tree

.github/workflows/testoperator_dispatch.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ on:
2929
required: false
3030
type: boolean
3131
default: false
32+
validate:
33+
description: 'Validate results?'
34+
required: false
35+
type: boolean
36+
default: false
3237

3338
jobs:
3439
dispatch-tests:
@@ -62,7 +67,8 @@ jobs:
6267
testoperator dispatch \
6368
${{ github.event.inputs.test_files_path }} \
6469
--workflow ${{ github.event.inputs.workflow_type }} \
65-
--update-snapshots ${{ github.event.inputs.update_snapshots }}
70+
--update-snapshots ${{ github.event.inputs.update_snapshots }} \
71+
--validate=${{ github.event.inputs.validate }} \
6672
env:
6773
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
6874
SPICED_COMMIT: ${{ steps.setup-spiced.outputs.SPICED_COMMIT }}

crates/test-framework/src/metrics/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ impl StatisticsCollector<BTreeMap<String, Duration>, BTreeMap<String, Vec<Durati
293293
pub struct QueryMetrics<T: ExtendedMetrics, R: ExtendedMetrics> {
294294
pub run_id: Uuid,
295295
pub run_name: String,
296+
pub spiced_version: String,
296297
pub commit_sha: String,
297298
pub branch_name: String,
298299
pub test_type: TestType,
@@ -373,6 +374,7 @@ impl<T: ExtendedMetrics, R: ExtendedMetrics> QueryMetrics<T, R> {
373374

374375
let mut base_fields = vec![
375376
Field::new("run_id", DataType::Utf8, false),
377+
Field::new("spiced_version", DataType::Utf8, false),
376378
Field::new("run_name", DataType::Utf8, false),
377379
Field::new("commit_sha", DataType::Utf8, false),
378380
Field::new("branch_name", DataType::Utf8, false),
@@ -397,6 +399,7 @@ impl<T: ExtendedMetrics, R: ExtendedMetrics> QueryMetrics<T, R> {
397399

398400
let mut base_fields = vec![
399401
Field::new("run_id", DataType::Utf8, false),
402+
Field::new("spiced_version", DataType::Utf8, false),
400403
Field::new("started_at", DataType::Int64, false),
401404
Field::new("finished_at", DataType::Int64, false),
402405
Field::new("query_name", DataType::Utf8, false),
@@ -499,6 +502,7 @@ impl<T: ExtendedMetrics, R: ExtendedMetrics> QueryMetrics<T, R> {
499502
#[allow(clippy::cast_possible_wrap)]
500503
pub fn build_records(&self) -> Result<Vec<RecordBatch>> {
501504
let run_id = vec![self.run_id.to_string(); self.metrics.len()];
505+
let spiced_version = vec![self.spiced_version.clone(); self.metrics.len()];
502506

503507
let started_at = extract_metric_values!(self.metrics, started_at, as_i64);
504508
let finished_at = extract_metric_values!(self.metrics, finished_at, as_i64);
@@ -520,6 +524,7 @@ impl<T: ExtendedMetrics, R: ExtendedMetrics> QueryMetrics<T, R> {
520524

521525
let mut columns: Vec<ArrayRef> = vec![
522526
Arc::new(StringArray::from(run_id)),
527+
Arc::new(StringArray::from(spiced_version)),
523528
Arc::new(Int64Array::from(started_at)),
524529
Arc::new(Int64Array::from(finished_at)),
525530
Arc::new(StringArray::from(query_name)),
@@ -569,6 +574,7 @@ impl<T: ExtendedMetrics, R: ExtendedMetrics> QueryMetrics<T, R> {
569574
/// The record batch is a single row, representing the run as a whole - which can pass or fail separately from individual queries
570575
pub fn build_run(&self, status: QueryStatus) -> Result<Vec<RecordBatch>> {
571576
let run_id = vec![self.run_id.to_string()];
577+
let spiced_version = vec![self.spiced_version.to_string()];
572578
let run_name = vec![self.run_name.clone()];
573579
let commit_sha = vec![self.commit_sha.clone()];
574580
let branch_name = vec![self.branch_name.clone()];
@@ -602,6 +608,7 @@ impl<T: ExtendedMetrics, R: ExtendedMetrics> QueryMetrics<T, R> {
602608

603609
let mut columns: Vec<ArrayRef> = vec![
604610
Arc::new(StringArray::from(run_id)),
611+
Arc::new(StringArray::from(spiced_version)),
605612
Arc::new(StringArray::from(run_name)),
606613
Arc::new(StringArray::from(commit_sha)),
607614
Arc::new(StringArray::from(branch_name)),
@@ -650,11 +657,13 @@ pub trait MetricCollector<T: ExtendedMetrics, R: ExtendedMetrics> {
650657
fn start_time(&self) -> SystemTime;
651658
fn end_time(&self) -> SystemTime;
652659
fn name(&self) -> String;
660+
fn spiced_version(&self) -> Result<&str>;
653661
fn metrics(&self) -> Result<Vec<QueryMetric<T>>>;
654662
fn collect(&self, test_type: TestType) -> Result<QueryMetrics<T, R>> {
655663
Ok(QueryMetrics {
656664
run_id: uuid::Uuid::new_v4(),
657665
run_name: self.name(),
666+
spiced_version: self.spiced_version()?.to_string(),
658667
commit_sha: git::get_commit_sha(),
659668
branch_name: git::get_branch_name(),
660669
test_type,

crates/test-framework/src/spiced/mod.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ limitations under the License.
1515
*/
1616

1717
use std::{
18+
fmt::Display,
1819
path::PathBuf,
1920
process::{Child, Command},
2021
time::Duration,
@@ -28,9 +29,25 @@ use tempfile::TempDir;
2829

2930
use crate::{process::Process, utils::wait_until_true};
3031

32+
#[derive(Debug, Clone)]
33+
pub struct SpicedVersion(String);
34+
impl SpicedVersion {
35+
#[must_use]
36+
pub fn new(version: String) -> Self {
37+
Self(version)
38+
}
39+
}
40+
41+
impl Display for SpicedVersion {
42+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43+
write!(f, "{}", self.0)
44+
}
45+
}
46+
3147
pub struct SpicedInstance {
3248
child: Child,
3349
tempdir: TempDir,
50+
version: SpicedVersion,
3451
}
3552

3653
pub struct StartRequest {
@@ -113,13 +130,42 @@ impl SpicedInstance {
113130

114131
let tempdir = start_request.tempdir;
115132

133+
// Get spiced version
134+
let version_cmd = Command::new(start_request.spiced_path.clone())
135+
.arg("--version")
136+
.output()?;
137+
138+
if !version_cmd.status.success() {
139+
anyhow::bail!(
140+
"Failed to get spiced version: {}",
141+
String::from_utf8_lossy(&version_cmd.stderr)
142+
);
143+
}
144+
145+
let version = String::from_utf8_lossy(&version_cmd.stdout).to_string();
146+
// take just the v1.0.0 part of the version
147+
let version = match (version.contains('-'), version.contains('+')) {
148+
(true, _) => version.split('-').next().unwrap_or(&version).to_string(),
149+
(false, true) => version.split('+').next().unwrap_or(&version).to_string(),
150+
(false, false) => version,
151+
};
152+
116153
// Start the spiced instance
117154
let mut cmd = Command::new(start_request.spiced_path);
118155
cmd.current_dir(tempdir.path());
119156
cmd.arg("--telemetry-enabled=false");
120157
let child = cmd.spawn()?;
121158

122-
Ok(Self { child, tempdir })
159+
Ok(Self {
160+
child,
161+
tempdir,
162+
version: SpicedVersion::new(version),
163+
})
164+
}
165+
166+
#[must_use]
167+
pub fn version(&self) -> &str {
168+
self.version.0.as_str()
123169
}
124170

125171
#[must_use]

crates/test-framework/src/spicetest/datasets/mod.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,15 @@ impl MetricCollector<DatasetMetrics, NoExtendedMetrics> for SpiceTest<Completed>
384384
self.name.clone()
385385
}
386386

387+
fn spiced_version(&self) -> Result<&str> {
388+
let spiced_instance = self.spiced_instance.as_ref().ok_or(
389+
anyhow::anyhow!(
390+
"Spiced instance is not available. SpiceTest must be started before metrics can be collected."
391+
))?;
392+
393+
Ok(spiced_instance.version())
394+
}
395+
387396
fn metrics(&self) -> Result<Vec<QueryMetric<DatasetMetrics>>> {
388397
self.get_query_durations()
389398
.iter()
@@ -429,6 +438,15 @@ impl MetricCollector<NoExtendedMetrics, ThroughputMetrics> for SpiceTest<Complet
429438
self.name.clone()
430439
}
431440

441+
fn spiced_version(&self) -> Result<&str> {
442+
let spiced_instance = self.spiced_instance.as_ref().ok_or(
443+
anyhow::anyhow!(
444+
"Spiced instance is not available. SpiceTest must be started before metrics can be collected."
445+
))?;
446+
447+
Ok(spiced_instance.version())
448+
}
449+
432450
fn metrics(&self) -> Result<Vec<QueryMetric<NoExtendedMetrics>>> {
433451
self.get_query_durations()
434452
.iter()

crates/test-framework/src/spicetest/http/consistency.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,15 @@ impl MetricCollector<NoExtendedMetrics, NoExtendedMetrics> for SpiceTest<Complet
212212
self.name.clone()
213213
}
214214

215+
fn spiced_version(&self) -> Result<&str> {
216+
let spiced_instance = self.spiced_instance.as_ref().ok_or(
217+
anyhow::anyhow!(
218+
"Spiced instance is not available. SpiceTest must be started before metrics can be collected."
219+
))?;
220+
221+
Ok(spiced_instance.version())
222+
}
223+
215224
fn metrics(&self) -> Result<Vec<QueryMetric<NoExtendedMetrics>>> {
216225
self.state
217226
.result

crates/test-framework/src/spicetest/http/overhead.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,15 @@ impl MetricCollector<NoExtendedMetrics, NoExtendedMetrics> for SpiceTest<Complet
193193
self.name.clone()
194194
}
195195

196+
fn spiced_version(&self) -> Result<&str> {
197+
let spiced_instance = self.spiced_instance.as_ref().ok_or(
198+
anyhow::anyhow!(
199+
"Spiced instance is not available. SpiceTest must be started before metrics can be collected."
200+
))?;
201+
202+
Ok(spiced_instance.version())
203+
}
204+
196205
fn metrics(&self) -> Result<Vec<QueryMetric<NoExtendedMetrics>>> {
197206
let baseline = QueryMetric::new_from_durations(
198207
"baseline",

crates/test-framework/src/spicetest/vector_search/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,15 @@ impl MetricCollector<SearchScoreMetric, NoExtendedMetrics> for SpiceTest<Complet
149149
self.name.clone()
150150
}
151151

152+
fn spiced_version(&self) -> Result<&str> {
153+
let spiced_instance = self.spiced_instance.as_ref().ok_or(
154+
anyhow::anyhow!(
155+
"Spiced instance is not available. SpiceTest must be started before metrics can be collected."
156+
))?;
157+
158+
Ok(spiced_instance.version())
159+
}
160+
152161
fn metrics(&self) -> Result<Vec<QueryMetric<SearchScoreMetric>>> {
153162
self.state
154163
.results

tools/testoperator/dispatch/tpch/accelerated/file_arrow.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ tests:
33
spicepod_path: ./test/spicepods/tpch/accelerated/file_arrow.yaml
44
query_set: tpch
55
runner_type: spiceai-runners
6+
validate: true
67
throughput:
78
spicepod_path: ./test/spicepods/tpch/accelerated/file_arrow.yaml
89
query_set: tpch

tools/testoperator/dispatch/tpch/accelerated/file_duckdb_file.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ tests:
33
spicepod_path: ./test/spicepods/tpch/accelerated/file_duckdb_file.yaml
44
query_set: tpch
55
runner_type: spiceai-runners
6+
validate: true
67
throughput:
78
spicepod_path: ./test/spicepods/tpch/accelerated/file_duckdb_file.yaml
89
query_set: tpch

tools/testoperator/dispatch/tpch/accelerated/file_duckdb_memory.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ tests:
33
spicepod_path: ./test/spicepods/tpch/accelerated/file_duckdb_memory.yaml
44
query_set: tpch
55
runner_type: spiceai-runners
6+
validate: true
67
throughput:
78
spicepod_path: ./test/spicepods/tpch/accelerated/file_duckdb_memory.yaml
89
query_set: tpch

0 commit comments

Comments
 (0)