feat: unify object observation API
This commit is contained in:
@@ -11,17 +11,17 @@ use wip_fs_server::{AccessMode, ServerConfig, TransportSecurity, WipFsServer};
|
||||
use wip_https::{
|
||||
BatchRequest, BatchRequestItem, BatchRequestKind, BatchResponse, BatchSuccess, DecodedResponse,
|
||||
Endpoint, JSON_CONTENT_TYPE, Limits, Route, decode_batch_request, decode_batch_response,
|
||||
decode_call_operation_response, decode_fetch_interface_response, decode_fetch_response,
|
||||
decode_fetch_tree_response, encode_batch_request, encode_call_operation_request,
|
||||
encode_fetch_interface_request, encode_fetch_request, encode_fetch_tree_request,
|
||||
decode_call_operation_response, decode_fetch_interface_response, decode_observe_response,
|
||||
encode_batch_request, encode_call_operation_request, encode_fetch_interface_request,
|
||||
encode_observe_request,
|
||||
};
|
||||
use wip_protocol::{
|
||||
CallOperationRequest, FetchInterfaceRequest, FetchRequest, FetchTreeRequest, InterfaceTarget,
|
||||
CallOperationRequest, FetchInterfaceRequest, InterfaceTarget, ObserveRequest,
|
||||
ProtocolErrorCode, Target, Value,
|
||||
};
|
||||
|
||||
#[test]
|
||||
fn real_listener_serves_four_core_interactions_batch_and_write() {
|
||||
fn real_listener_serves_three_core_interactions_batch_and_write() {
|
||||
let temporary = tempdir().expect("temporary root");
|
||||
std::fs::write(temporary.path().join("hello.txt"), b"hello world").expect("write file");
|
||||
std::fs::create_dir(temporary.path().join("nested")).expect("create directory");
|
||||
@@ -46,32 +46,39 @@ fn real_listener_serves_four_core_interactions_batch_and_write() {
|
||||
let endpoint = Endpoint::parse(&format!("https://localhost:{}/wip", address.port()))
|
||||
.expect("client endpoint");
|
||||
|
||||
let file_request = FetchRequest {
|
||||
let file_request = ObserveRequest {
|
||||
path: "/hello.txt".into(),
|
||||
depth: 0,
|
||||
};
|
||||
let response = exchange(
|
||||
address,
|
||||
encode_fetch_request(&endpoint, &file_request, limits).expect("encode fetch"),
|
||||
encode_observe_request(&endpoint, &file_request, limits).expect("encode observation"),
|
||||
);
|
||||
let file =
|
||||
success(decode_fetch_response(&file_request, &response, limits).expect("decode fetch"));
|
||||
let file = success(
|
||||
decode_observe_response(&file_request, &response, limits).expect("decode observation"),
|
||||
)
|
||||
.object;
|
||||
assert_eq!(file.name, "hello.txt");
|
||||
assert_eq!(file.interfaces.len(), 2);
|
||||
assert!(file.validator.is_some());
|
||||
|
||||
let tree_request = FetchTreeRequest {
|
||||
let tree_request = ObserveRequest {
|
||||
path: "/".into(),
|
||||
depth: 1,
|
||||
limit: 10,
|
||||
};
|
||||
let response = exchange(
|
||||
address,
|
||||
encode_fetch_tree_request(&endpoint, &tree_request, limits).expect("encode tree"),
|
||||
encode_observe_request(&endpoint, &tree_request, limits).expect("encode tree"),
|
||||
);
|
||||
let tree =
|
||||
success(decode_fetch_tree_response(&tree_request, &response, limits).expect("decode tree"));
|
||||
assert!(!tree.truncated);
|
||||
assert_eq!(tree.root.children.len(), 2);
|
||||
success(decode_observe_response(&tree_request, &response, limits).expect("decode tree"));
|
||||
assert_eq!(
|
||||
tree.children
|
||||
.as_ref()
|
||||
.expect("root children observed")
|
||||
.len(),
|
||||
2
|
||||
);
|
||||
|
||||
let read_interface_request = FetchInterfaceRequest {
|
||||
interface: file.interfaces[0].clone(),
|
||||
@@ -122,14 +129,16 @@ fn real_listener_serves_four_core_interactions_batch_and_write() {
|
||||
requests: vec![
|
||||
BatchRequestItem {
|
||||
id: "root".into(),
|
||||
request: BatchRequestKind::Fetch(FetchRequest { path: "/".into() }),
|
||||
request: BatchRequestKind::Observe(ObserveRequest {
|
||||
path: "/".into(),
|
||||
depth: 0,
|
||||
}),
|
||||
},
|
||||
BatchRequestItem {
|
||||
id: "tree".into(),
|
||||
request: BatchRequestKind::FetchTree(FetchTreeRequest {
|
||||
request: BatchRequestKind::Observe(ObserveRequest {
|
||||
path: "/nested".into(),
|
||||
depth: 1,
|
||||
limit: 4,
|
||||
}),
|
||||
},
|
||||
BatchRequestItem {
|
||||
@@ -230,7 +239,7 @@ fn stalled_request_body_times_out_and_releases_the_only_worker() {
|
||||
.expect("set stalled read timeout");
|
||||
write!(
|
||||
stalled,
|
||||
"POST /wip/v1/fetch HTTP/1.1\r\nHost: localhost\r\nContent-Type: application/json\r\nAccept: application/json\r\nContent-Length: 100\r\n\r\n{{"
|
||||
"POST /wip/v1/observe HTTP/1.1\r\nHost: localhost\r\nContent-Type: application/json\r\nAccept: application/json\r\nContent-Length: 100\r\n\r\n{{"
|
||||
)
|
||||
.expect("write partial request");
|
||||
stalled.flush().expect("flush partial request");
|
||||
@@ -238,13 +247,17 @@ fn stalled_request_body_times_out_and_releases_the_only_worker() {
|
||||
|
||||
let endpoint = Endpoint::parse(&format!("https://localhost:{}/wip", address.port()))
|
||||
.expect("client endpoint");
|
||||
let fetch = FetchRequest { path: "/".into() };
|
||||
let observe = ObserveRequest {
|
||||
path: "/".into(),
|
||||
depth: 0,
|
||||
};
|
||||
let started = Instant::now();
|
||||
let response = exchange(
|
||||
address,
|
||||
encode_fetch_request(&endpoint, &fetch, limits).expect("encode fetch"),
|
||||
encode_observe_request(&endpoint, &observe, limits).expect("encode observation"),
|
||||
);
|
||||
let _root = success(decode_fetch_response(&fetch, &response, limits).expect("decode fetch"));
|
||||
let _root =
|
||||
success(decode_observe_response(&observe, &response, limits).expect("decode observation"));
|
||||
assert!(
|
||||
started.elapsed() < Duration::from_secs(1),
|
||||
"the valid request remained starved after the intake deadline"
|
||||
@@ -277,7 +290,7 @@ fn batch_keeps_known_malformed_arguments_item_local() {
|
||||
let limits = config.limits.wire;
|
||||
let server = WipFsServer::new(config).expect("build server");
|
||||
let endpoint = Endpoint::parse("https://localhost/wip").expect("endpoint");
|
||||
let body = br#"{"requests":[{"id":"ok","method":"fetch","arguments":{"path":"/"}},{"id":"bad","method":"fetch_tree","arguments":{"path":"/","depth":"bad","limit":1}}]}"#;
|
||||
let body = br#"{"requests":[{"id":"ok","method":"observe","arguments":{"path":"/","depth":0}},{"id":"bad","method":"observe","arguments":{"path":"/","depth":"bad"}}]}"#;
|
||||
let logical = decode_batch_request(body, limits).expect("decode item-local invalid request");
|
||||
assert!(matches!(
|
||||
logical.requests[1].request,
|
||||
@@ -296,7 +309,7 @@ fn batch_keeps_known_malformed_arguments_item_local() {
|
||||
);
|
||||
assert!(matches!(
|
||||
batch.responses[0].outcome,
|
||||
Ok(BatchSuccess::Fetch(_))
|
||||
Ok(BatchSuccess::Observe(_))
|
||||
));
|
||||
assert!(batch.responses[1].outcome.is_err());
|
||||
}
|
||||
@@ -331,13 +344,15 @@ fn backend_invalid_unicode_path_is_not_found_not_internal() {
|
||||
let limits = config.limits.wire;
|
||||
let server = WipFsServer::new(config).expect("build server");
|
||||
let endpoint = Endpoint::parse("https://localhost/wip").expect("endpoint");
|
||||
let request = FetchRequest {
|
||||
let request = ObserveRequest {
|
||||
path: "/bad\0name".into(),
|
||||
depth: 0,
|
||||
};
|
||||
let response = server
|
||||
.handle_http(encode_fetch_request(&endpoint, &request, limits).expect("encode fetch"));
|
||||
let response = server.handle_http(
|
||||
encode_observe_request(&endpoint, &request, limits).expect("encode observation"),
|
||||
);
|
||||
assert_eq!(response.status(), http::StatusCode::NOT_FOUND);
|
||||
match decode_fetch_response(&request, &response, limits).expect("decode missing response") {
|
||||
match decode_observe_response(&request, &response, limits).expect("decode missing response") {
|
||||
DecodedResponse::ProtocolFailure { error, .. } => {
|
||||
assert_eq!(error.code, ProtocolErrorCode::NotFound);
|
||||
}
|
||||
@@ -355,14 +370,17 @@ fn read_response_size_failure_preserves_non_commit_guarantee() {
|
||||
let server = WipFsServer::new(config).expect("build server");
|
||||
let endpoint = Endpoint::parse("https://localhost/wip").expect("endpoint");
|
||||
|
||||
let fetch_request = FetchRequest {
|
||||
let observe_request = ObserveRequest {
|
||||
path: "/large".into(),
|
||||
depth: 0,
|
||||
};
|
||||
let response = server.handle_http(
|
||||
encode_fetch_request(&endpoint, &fetch_request, limits).expect("encode fetch"),
|
||||
encode_observe_request(&endpoint, &observe_request, limits).expect("encode observation"),
|
||||
);
|
||||
let file =
|
||||
success(decode_fetch_response(&fetch_request, &response, limits).expect("decode fetch"));
|
||||
let file = success(
|
||||
decode_observe_response(&observe_request, &response, limits).expect("decode observation"),
|
||||
)
|
||||
.object;
|
||||
let interface_request = FetchInterfaceRequest {
|
||||
interface: file.interfaces[0].clone(),
|
||||
};
|
||||
@@ -405,11 +423,11 @@ fn assert_batch_successes(batch: &BatchResponse) {
|
||||
assert_eq!(batch.responses.len(), 3);
|
||||
assert!(matches!(
|
||||
batch.responses[0].outcome,
|
||||
Ok(BatchSuccess::Fetch(_))
|
||||
Ok(BatchSuccess::Observe(_))
|
||||
));
|
||||
assert!(matches!(
|
||||
batch.responses[1].outcome,
|
||||
Ok(BatchSuccess::FetchTree(_))
|
||||
Ok(BatchSuccess::Observe(_))
|
||||
));
|
||||
assert!(matches!(
|
||||
batch.responses[2].outcome,
|
||||
|
||||
Reference in New Issue
Block a user