Skip to content

Commit f41b241

Browse files
authored
Test Coverage: Deadlines (#62)
- Add comments about closing response channel on exception in Curl.jl - Remove unreachable exception case in Streaming.jl for response streaming - Add test coverage for deadlines
1 parent 4e9aeea commit f41b241

File tree

3 files changed

+58
-28
lines changed

3 files changed

+58
-28
lines changed

src/Curl.jl

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ function write_callback(
4242
GRPC_INTERNAL,
4343
"Recieved $(n) bytes from curl but only handled $(handled_n_bytes_total)",
4444
)
45+
# If we are response streaming unblock the task waiting on response_c
4546
!isnothing(req.response_c) && close(req.response_c)
4647
return typemax(Csize_t)
4748
end
@@ -129,7 +130,25 @@ function header_callback(
129130
end
130131
end
131132

132-
133+
function grpc_timeout_header_val(timeout::Real)
134+
if round(Int, timeout) == timeout
135+
timeout_secs = round(Int64, timeout)
136+
return "$(timeout_secs)S"
137+
end
138+
timeout *= 1000
139+
if round(Int, timeout) == timeout
140+
timeout_millisecs = round(Int64, timeout)
141+
return "$(timeout_millisecs)m"
142+
end
143+
timeout *= 1000
144+
if round(Int, timeout) == timeout
145+
timeout_microsecs = round(Int64, timeout)
146+
return "$(timeout_microsecs)u"
147+
end
148+
timeout *= 1000
149+
timeout_nanosecs = round(Int64, timeout)
150+
return "$(timeout_nanosecs)n"
151+
end
133152

134153
mutable struct gRPCRequest
135154
# CURL multi lock for exclusive access to the easy handle after its added to the multi
@@ -221,26 +240,6 @@ mutable struct gRPCRequest
221240
curl_easy_setopt(easy_handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2TLS)
222241
end
223242

224-
function grpc_timeout_header_val(timeout::Real)
225-
if round(Int, timeout) == timeout
226-
timeout_secs = round(Int64, timeout)
227-
return "$(timeout_secs)S"
228-
end
229-
timeout *= 1000
230-
if round(Int, timeout) == timeout
231-
timeout_millisecs = round(Int64, timeout)
232-
return "$(timeout_millisecs)m"
233-
end
234-
timeout *= 1000
235-
if round(Int, timeout) == timeout
236-
timeout_microsecs = round(Int64, timeout)
237-
return "$(timeout_microsecs)u"
238-
end
239-
timeout *= 1000
240-
timeout_nanosecs = round(Int64, timeout)
241-
return "$(timeout_nanosecs)n"
242-
end
243-
244243
headers = C_NULL
245244
headers = curl_slist_append(headers, "User-Agent: $(USER_AGENT)")
246245
headers = curl_slist_append(headers, "Content-Type: application/grpc+proto")
@@ -352,6 +351,7 @@ function handle_write(req::gRPCRequest, buf::Vector{UInt8})::Tuple{Int64, Union{
352351
GRPC_UNIMPLEMENTED,
353352
"Response was compressed but compression is not currently supported.",
354353
)
354+
# If we are response streaming unblock the task waiting on response_c
355355
!isnothing(req.response_c) && close(req.response_c)
356356
notify(req.ready)
357357
return n, nothing
@@ -360,6 +360,7 @@ function handle_write(req::gRPCRequest, buf::Vector{UInt8})::Tuple{Int64, Union{
360360
GRPC_RESOURCE_EXHAUSTED,
361361
"length-prefix longer than max_recieve_message_length: $(req.response_length) > $(req.max_recieve_message_length)",
362362
)
363+
# If we are response streaming unblock the task waiting on response_c
363364
!isnothing(req.response_c) && close(req.response_c)
364365
notify(req.ready)
365366
return n, nothing

src/Streaming.jl

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,11 +100,6 @@ function grpc_async_stream_response(
100100
catch ex
101101
if isa(ex, InvalidStateException)
102102

103-
elseif isa(ex, gRPCServiceCallException)
104-
if isnothing(req.ex)
105-
req.ex = ex
106-
notify(req.ready)
107-
end
108103
else
109104
if isnothing(req.ex)
110105
req.ex = ex

test/runtests.jl

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
using Test
2-
using ProtoBuf
1+
using Test
2+
using ProtoBuf
33
using gRPCClient
44
using Base.Threads
55

6+
# Import the timeout header formatting function for testing
7+
import gRPCClient: grpc_timeout_header_val, GRPC_DEADLINE_EXCEEDED
8+
69

710
function _get_test_host()
811
if "GRPC_TEST_SERVER_HOST" in keys(ENV)
@@ -345,5 +348,36 @@ include("gen/test/test_pb.jl")
345348
# end
346349
end
347350

351+
# @testset "Timeout Header Value Formatting" begin
352+
# Test integer seconds
353+
@test grpc_timeout_header_val(1) == "1S"
354+
355+
# Test milliseconds
356+
@test grpc_timeout_header_val(0.001) == "1m"
357+
358+
# Test microseconds
359+
@test grpc_timeout_header_val(0.000001) == "1u"
360+
361+
# Test nanoseconds
362+
@test grpc_timeout_header_val(0.0000001) == "100n"
363+
364+
# end
365+
366+
# @testset "Deadline - Very short timeout" begin
367+
# Test with an extremely short deadline that might timeout
368+
# Note: This test is timing-sensitive and might be flaky
369+
client = TestService_TestRPC_Client(_TEST_HOST, _TEST_PORT; deadline=0.000000001)
370+
371+
# Try to make a request - it might timeout depending on server response time
372+
try
373+
response = grpc_sync_request(client, TestRequest(1, zeros(UInt64, 1)))
374+
@test false
375+
catch ex
376+
# If it times out, verify it's an exception (CURL timeout or gRPC error)
377+
@test isa(ex, gRPCServiceCallException)
378+
@test ex.grpc_status == GRPC_DEADLINE_EXCEEDED
379+
end
380+
# end
381+
348382
grpc_shutdown()
349383
end

0 commit comments

Comments
 (0)