From f58f3cdb5c6b622fdcb636b58afff5c61b3f7609 Mon Sep 17 00:00:00 2001 From: "Tristan B. Velloza Kildaire" Date: Mon, 25 Sep 2023 14:36:38 +0200 Subject: [PATCH] CoapClient - Disabled normal `get()`-based tests for now (whilst I test the timeout-based ones) - Added unit test to test timeout-based `get(Duration)` CoapRequestFuture - Added documentation for `get(Duration)` - Fixed bug whereby the `Mutex` was NOT unlock after a failed `wait(Duration)` (a timedout one) --- source/doap/client/client.d | 55 ++++++++++++++++++++++++++++++++---- source/doap/client/request.d | 20 +++++++++++-- 2 files changed, 67 insertions(+), 8 deletions(-) diff --git a/source/doap/client/client.d b/source/doap/client/client.d index a38ffe7..c360df1 100644 --- a/source/doap/client/client.d +++ b/source/doap/client/client.d @@ -112,12 +112,16 @@ public class CoapClient this.messaging.close(); // Cancel all active request futures + writeln("Awaking any sleeping futures.... (for shutdown)"); this.requestsLock.lock(); foreach(CoapRequest curReq; outgoingRequests) { + writeln("Awaking any sleeping futures.... (for shutdown): ", curReq); curReq.future.cancel(); + writeln("Awaking any sleeping futures.... (for shutdown): ", curReq, " [done]"); } this.requestsLock.unlock(); + writeln("Awaking any sleeping futures.... (for shutdown) [done]"); } /** @@ -301,6 +305,37 @@ version(unittest) * and `client` module. */ unittest +{ + // CoapClient client = new CoapClient("coap.me", 5683); + + + // CoapRequestFuture future = client.newRequestBuilder() + // .payload(cast(ubyte[])"Hello this is Tristan!") + // .token([69]) + // .post(); + + + // writeln("Future start"); + // CoapPacket response = future.get(); + // writeln("Future done"); + // writeln("Got response: ", response); + + // client.close(); +} + +version(unittest) +{ + import core.time : dur; + import doap.client.exceptions : RequestTimeoutException; +} + +/** + * Client testing + * + * See above except we test a timeout-based + * request future here. + */ +unittest { CoapClient client = new CoapClient("coap.me", 5683); @@ -309,12 +344,22 @@ unittest .payload(cast(ubyte[])"Hello this is Tristan!") .token([69]) .post(); + + try + { + writeln("Future start"); + CoapPacket response = future.get(dur!("msecs")(10)); + // We should timeout and NOT get here + assert(false); + } + catch(RequestTimeoutException e) + { + // We SHOULD time out + assert(true); + } - writeln("Future start"); - CoapPacket response = future.get(); - writeln("Future done"); - writeln("Got response: ", response); - + writeln("Closing client..."); client.close(); + writeln("Client closed"); } \ No newline at end of file diff --git a/source/doap/client/request.d b/source/doap/client/request.d index 653b83a..b8d709e 100644 --- a/source/doap/client/request.d +++ b/source/doap/client/request.d @@ -400,18 +400,32 @@ public class CoapRequestFuture } } + /** + * Blocks until the response is received + * but will unbllock if the timeout given + * is exceeded + * + * Returns: the response as a `CoapPacket` + * Throws: + * RequestTimeoutException = on the + * future request timing out + */ public CoapPacket get(Duration timeout) { // We can only wait on a condition if we // ... first have a-hold of the lock this.mutex.lock(); + scope(exit) + { + // Unlock the lock (either from successfully + // ... waiting or timing out) + this.mutex.unlock(); + } + // Await a response if(this.condition.wait(timeout)) { - // Upon waking up release lock - this.mutex.unlock(); - return this.response; } else