Move echo_server to tests
This commit is contained in:
81
test/echo_server.gleam
Normal file
81
test/echo_server.gleam
Normal file
@@ -0,0 +1,81 @@
|
||||
import gleam/erlang/process.{type Subject}
|
||||
import gleam/io
|
||||
import gleam/otp/actor
|
||||
import gleam/result
|
||||
import gleam/string
|
||||
|
||||
import tcp/reason.{type Reason}
|
||||
import tcp/tcp
|
||||
|
||||
pub type Message {
|
||||
Shutdown
|
||||
ReadyToAccept(subject: Subject(Message), listen_socket: tcp.Socket)
|
||||
}
|
||||
|
||||
pub fn new(socket_path: String) -> Result(tcp.Socket, String) {
|
||||
let server = actor.new(Nil) |> actor.on_message(handle_message) |> actor.start
|
||||
|
||||
case tcp.listen(socket_path), server {
|
||||
Error(r), _ -> Error(reason.to_string(r))
|
||||
_, Error(start_error) ->
|
||||
case start_error {
|
||||
actor.InitExited(_) -> Error("InitExited")
|
||||
actor.InitFailed(_) -> Error("InitFailed")
|
||||
actor.InitTimeout -> Error("InitTimeout")
|
||||
}
|
||||
Ok(listen_socket), Ok(b) -> {
|
||||
let subject = b.data
|
||||
actor.send(subject, ReadyToAccept(subject, listen_socket))
|
||||
Ok(listen_socket)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_message(_: Nil, message: Message) -> actor.Next(Nil, Message) {
|
||||
case message {
|
||||
Shutdown -> actor.stop()
|
||||
|
||||
ReadyToAccept(subject, listen_socket) -> {
|
||||
case tcp.accept(listen_socket) {
|
||||
Error(r) ->
|
||||
actor.stop_abnormal(
|
||||
"Could not accept connection :" <> reason.to_string(r),
|
||||
)
|
||||
Ok(socket) -> {
|
||||
case receive_from_connection(socket) {
|
||||
Error(r) ->
|
||||
io.println_error(
|
||||
"Failed to receive from connection :" <> reason.to_string(r),
|
||||
)
|
||||
Ok(_) -> Nil
|
||||
}
|
||||
|
||||
actor.send(subject, ReadyToAccept(subject, listen_socket))
|
||||
actor.continue(Nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn receive_from_connection(socket: tcp.Socket) -> Result(Nil, Reason) {
|
||||
result.try(receive_until_closed(socket, ""), fn(data) {
|
||||
let _ = tcp.send(socket, data)
|
||||
tcp.close(socket)
|
||||
Ok(Nil)
|
||||
})
|
||||
}
|
||||
|
||||
fn receive_until_closed(
|
||||
socket: tcp.Socket,
|
||||
result: String,
|
||||
) -> Result(String, Reason) {
|
||||
case tcp.receive(socket, 10_000) {
|
||||
Error(reason.Closed) -> Ok(result)
|
||||
Error(err) -> Error(err)
|
||||
Ok(data) -> {
|
||||
let result = data |> string.append(result, _)
|
||||
receive_until_closed(socket, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,5 @@
|
||||
import gleam/list
|
||||
import gleeunit
|
||||
import simplifile
|
||||
|
||||
import tcp/echo_server
|
||||
import tcp/tcp
|
||||
|
||||
pub fn main() -> Nil {
|
||||
gleeunit.main()
|
||||
}
|
||||
|
||||
pub fn tcp_send_shutdown_receive_test() {
|
||||
let socket_path = "/tmp/musicplayer-test.sock"
|
||||
|
||||
let assert Ok(_) = echo_server.new(socket_path)
|
||||
let assert Ok(socket) = tcp.connect(socket_path)
|
||||
|
||||
let messages = ["hello, ", "world!\n"]
|
||||
list.each(messages, fn(message) {
|
||||
let assert Ok(_) = tcp.send(socket, message)
|
||||
})
|
||||
|
||||
let assert Ok(_) = tcp.shutdown(socket)
|
||||
|
||||
let timeout_ms = 100
|
||||
assert Ok("hello, world!\n") == tcp.receive(socket, timeout_ms)
|
||||
|
||||
// TODO find better way to always do cleanup
|
||||
simplifile.delete(socket_path)
|
||||
}
|
||||
|
||||
30
test/tcp/tcp_test.gleam
Normal file
30
test/tcp/tcp_test.gleam
Normal file
@@ -0,0 +1,30 @@
|
||||
import gleam/list
|
||||
import gleeunit
|
||||
import simplifile
|
||||
|
||||
import echo_server
|
||||
import tcp/tcp
|
||||
|
||||
pub fn main() -> Nil {
|
||||
gleeunit.main()
|
||||
}
|
||||
|
||||
pub fn tcp_send_shutdown_receive_test() {
|
||||
let socket_path = "/tmp/musicplayer-test.sock"
|
||||
|
||||
let assert Ok(_) = echo_server.new(socket_path)
|
||||
let assert Ok(socket) = tcp.connect(socket_path)
|
||||
|
||||
let messages = ["hello, ", "world!\n"]
|
||||
list.each(messages, fn(message) {
|
||||
let assert Ok(_) = tcp.send(socket, message)
|
||||
})
|
||||
|
||||
let assert Ok(_) = tcp.shutdown(socket)
|
||||
|
||||
let timeout_ms = 100
|
||||
assert Ok("hello, world!\n") == tcp.receive(socket, timeout_ms)
|
||||
|
||||
// TODO find better way to always do cleanup
|
||||
simplifile.delete(socket_path)
|
||||
}
|
||||
Reference in New Issue
Block a user