24#include <freeradius-devel/util/test/acutest_common_init.h>
25#include <freeradius-devel/util/test/acutest_helpers.h>
28#include <freeradius-devel/bio/bio_priv.h>
29#include <freeradius-devel/util/rb.h>
30#include <freeradius-devel/bio/dedup.h>
117 if (!cfg->
el)
return NULL;
122 if (!stub)
return NULL;
165 if (!dedup)
goto done;
170 TEST_CASE(
"fr_bio_dedup_respond() writes the reply");
173 TEST_CASE(
"the dedup entry expires once the lifetime is over");
192 if (!dedup)
goto done;
197 TEST_CASE(
"fr_bio_write() writes the reply");
200 TEST_CASE(
"the dedup entry expires once the lifetime is over");
224 if (!dedup)
goto done;
226 TEST_CASE(
"a dedup bio with two entries finds a free entry for each of five requests");
227 for (i = 0; i < 5; i++) {
257 if (!dedup)
goto done;
261 if (!first)
goto done;
266 if (!second)
goto done;
269 TEST_CASE(
"fr_bio_dedup_entry_extend() gives both entries the same expiry time");
288 if (!my->priv_cb.write_resume)
return -1;
290 return my->priv_cb.write_resume(dedup);
315 if (!dedup)
goto done;
318 TEST_CASE(
"a reply written while the stub transport is blocked goes on the pending list");
322 TEST_CASE(
"write_resume sends the pending reply");
327 TEST_CASE(
"the dedup entry then expires once the lifetime is over");
346 if (!dedup)
goto done;
351 TEST_CASE(
"write_resume reports that writes are still blocked");
354 TEST_CASE(
"write_resume kept the pending reply, and the next write_resume call sends the pending reply");
374 if (!dedup)
goto done;
379 TEST_CASE(
"the stub transport accepts one byte, so write_resume reports that writes are still blocked");
384 TEST_CASE(
"the next write_resume call sends the rest of the reply exactly once");
static int const char char buffer[256]
#define TEST_CHECK_RET(_got, _exp)
fr_bio_write_t _CONST write
write to the underlying bio
static ssize_t fr_bio_write(fr_bio_t *bio, void *packet_ctx, void const *buffer, size_t size)
Write raw data to a bio.
static fr_bio_t * fr_bio_next(fr_bio_t *bio)
static ssize_t fr_bio_read(fr_bio_t *bio, void *packet_ctx, void *buffer, size_t size)
Read raw data from a bio.
static void test_respond_expires(void)
The dedup entry for a reply sent with fr_bio_dedup_respond() expires once the lifetime is over.
static fr_bio_dedup_entry_t * saved_item
static void test_resume_partial(void)
When the stub transport writes only part of a pending reply, the next resume writes the rest.
static bool test_read_request(fr_bio_t *dedup, uint8_t *buffer, size_t size)
Read one request through the dedup bio, and attach reply to the dedup entry of the request.
static ssize_t stub_read(UNUSED fr_bio_t *bio, UNUSED void *pctx, void *buffer, size_t size)
The stub transport returns a copy of request on every read, and reports every write as complete.
static void test_write_expires(void)
The dedup entry for a reply sent with fr_bio_write() expires once the lifetime is over.
static bool dedup_receive(UNUSED fr_bio_t *bio, fr_bio_dedup_entry_t *dedup_ctx, UNUSED void *pctx)
static int packet_ctx
the tests pass only the address of packet_ctx
static void test_resume_still_blocked(void)
write_resume keeps the pending reply when the stub transport is still blocked.
static fr_bio_dedup_entry_t * dedup_get_item(UNUSED fr_bio_t *bio, UNUSED void *pctx)
static ssize_t stub_write_block(UNUSED fr_bio_t *bio, UNUSED void *pctx, UNUSED void const *buffer, UNUSED size_t size)
A stub transport write function which always returns IO_WOULD_BLOCK.
static void dedup_release(UNUSED fr_bio_t *bio, UNUSED fr_bio_dedup_entry_t *dedup_ctx, fr_bio_dedup_release_reason_t reason)
static bool test_pending_reply(fr_bio_t *dedup, fr_bio_t *stub, uint8_t *buffer, size_t size)
Read a request, and respond while the stub transport is blocked, so that the reply goes on the pendin...
static void test_equal_expiry(void)
Two entries with the same expiry time both expire.
static void test_entries_are_reused(void)
The expiry timer returns each expired entry to the free list, so the dedup bio reads more requests th...
static uint8_t request[4]
static void test_resume_sends_pending(void)
write_resume sends a pending reply, and the dedup entry then expires once the lifetime is over.
static ssize_t stub_write_one(UNUSED fr_bio_t *bio, UNUSED void *pctx, void const *buffer, UNUSED size_t size)
A stub transport write function which accepts one byte of each write.
static fr_bio_t * stub_alloc(TALLOC_CTX *ctx)
static fr_bio_t * test_dedup_alloc(TALLOC_CTX *ctx, fr_bio_dedup_config_t *cfg)
Allocate a dedup bio with two entries and a one-second lifetime, in front of the stub transport.
static void test_run_timers(fr_bio_dedup_config_t *cfg)
Run every timer which is due within the next five seconds.
static ssize_t stub_write_all(UNUSED fr_bio_t *bio, UNUSED void *pctx, void const *buffer, size_t size)
static size_t stub_bytes
bytes of reply data which the stub transport has accepted
static int test_write_resume(fr_bio_t *dedup)
Call the dedup bio's write_resume callback, as fr_bio_packet_write_resume() does.
ssize_t fr_bio_dedup_respond(fr_bio_t *bio, fr_bio_dedup_entry_t *item)
Resend a reply when we receive a duplicate request.
int fr_bio_dedup_entry_extend(fr_bio_t *bio, fr_bio_dedup_entry_t *item, fr_time_t expires)
Extend the expiry time for an entry.
fr_bio_t * fr_bio_dedup_alloc(TALLOC_CTX *ctx, size_t max_saved, fr_bio_dedup_receive_t receive, fr_bio_dedup_release_t release, fr_bio_dedup_get_item_t get_item, fr_bio_dedup_config_t const *cfg, fr_bio_t *next)
Allocate a fr_bio_dedup_t.
fr_event_list_t * el
event list
fr_time_delta_t lifetime
default lifetime of dedup entry
uint8_t * reply
reply cached by the application
size_t reply_size
size of the cached reply
void * reply_ctx
reply ctx
fr_bio_dedup_release_reason_t
fr_event_list_t * fr_event_list_alloc(TALLOC_CTX *ctx, fr_event_status_cb_t status, void *status_uctx)
Initialise a new event list.
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
static fr_time_delta_t fr_time_delta_from_sec(int64_t sec)
#define fr_time_add(_a, _b)
Add a time/time delta together.
int fr_timer_list_run(fr_timer_list_t *tl, fr_time_t *when)
Execute any pending events in the event loop.