101 lines
3.7 KiB
Rust
101 lines
3.7 KiB
Rust
use std::sync::Arc;
|
|
use tonic::{Request, Response, Status};
|
|
use roto_runtime::RotoOwned;
|
|
use roto_tonic::{BufferPool, generated::helloworld::{Greeter, GreeterServer, OwnedHelloRequest, OwnedHelloReply, HelloReplyBuilder, HelloBuilder}};
|
|
use std::net::SocketAddr;
|
|
use tokio::net::TcpListener;
|
|
|
|
struct MyGreeter;
|
|
|
|
#[tonic::async_trait]
|
|
impl Greeter for MyGreeter {
|
|
async fn say_hello(&self, request: Request<OwnedHelloRequest>) -> std::result::Result<Response<OwnedHelloReply>, Status> {
|
|
let req = request.into_inner();
|
|
let hello_req = req.reader();
|
|
|
|
// Extract name from the nested Hello message in HelloRequest
|
|
let name = match hello_req.request() {
|
|
Ok(req_bytes) => {
|
|
let hello = roto_tonic::generated::helloworld::Hello::new(req_bytes).unwrap();
|
|
hello.name_or_default().unwrap().to_string()
|
|
},
|
|
Err(_) => "Unknown".to_string(),
|
|
};
|
|
|
|
// Build the Hello response message
|
|
let mut hello_buf = [0u8; 1024];
|
|
let mut hello_builder = HelloBuilder::builder(&mut hello_buf);
|
|
hello_builder = hello_builder.name(&format!("Hello, {}!", name))
|
|
.map_err(|e| Status::internal(format!("Build error: {:?}", e)))?;
|
|
|
|
let hello_bytes = hello_builder.finish()
|
|
.map_err(|e| Status::internal(format!("Finish error: {:?}", e)))?;
|
|
|
|
// Build the HelloReply message containing the Hello bytes
|
|
let mut reply_buf = [0u8; 1024];
|
|
let mut reply_builder = HelloReplyBuilder::builder(&mut reply_buf);
|
|
reply_builder = reply_builder.response(hello_bytes)
|
|
.map_err(|e| Status::internal(format!("Build error: {:?}", e)))?;
|
|
|
|
let reply_bytes = reply_builder.finish()
|
|
.map_err(|e| Status::internal(format!("Finish error: {:?}", e)))?;
|
|
|
|
Ok(Response::new(OwnedHelloReply {
|
|
data: reply_bytes.to_vec().into(),
|
|
}))
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_say_hello_handler() {
|
|
let greeter = MyGreeter;
|
|
|
|
// Manually construct a valid proto buffer for HelloRequest
|
|
// HelloRequest { request: Hello { name: "World" } }
|
|
let mut hello_buf = [0u8; 1024];
|
|
let mut hb = HelloBuilder::builder(&mut hello_buf);
|
|
hb = hb.name("World").unwrap();
|
|
let hello_bytes = hb.finish().unwrap();
|
|
|
|
let mut req_buf = [0u8; 1024];
|
|
let mut rb = roto_tonic::generated::helloworld::HelloRequestBuilder::builder(&mut req_buf);
|
|
rb = rb.request(hello_bytes).unwrap();
|
|
let req_bytes = rb.finish().unwrap();
|
|
|
|
let request = Request::new(OwnedHelloRequest {
|
|
data: req_bytes.to_vec().into(),
|
|
});
|
|
|
|
let response = greeter.say_hello(request).await.unwrap();
|
|
let reply = response.into_inner();
|
|
let reply_reader = reply.reader();
|
|
|
|
let response_msg_bytes = reply_reader.response().expect("Response field missing");
|
|
let response_msg = roto_tonic::generated::helloworld::Hello::new(response_msg_bytes).expect("Invalid Hello message");
|
|
|
|
assert_eq!(response_msg.name_or_default().unwrap(), "Hello, World!");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_server_start() {
|
|
let pool = Arc::new(BufferPool::new(1024));
|
|
let greeter = Arc::new(MyGreeter);
|
|
let server = GreeterServer::new(greeter, pool);
|
|
|
|
let addr = SocketAddr::from(([127, 0, 0, 1], 0));
|
|
let listener = TcpListener::bind(addr).await.unwrap();
|
|
let _local_addr = listener.local_addr().unwrap();
|
|
|
|
let server_handle = tokio::spawn(async move {
|
|
tonic::transport::Server::builder()
|
|
.add_service(server)
|
|
.serve_with_incoming(tokio_stream::wrappers::TcpListenerStream::new(listener))
|
|
.await
|
|
.unwrap();
|
|
});
|
|
|
|
// Just verify it can start without crashing
|
|
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
|
server_handle.abort();
|
|
}
|