PipelineStageSpec/Registry, PipelineGraph (Kahn topo sort), PipelineExecutionPlan, PipelineParityValidator — 26/26 tests pass. Integration step 1947: Python→Rust→Go→Haskell→TypeScript pipeline verified. Metrics: 7 whetstone calls, 8566 tokens. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
117 lines
4.4 KiB
C++
117 lines
4.4 KiB
C++
// Step 1947: Sprint 283 Integration — poly-pipeline
|
|
//
|
|
// 5-stage pipeline: Python(ingest)→Rust(normalize)→Go(fanout)→Haskell(transform)→TypeScript(serialize)
|
|
//
|
|
// t1: plan is valid, execution order correct, 4 boundary pairs
|
|
// t2: language sequence is Python Rust Go Haskell TypeScript
|
|
// t3: parity validation passes when all stage outputs match references
|
|
// t4: parity validation fails when one stage output is wrong
|
|
// t5: Sprint283IntegrationSummary reports 5 steps
|
|
|
|
#include "PipelineExecutionPlan.h"
|
|
#include "PipelineParityValidator.h"
|
|
#include "Sprint283IntegrationSummary.h"
|
|
#include <algorithm>
|
|
#include <iostream>
|
|
|
|
namespace ws = whetstone;
|
|
static int p=0,f=0;
|
|
#define T(n) { std::cout<<" "<<#n<<"... "; }
|
|
#define P() { std::cout<<"PASS\n"; ++p; }
|
|
#define F(m) { std::cout<<"FAIL: "<<m<<"\n"; ++f; }
|
|
#define C(c,m) if(!(c)){F(m);return;}
|
|
|
|
static ws::PipelineExecutionPlan makePipeline() {
|
|
ws::PipelineExecutionPlan p;
|
|
p.addStage({"ingest", "Python", "CSV ingestion", "csv", "records"});
|
|
p.addStage({"normalize", "Rust", "Data normalization", "records", "normed"});
|
|
p.addStage({"fanout", "Go", "Fan-out routing", "normed", "batches"});
|
|
p.addStage({"transform", "Haskell", "Statistical transform","batches", "results"});
|
|
p.addStage({"serialize", "TypeScript", "JSON serialization", "results", "json"});
|
|
p.addEdge("ingest","normalize");
|
|
p.addEdge("normalize","fanout");
|
|
p.addEdge("fanout","transform");
|
|
p.addEdge("transform","serialize");
|
|
return p;
|
|
}
|
|
|
|
void t1(){
|
|
T(pipeline_valid_and_boundary_pairs);
|
|
auto plan = makePipeline();
|
|
C(plan.isValid(), "pipeline valid");
|
|
auto pairs = plan.boundaryPairs();
|
|
C(pairs.size() == 4, "four boundary pairs");
|
|
bool hasPyRs = std::find(pairs.begin(),pairs.end(),"Python->Rust") != pairs.end();
|
|
bool hasRsGo = std::find(pairs.begin(),pairs.end(),"Rust->Go") != pairs.end();
|
|
bool hasGoHs = std::find(pairs.begin(),pairs.end(),"Go->Haskell") != pairs.end();
|
|
bool hasHsTs = std::find(pairs.begin(),pairs.end(),"Haskell->TypeScript") != pairs.end();
|
|
C(hasPyRs && hasRsGo && hasGoHs && hasHsTs, "all four language transitions");
|
|
P();
|
|
}
|
|
|
|
void t2(){
|
|
T(language_sequence_correct);
|
|
auto plan = makePipeline();
|
|
auto langs = plan.languageSequence();
|
|
C(langs.size() == 5, "five languages");
|
|
C(langs[0] == "Python", "Python first");
|
|
C(langs[1] == "Rust", "Rust second");
|
|
C(langs[2] == "Go", "Go third");
|
|
C(langs[3] == "Haskell", "Haskell fourth");
|
|
C(langs[4] == "TypeScript", "TypeScript fifth");
|
|
P();
|
|
}
|
|
|
|
void t3(){
|
|
T(parity_validation_all_pass);
|
|
ws::PipelineParityValidator v;
|
|
v.setReference("ingest", "row1,row2\n");
|
|
v.setReference("normalize", "norm1,norm2\n");
|
|
v.setReference("fanout", "batch1\n");
|
|
v.setReference("transform", "result1\n");
|
|
v.setReference("serialize", "{\"data\":1}\n");
|
|
std::vector<ws::StageOutput> outputs = {
|
|
{"ingest", "Python", "row1,row2\n", true},
|
|
{"normalize", "Rust", "norm1,norm2\n", true},
|
|
{"fanout", "Go", "batch1\n", true},
|
|
{"transform", "Haskell", "result1\n", true},
|
|
{"serialize", "TypeScript", "{\"data\":1}\n",true}
|
|
};
|
|
auto r = v.validate(outputs);
|
|
C(r.passed, "all pass");
|
|
C(r.failedStages.empty(),"no failures");
|
|
P();
|
|
}
|
|
|
|
void t4(){
|
|
T(parity_validation_fails_on_bad_stage);
|
|
ws::PipelineParityValidator v;
|
|
v.setReference("fanout","batch1\n");
|
|
v.setReference("transform","result1\n");
|
|
std::vector<ws::StageOutput> outputs = {
|
|
{"fanout", "Go", "WRONG\n", true},
|
|
{"transform", "Haskell","result1\n", true}
|
|
};
|
|
auto r = v.validate(outputs);
|
|
C(!r.passed, "not passed");
|
|
C(r.failedStages.size()==1,"one failure");
|
|
C(r.failedStages[0]=="fanout","fanout failed");
|
|
P();
|
|
}
|
|
|
|
void t5(){
|
|
T(sprint283_integration_summary);
|
|
ws::Sprint283IntegrationSummary s;
|
|
C(s.stepsCompleted == 5, "5 steps");
|
|
C(s.success, "success");
|
|
C(s.sprintName() == "Sprint 283: poly-pipeline","name");
|
|
P();
|
|
}
|
|
|
|
int main(){
|
|
std::cout << "Step 1947: Sprint 283 Integration\n";
|
|
t1(); t2(); t3(); t4(); t5();
|
|
std::cout << "\n" << p << "/" << (p+f) << " passed\n";
|
|
return f > 0 ? 1 : 0;
|
|
}
|