Skip to content

Commit 8ab63da

Browse files
📝 Add docstrings to feat-multi-url
Docstrings generation was requested by @ideoma. * #59 (comment) The following files were modified: * `src/dummy-http-server/DummyHttpServer.cs` * `src/dummy-http-server/IlpEndpoint.cs` * `src/net-questdb-client-tests/QuestDbManager.cs` * `src/net-questdb-client/Buffers/BufferV1.cs` * `src/net-questdb-client/Buffers/IBuffer.cs` * `src/net-questdb-client/Senders/AbstractSender.cs` * `src/net-questdb-client/Senders/HttpSender.cs` * `src/net-questdb-client/Senders/ISender.cs` * `src/net-questdb-client/Utils/AddressProvider.cs` * `src/net-questdb-client/Utils/SenderOptions.cs`
1 parent 4ae71aa commit 8ab63da

File tree

10 files changed

+404
-34
lines changed

10 files changed

+404
-34
lines changed

src/dummy-http-server/DummyHttpServer.cs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,15 @@ public class DummyHttpServer : IDisposable
5555
/// <param name="withRetriableError">If true, configure the test endpoint to produce retriable error responses.</param>
5656
/// <param name="withErrorMessage">If true, include error messages in test error responses.</param>
5757
/// <param name="withStartDelay">Optional delay applied when starting the server.</param>
58-
/// <param name="requireClientCert">If true, require client TLS certificates for HTTPS connections.</param>
58+
/// <summary>
59+
/// Creates a test in-process HTTP server configured for FastEndpoints with optional authentication, error behaviors, startup delay, and client TLS certificate requirement.
60+
/// </summary>
61+
/// <param name="withTokenAuth">Enable JWT bearer authentication and related authorization checks for endpoints.</param>
62+
/// <param name="withBasicAuth">Enable basic-like username/password validation on test endpoints.</param>
63+
/// <param name="withRetriableError">Make certain endpoints return retriable error responses to simulate transient failures.</param>
64+
/// <param name="withErrorMessage">Include error messages in responses for endpoints that simulate failures.</param>
65+
/// <param name="withStartDelay">Optional delay applied at startup; pass null for no delay.</param>
66+
/// <param name="requireClientCert">Require client TLS certificates for HTTPS connections when true.</param>
5967
public DummyHttpServer(bool withTokenAuth = false, bool withBasicAuth = false, bool withRetriableError = false,
6068
bool withErrorMessage = false, TimeSpan? withStartDelay = null, bool requireClientCert = false)
6169
{
@@ -143,7 +151,9 @@ public void Dispose()
143151
/// <remarks>
144152
/// Empties IlpEndpoint.ReceiveBuffer and IlpEndpoint.ReceiveBytes, sets IlpEndpoint.LastError to null,
145153
/// and sets IlpEndpoint.Counter to zero.
146-
/// </remarks>
154+
/// <summary>
155+
/// Clears in-memory receive buffers, counters, and any recorded error state for this server instance's configured port.
156+
/// </summary>
147157
public void Clear()
148158
{
149159
IlpEndpoint.ClearPort(_port);
@@ -154,6 +164,11 @@ public void Clear()
154164
/// </summary>
155165
/// <param name="port">Port to listen on (defaults to 29743).</param>
156166
/// <param name="versions">Array of supported protocol versions; defaults to {1, 2, 3} when null.</param>
167+
/// <summary>
168+
/// Starts the server on the specified port, initializes per-port test configuration, and begins the app's background run task.
169+
/// </summary>
170+
/// <param name="port">The TCP port the server will listen on.</param>
171+
/// <param name="versions">Protocol or API versions to expose; assigned to <c>SettingsEndpoint.Versions</c>. If null, defaults to {1, 2, 3}.</param>
157172
/// <returns>A task that completes after any configured startup delay has elapsed and the server's background run task has been initiated.</returns>
158173
public async Task StartAsync(int port = 29743, int[]? versions = null)
159174
{
@@ -195,7 +210,10 @@ public async Task StopAsync()
195210
/// <summary>
196211
/// Gets the server's in-memory text buffer of received data.
197212
/// </summary>
198-
/// <returns>The mutable <see cref="StringBuilder"/> containing the accumulated received text; modifying it updates the server's buffer.</returns>
213+
/// <summary>
214+
/// Gets the server instance's accumulated received-text buffer for the configured port.
215+
/// </summary>
216+
/// <returns>The mutable <see cref="StringBuilder"/> containing the accumulated received text for this port; modifying it updates the server's buffer.</returns>
199217
public StringBuilder GetReceiveBuffer()
200218
{
201219
return IlpEndpoint.GetReceiveBuffer(_port);
@@ -204,17 +222,28 @@ public StringBuilder GetReceiveBuffer()
204222
/// <summary>
205223
/// Gets the in-memory list of bytes received by the ILP endpoint.
206224
/// </summary>
207-
/// <returns>The mutable list of bytes received by the endpoint.</returns>
225+
/// <summary>
226+
/// Retrieve the mutable list of raw bytes received by this server instance's endpoint.
227+
/// </summary>
228+
/// <returns>The mutable list of bytes received by the endpoint for the current port.</returns>
208229
public List<byte> GetReceivedBytes()
209230
{
210231
return IlpEndpoint.GetReceiveBytes(_port);
211232
}
212233

234+
/// <summary>
235+
/// Retrieves the last exception recorded for the server instance's configured port.
236+
/// </summary>
237+
/// <returns>The most recent <see cref="Exception"/> captured for the server port, or <c>null</c> if no error has been recorded.</returns>
213238
public Exception? GetLastError()
214239
{
215240
return IlpEndpoint.GetLastError(_port);
216241
}
217242

243+
/// <summary>
244+
/// Checks whether the server's /ping endpoint responds with a successful HTTP status.
245+
/// </summary>
246+
/// <returns>`true` if the /ping endpoint returns a successful HTTP status code, `false` otherwise.</returns>
218247
public async Task<bool> Healthcheck()
219248
{
220249
var response = await new HttpClient().GetAsync($"http://localhost:{_port}/ping");
@@ -241,6 +270,10 @@ public async Task<bool> Healthcheck()
241270
return null;
242271
}
243272

273+
/// <summary>
274+
/// Gets the current receive counter for this server instance's configured port.
275+
/// </summary>
276+
/// <returns>The current counter value associated with the server's port.</returns>
244277
public int GetCounter()
245278
{
246279
return IlpEndpoint.GetCounter(_port);

src/dummy-http-server/IlpEndpoint.cs

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,11 @@ public class IlpEndpoint : Endpoint<Request, JsonErrorResponse?>
9898
public static bool WithRetriableError = false;
9999
public static bool WithErrorMessage = false;
100100

101-
// Get the port from request headers (set by DummyHttpServer)
101+
/// <summary>
102+
/// Determine the port key used for per-port state, preferring an explicit X-Server-Port request header when present.
103+
/// </summary>
104+
/// <param name="context">HTTP context from which to read the X-Server-Port header or the connection's local port.</param>
105+
/// <returns>The port number from the X-Server-Port header if present and valid; otherwise the connection's local port; or 0 if neither is available.</returns>
102106
private static int GetPortKey(HttpContext context)
103107
{
104108
if (context?.Request.Headers.TryGetValue("X-Server-Port", out var portHeader) == true
@@ -109,6 +113,17 @@ private static int GetPortKey(HttpContext context)
109113
return context?.Connection?.LocalPort ?? 0;
110114
}
111115

116+
/// <summary>
117+
/// Retrieve the port-scoped state for the specified server port, creating a new empty tuple if none exists.
118+
/// </summary>
119+
/// <param name="port">Server port number used as the key for port-scoped state.</param>
120+
/// <returns>
121+
/// A tuple containing:
122+
/// - `Buffer`: the StringBuilder receiving text for the port,
123+
/// - `Bytes`: the List&lt;byte&gt; receiving raw bytes for the port,
124+
/// - `Error`: the last Exception observed for the port, or `null` if none,
125+
/// - `Counter`: the per-port request counter.
126+
/// </returns>
112127
private static (StringBuilder Buffer, List<byte> Bytes, Exception? Error, int Counter) GetOrCreatePortData(int port)
113128
{
114129
lock (PortData)
@@ -123,10 +138,24 @@ private static (StringBuilder Buffer, List<byte> Bytes, Exception? Error, int Co
123138
}
124139

125140

126-
// Public methods for accessing port-specific data (used by DummyHttpServer)
141+
/// <summary>
142+
/// Gets the StringBuilder that accumulates received request bodies for the specified server port.
143+
/// </summary>
144+
/// <param name="port">The port number identifying the server instance whose buffer to retrieve.</param>
145+
/// <returns>The per-port receive buffer containing appended request string data.</returns>
127146
public static StringBuilder GetReceiveBuffer(int port) => GetOrCreatePortData(port).Buffer;
128-
public static List<byte> GetReceiveBytes(int port) => GetOrCreatePortData(port).Bytes;
129-
147+
/// <summary>
148+
/// Gets the list of bytes received by the server instance identified by the specified port.
149+
/// </summary>
150+
/// <param name="port">The port number that identifies the server instance.</param>
151+
/// <returns>The list of bytes that have been received for the specified port.</returns>
152+
public static List<byte> GetReceiveBytes(int port) => GetOrCreatePortData(port).Bytes;
153+
154+
/// <summary>
155+
/// Gets the last exception recorded for the specified server port.
156+
/// </summary>
157+
/// <param name="port">The port number used to identify the per-port server state.</param>
158+
/// <returns>The exception recorded for the port, or <c>null</c> if no error has been recorded.</returns>
130159
public static Exception? GetLastError(int port)
131160
{
132161
lock (PortData)
@@ -135,6 +164,11 @@ private static (StringBuilder Buffer, List<byte> Bytes, Exception? Error, int Co
135164
}
136165
}
137166

167+
/// <summary>
168+
/// Stores or clears the last exception associated with the specified server port in the port-scoped state.
169+
/// </summary>
170+
/// <param name="port">The port identifier whose stored error will be set.</param>
171+
/// <param name="error">The exception to store for the port, or <c>null</c> to clear the stored error.</param>
138172
public static void SetLastError(int port, Exception? error)
139173
{
140174
lock (PortData)
@@ -144,6 +178,11 @@ public static void SetLastError(int port, Exception? error)
144178
}
145179
}
146180

181+
/// <summary>
182+
/// Retrieves the current request counter for the specified port.
183+
/// </summary>
184+
/// <param name="port">The server port whose counter to retrieve.</param>
185+
/// <returns>The current request counter value associated with the specified port.</returns>
147186
public static int GetCounter(int port)
148187
{
149188
lock (PortData)
@@ -152,6 +191,11 @@ public static int GetCounter(int port)
152191
}
153192
}
154193

194+
/// <summary>
195+
/// Set the request counter for the specified server port's per-port state.
196+
/// </summary>
197+
/// <param name="port">Port key identifying which server instance's state to modify.</param>
198+
/// <param name="value">New counter value to store for that port.</param>
155199
public static void SetCounter(int port, int value)
156200
{
157201
lock (PortData)
@@ -161,6 +205,10 @@ public static void SetCounter(int port, int value)
161205
}
162206
}
163207

208+
/// <summary>
209+
/// Clears stored state for the specified port, removing accumulated request text and bytes and resetting the port's last error and request counter.
210+
/// </summary>
211+
/// <param name="port">Port number whose stored buffers and metadata will be reset.</param>
164212
public static void ClearPort(int port)
165213
{
166214
lock (PortData)
@@ -174,6 +222,14 @@ public static void ClearPort(int port)
174222
}
175223
}
176224

225+
/// <summary>
226+
/// Set per-port configuration flags that control authentication requirements and simulated error behavior for the server running on the specified port.
227+
/// </summary>
228+
/// <param name="port">The server port to configure.</param>
229+
/// <param name="tokenAuth">If true, token-based authentication is required for requests to this port.</param>
230+
/// <param name="basicAuth">If true, HTTP Basic authentication is required for requests to this port.</param>
231+
/// <param name="retriableError">If true, the endpoint will respond with an HTTP 500 to simulate a retriable server error for this port.</param>
232+
/// <param name="errorMessage">If true, the endpoint will respond with a JSON error payload and HTTP 400 to simulate a client error for this port.</param>
177233
public static void SetPortConfig(int port, bool tokenAuth, bool basicAuth, bool retriableError, bool errorMessage)
178234
{
179235
lock (PortConfig)
@@ -182,6 +238,19 @@ public static void SetPortConfig(int port, bool tokenAuth, bool basicAuth, bool
182238
}
183239
}
184240

241+
/// <summary>
242+
/// Resolve authentication and error-behavior flags for the specified server port, falling back to global defaults when no per-port configuration exists.
243+
/// </summary>
244+
/// <param name="port">TCP port number used to look up per-port configuration.</param>
245+
/// <returns>
246+
/// A tuple with the resolved flags:
247+
/// <list type="bullet">
248+
/// <item><description><c>TokenAuth</c>: <c>true</c> if token authentication is enabled for the port, <c>false</c> otherwise.</description></item>
249+
/// <item><description><c>BasicAuth</c>: <c>true</c> if basic authentication is enabled for the port, <c>false</c> otherwise.</description></item>
250+
/// <item><description><c>RetriableError</c>: <c>true</c> if the port is configured to respond with retriable errors, <c>false</c> otherwise.</description></item>
251+
/// <item><description><c>ErrorMessage</c>: <c>true</c> if the port is configured to return structured error messages, <c>false</c> otherwise.</description></item>
252+
/// </list>
253+
/// </returns>
185254
private static (bool TokenAuth, bool BasicAuth, bool RetriableError, bool ErrorMessage) GetPortConfig(int port)
186255
{
187256
lock (PortConfig)
@@ -195,6 +264,14 @@ private static (bool TokenAuth, bool BasicAuth, bool RetriableError, bool ErrorM
195264
}
196265
}
197266

267+
/// <summary>
268+
/// Configure the endpoint's route, authentication behavior, request description, and request binder.
269+
/// </summary>
270+
/// <remarks>
271+
/// Maps the POST route "api/v2/write" to the endpoint, allows anonymous access when token auth is disabled,
272+
/// registers a basic-auth preprocessor when basic auth is enabled, declares that the endpoint accepts a <see cref="Request"/>,
273+
/// and assigns the <see cref="Binder"/> as the request binder.
274+
/// </remarks>
198275
public override void Configure()
199276
{
200277
Post("write", "api/v2/write");
@@ -212,6 +289,19 @@ public override void Configure()
212289
RequestBinder(new Binder());
213290
}
214291

292+
/// <summary>
293+
/// Processes an incoming write request for a specific port's dummy server, recording the request body into that port's in-memory buffers or returning configured error responses.
294+
/// </summary>
295+
/// <param name="req">The bound request containing raw bytes and a UTF-8 string representation of the body.</param>
296+
/// <param name="ct">A cancellation token to observe while processing the request.</param>
297+
/// <remarks>
298+
/// Behavior:
299+
/// - Increments the per-port request counter.
300+
/// - If the port's configuration requests a retriable error, responds with HTTP 500 and no content.
301+
/// - If the port's configuration requests an error message, responds with a JsonErrorResponse and HTTP 400.
302+
/// - Otherwise appends the request string to the port's receive buffer and the request bytes to the port's byte list, then responds with HTTP 204.
303+
/// - On exception, stores the exception as the port's last error and rethrows.
304+
/// </remarks>
215305
public override async Task HandleAsync(Request req, CancellationToken ct)
216306
{
217307
int port = GetPortKey(HttpContext);

0 commit comments

Comments
 (0)