108 lines
4.2 KiB
C++
108 lines
4.2 KiB
C++
|
|
// Step 1937: Sprint 281 Integration — Python+Rust DAP session
|
||
|
|
//
|
||
|
|
// Scenario: a Python service calling into Rust.
|
||
|
|
// - Adapters registered for Python and Rust.
|
||
|
|
// - Breakpoints on "computeSum" node in both languages.
|
||
|
|
// - A stopped event is broadcast; handlers in both adapters receive it.
|
||
|
|
// - Breakpoint hit on Rust source dispatches router to Rust.
|
||
|
|
// - DAP request validation confirms well-formed messages throughout.
|
||
|
|
// - Sprint281IntegrationSummary reports 5 steps complete.
|
||
|
|
//
|
||
|
|
// t1: validator accepts all well-formed DAP messages in the session
|
||
|
|
// t2: capability negotiator routes commands to correct adapter
|
||
|
|
// t3: event broadcaster delivers stopped event to both subscribers
|
||
|
|
// t4: hit dispatcher routes server.rs:42 hit to Rust adapter
|
||
|
|
// t5: Sprint281IntegrationSummary reports success
|
||
|
|
|
||
|
|
#include "DAPRequestValidator.h"
|
||
|
|
#include "DAPCapabilityNegotiator.h"
|
||
|
|
#include "DAPEventBroadcaster.h"
|
||
|
|
#include "DAPBreakpointHitDispatcher.h"
|
||
|
|
#include "ASTNodeBreakpointMapper.h"
|
||
|
|
#include "DebugAdapterRouter.h"
|
||
|
|
#include "Sprint281IntegrationSummary.h"
|
||
|
|
#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::DebugAdapterRouter makeRouter() {
|
||
|
|
ws::DebugAdapterRouter r;
|
||
|
|
r.registerAdapter("Python", {"stackTrace","stepIn","next","continue"});
|
||
|
|
r.registerAdapter("Rust", {"stackTrace","next","continue"});
|
||
|
|
r.setActiveLanguage("Python");
|
||
|
|
return r;
|
||
|
|
}
|
||
|
|
|
||
|
|
void t1(){
|
||
|
|
T(validator_accepts_session_messages);
|
||
|
|
ws::DAPRequestValidator v;
|
||
|
|
nlohmann::json launch = {{"type","request"}, {"seq",1},{"command","launch"}};
|
||
|
|
nlohmann::json resp = {{"type","response"},{"seq",1},{"command","launch"}};
|
||
|
|
nlohmann::json stopped = {{"type","event"}, {"seq",2},{"event","stopped"}};
|
||
|
|
C(v.validate(launch).valid, "launch request valid");
|
||
|
|
C(v.validate(resp).valid, "launch response valid");
|
||
|
|
C(v.validate(stopped).valid, "stopped event valid");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
void t2(){
|
||
|
|
T(capability_negotiator_routes_commands);
|
||
|
|
ws::DAPCapabilityNegotiator n;
|
||
|
|
n.registerAdapter("Python", {"stackTrace","stepIn","next","continue"});
|
||
|
|
n.registerAdapter("Rust", {"stackTrace","next","continue"});
|
||
|
|
C(n.selectAdapter("stepIn", "Python") == "Python", "Python selected for stepIn");
|
||
|
|
C(n.selectAdapter("stepIn", "Rust") != "Rust", "Rust not selected for stepIn");
|
||
|
|
C(n.selectAdapter("next", "Rust") == "Rust", "Rust selected for next");
|
||
|
|
C(n.languagesFor("stackTrace").size() == 2, "both langs support stackTrace");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
void t3(){
|
||
|
|
T(broadcaster_delivers_stopped_to_subscribers);
|
||
|
|
ws::DAPEventBroadcaster b;
|
||
|
|
int pyCount = 0, rsCount = 0;
|
||
|
|
b.subscribe("stopped", [&](const nlohmann::json&){ ++pyCount; });
|
||
|
|
b.subscribe("stopped", [&](const nlohmann::json&){ ++rsCount; });
|
||
|
|
nlohmann::json ev = {{"type","event"},{"seq",2},{"event","stopped"},
|
||
|
|
{"body",{{"reason","breakpoint"}}}};
|
||
|
|
b.broadcastAll(ev);
|
||
|
|
C(pyCount == 1, "Python handler fired");
|
||
|
|
C(rsCount == 1, "Rust handler fired");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
void t4(){
|
||
|
|
T(hit_dispatcher_routes_rust_source_to_rust);
|
||
|
|
ws::ASTNodeBreakpointMapper mapper;
|
||
|
|
mapper.setBreakpoint("computeSum","Python","compute.py",15);
|
||
|
|
mapper.setBreakpoint("computeSum","Rust", "server.rs", 42);
|
||
|
|
auto router = makeRouter();
|
||
|
|
ws::DAPBreakpointHitDispatcher d;
|
||
|
|
auto r = d.dispatch("server.rs", 42, mapper, router);
|
||
|
|
C(r.dispatched, "dispatched");
|
||
|
|
C(r.language == "Rust", "language Rust");
|
||
|
|
C(router.getActiveLanguage() == "Rust","router set to Rust");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
void t5(){
|
||
|
|
T(sprint281_integration_summary);
|
||
|
|
ws::Sprint281IntegrationSummary s;
|
||
|
|
C(s.stepsCompleted == 5, "5 steps");
|
||
|
|
C(s.success, "success");
|
||
|
|
C(s.sprintName() == "Sprint 281: DAP Hardening", "name");
|
||
|
|
P();
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(){
|
||
|
|
std::cout << "Step 1937: Sprint 281 Integration\n";
|
||
|
|
t1(); t2(); t3(); t4(); t5();
|
||
|
|
std::cout << "\n" << p << "/" << (p+f) << " passed\n";
|
||
|
|
return f > 0 ? 1 : 0;
|
||
|
|
}
|