Serene Runtime 1.0.0-dev
C runtime for the Serene programming language
Loading...
Searching...
No Matches
source_manager_tests.h File Reference
#include <fcntl.h>
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <serene/rt/context.h>
#include <serene/rt/source_manager.h>
#include "base.h"
Include dependency graph for source_manager_tests.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define SM_TESTS(X)

Functions

static int sm_make_temp_file (char *path_out, const char *content)
static void test_sm_init ()
 TEST_IN_FIBER (sm_buffer_new_file, { char path[PATH_MAX];TEST_ASSERT(sm_make_temp_file(path, "hello")==0);srn_sm_t *sm=srn_sm_init(ctx);auto result=srn_sm_buffer_file(sm, path, false);TEST_NO_ERROR(result);ASSERT_NOT_NULL(result.buffer);TEST_CHECK(sm->buffer_counts==1);TEST_CHECK(srn_sm_buffer_len(result.buffer)==6);TEST_CHECK(memcmp(srn_sm_buffer_data(result.buffer), "hello", 5)==0);srn_sm_shutdown(sm);unlink(path);}) TEST_IN_FIBER(sm_buffer_terminated
 TEST_ASSERT (sm_make_temp_file(path, content)==0)
 for (size_t i=0;i< 8;i++)
 TEST_NO_ERROR (result)
 ASSERT_NOT_NULL (result.buffer)
 TEST_CHECK (srn_sm_buffer_len(result.buffer)==len+1)
 TEST_CHECK (memcmp(srn_sm_buffer_data(result.buffer), content, len)==0)
 TEST_CHECK (srn_sm_buffer_data(result.buffer)[len]=='\0')
 srn_sm_shutdown (sm)
 unlink (path)
 TEST_IN_FIBER (sm_buffer_same_file_no_reread, { char path[PATH_MAX];TEST_ASSERT(sm_make_temp_file(path, "data")==0);srn_sm_t *sm=srn_sm_init(ctx);auto first=srn_sm_buffer_file(sm, path, false);auto second=srn_sm_buffer_file(sm, path, false);TEST_NO_ERROR(first);TEST_NO_ERROR(second);TEST_CHECK(first.buffer==second.buffer);TEST_CHECK(sm->buffer_counts==1);srn_sm_shutdown(sm);unlink(path);}) TEST_IN_FIBER(sm_buffer_empty_file
 TEST_ASSERT (sm_make_temp_file(path, "")==0)
 ASSERT_NULL (srn_sm_buffer_data(result.buffer))
 TEST_CHECK (sm->buffer_counts==1)
 TEST_IN_FIBER (sm_buffer_nonexistent_file, { srn_sm_t *sm=srn_sm_init(ctx);auto result=srn_sm_buffer_file(sm, "/tmp/srn_does_not_exist_xyz123abc", false);ASSERT_NOT_NULL(result.maybe_error);TEST_CHECK(result.maybe_error->tag==NOT_FOUND);TEST_CHECK(sm->buffer_counts==0);srn_sm_shutdown(sm);}) TEST_IN_FIBER(sm_buffer_reread
 TEST_ASSERT (sm_make_temp_file(path, "version1")==0)
 TEST_NO_ERROR (first)
 ASSERT_NOT_NULL (srn_sm_buffer_data(first.buffer))
 TEST_ASSERT (fd >=0)
 TEST_ASSERT (write(fd, "version2", 8)==8)
 close (fd)
 TEST_NO_ERROR (second)
 ASSERT_NOT_NULL (srn_sm_buffer_data(second.buffer))
 TEST_CHECK (srn_sm_buffer_len(second.buffer)==9)
 TEST_CHECK (memcmp(srn_sm_buffer_data(second.buffer), "version2", 8)==0)
 TEST_CHECK (srn_sm_buffer_data(second.buffer) !=srn_sm_buffer_data(second.buffer->next))
 ASSERT_NOT_NULL (second.buffer->next)
 TEST_CHECK (srn_sm_buffer_len(second.buffer->next)==9)
 TEST_CHECK (memcmp(srn_sm_buffer_data(second.buffer->next), "version1", 8)==0)
 TEST_IN_FIBER (sm_get_buffer, { char path[PATH_MAX];TEST_ASSERT(sm_make_temp_file(path, "test content")==0);srn_sm_t *sm=srn_sm_init(ctx);auto result=srn_sm_read_buffer_file(sm, path, false);TEST_NO_ERROR(result);srn_sm_buffer_t *buf=srn_sm_get_buffer(sm, result.id);ASSERT_NOT_NULL(buf);TEST_CHECK(srn_sm_buffer_len(buf)==13);TEST_CHECK(memcmp(srn_sm_buffer_data(buf), "test content", 12)==0);TEST_CHECK(strcmp(buf->filename, path)==0);srn_sm_shutdown(sm);unlink(path);}) TEST_IN_FIBER(sm_reread_failure_keeps_buffer
 ASSERT_NOT_NULL (failed.maybe_error)
 TEST_CHECK (failed.maybe_error->tag==NOT_FOUND)
 TEST_NO_ERROR (again)
 TEST_CHECK (again.buffer==first.buffer)
 TEST_CHECK (srn_sm_buffer_len(again.buffer)==9)
 TEST_CHECK (memcmp(srn_sm_buffer_data(again.buffer), "version1", 8)==0)
 TEST_IN_FIBER (sm_filename_is_owned, { char path[PATH_MAX];TEST_ASSERT(sm_make_temp_file(path, "data")==0);char scratch[PATH_MAX];(void) snprintf(scratch, sizeof(scratch), "%s", path);srn_sm_t *sm=srn_sm_init(ctx);auto result=srn_sm_buffer_file(sm, scratch, false);TEST_NO_ERROR(result);memset(scratch, 'x', strlen(scratch));TEST_CHECK(strcmp(result.buffer->filename, path)==0);srn_sm_shutdown(sm);unlink(path);}) static srn_fiber_result_t sm_id_exhaustion_fiber(srn_context_t *ctx
 TEST_ASSERT (sm_make_temp_file(path1, "one")==0)
 TEST_ASSERT (sm_make_temp_file(path2, "two")==0)
 ASSERT_NOT_NULL (refused.maybe_error)
 TEST_CHECK (refused.maybe_error->tag==SM_BUFFER_ID_EXHAUSTED)
 TEST_NO_ERROR (accepted)
 unlink (path1)
 unlink (path2)
static void test_sm_id_exhaustion_releases_lock ()

Variables

const size_t len = sizeof(content) - 1
char path [PATH_MAX]
srn_sm_t * sm = srn_sm_init(ctx)
unsigned char * poison [8]
auto result = srn_sm_buffer_file(sm, path, false)
auto first = srn_sm_buffer_file(sm, path, false)
int fd = open(path, O_WRONLY | O_TRUNC)
auto second = srn_sm_buffer_file(sm, path, true)
auto failed = srn_sm_buffer_file(sm, path, true)
auto again = srn_sm_buffer_file(sm, path, false)
void * arg
char path1 [PATH_MAX]
char path2 [PATH_MAX]
sm buffer_counts = UINT16_MAX
auto refused = srn_sm_buffer_file(sm, path1, false)
auto accepted = srn_sm_buffer_file(sm, path2, false)
* done = true
return nullptr

Macro Definition Documentation

◆ SM_TESTS

#define SM_TESTS ( X)
Value:
X("source_manager::init", test_sm_init), \
X("source_manager::buffer_new_file", test_sm_buffer_new_file), \
X("source_manager::buffer_terminated", test_sm_buffer_terminated), \
X("source_manager::buffer_same_file_no_reread", test_sm_buffer_same_file_no_reread), \
X("source_manager::buffer_empty_file", test_sm_buffer_empty_file), \
X("source_manager::buffer_nonexistent_file", test_sm_buffer_nonexistent_file), \
X("source_manager::buffer_reread", test_sm_buffer_reread), \
X("source_manager::get_buffer", test_sm_get_buffer), \
X("source_manager::id_exhaustion_releases_lock", test_sm_id_exhaustion_releases_lock), \
X("source_manager::reread_failure_keeps_buffer", test_sm_reread_failure_keeps_buffer), \
X("source_manager::filename_is_owned", test_sm_filename_is_owned), \
X("source_manager::shutdown", test_sm_shutdown)
static void test_sm_init()
static void test_sm_id_exhaustion_releases_lock()

Definition at line 33 of file source_manager_tests.h.

33#define SM_TESTS(X) \
34 X("source_manager::init", test_sm_init), \
35 X("source_manager::buffer_new_file", test_sm_buffer_new_file), \
36 X("source_manager::buffer_terminated", test_sm_buffer_terminated), \
37 X("source_manager::buffer_same_file_no_reread", test_sm_buffer_same_file_no_reread), \
38 X("source_manager::buffer_empty_file", test_sm_buffer_empty_file), \
39 X("source_manager::buffer_nonexistent_file", test_sm_buffer_nonexistent_file), \
40 X("source_manager::buffer_reread", test_sm_buffer_reread), \
41 X("source_manager::get_buffer", test_sm_get_buffer), \
42 X("source_manager::id_exhaustion_releases_lock", test_sm_id_exhaustion_releases_lock), \
43 X("source_manager::reread_failure_keeps_buffer", test_sm_reread_failure_keeps_buffer), \
44 X("source_manager::filename_is_owned", test_sm_filename_is_owned), \
45 X("source_manager::shutdown", test_sm_shutdown)

Function Documentation

◆ ASSERT_NOT_NULL() [1/6]

ASSERT_NOT_NULL ( failed. maybe_error)

◆ ASSERT_NOT_NULL() [2/6]

ASSERT_NOT_NULL ( refused. maybe_error)

◆ ASSERT_NOT_NULL() [3/6]

ASSERT_NOT_NULL ( result. buffer)

◆ ASSERT_NOT_NULL() [4/6]

ASSERT_NOT_NULL ( second.buffer-> next)

◆ ASSERT_NOT_NULL() [5/6]

ASSERT_NOT_NULL ( srn_sm_buffer_data(first.buffer) )

◆ ASSERT_NOT_NULL() [6/6]

ASSERT_NOT_NULL ( srn_sm_buffer_data(second.buffer) )

◆ ASSERT_NULL()

◆ close()

close ( fd )
Here is the caller graph for this function:

◆ for()

for ( )

Definition at line 119 of file source_manager_tests.h.

119 {
120 poison[i] = srn_mm_malloc(ctx->engine->mm, len + 1);
121 memset(poison[i], 0xFF, len + 1);
122 }
void * srn_mm_malloc(srn_mm_t *mm, size_t size)
Generic allocations that do not participate in the block based pools.
Definition default.c:155
const size_t len
unsigned char * poison[8]
Here is the call graph for this function:

◆ sm_make_temp_file()

int sm_make_temp_file ( char * path_out,
const char * content )
static

Definition at line 49 of file source_manager_tests.h.

49 {
50 (void)snprintf(path_out, PATH_MAX, "/tmp/srn_sm_test_XXXXXX");
51 int fd = mkstemp(path_out);
52
53 if (fd < 0) {
54 return -1;
55 }
56
57 size_t len = strlen(content);
58 if (len > 0 && write(fd, content, len) != (ssize_t)len) {
59 close(fd);
60 unlink(path_out);
61 return -1;
62 }
63
64 close(fd);
65 return 0;
66}
unlink(path)
close(fd)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_sm_shutdown()

srn_sm_shutdown ( sm )
Here is the caller graph for this function:

◆ TEST_ASSERT() [1/7]

TEST_ASSERT ( fd >= 0)

◆ TEST_ASSERT() [2/7]

TEST_ASSERT ( sm_make_temp_file(path, "") = =0)

◆ TEST_ASSERT() [3/7]

TEST_ASSERT ( sm_make_temp_file(path, "version1") = =0)
Initial value:
{
char path[PATH_MAX]
char path[PATH_MAX]

◆ TEST_ASSERT() [4/7]

TEST_ASSERT ( sm_make_temp_file(path, content) = =0)

◆ TEST_ASSERT() [5/7]

TEST_ASSERT ( sm_make_temp_file(path1, "one") = =0)

◆ TEST_ASSERT() [6/7]

TEST_ASSERT ( sm_make_temp_file(path2, "two") = =0)

◆ TEST_ASSERT() [7/7]

TEST_ASSERT ( write(fd, "version2", 8) = =8)

◆ TEST_CHECK() [1/14]

TEST_CHECK ( again. buffer = =first.buffer)

◆ TEST_CHECK() [2/14]

TEST_CHECK ( failed.maybe_error-> tag = =NOT_FOUND)

◆ TEST_CHECK() [3/14]

TEST_CHECK ( memcmp(srn_sm_buffer_data(again.buffer), "version1", 8) = =0)

◆ TEST_CHECK() [4/14]

TEST_CHECK ( memcmp(srn_sm_buffer_data(result.buffer), content, len) = =0)

◆ TEST_CHECK() [5/14]

TEST_CHECK ( memcmp(srn_sm_buffer_data(second.buffer), "version2", 8) = =0)

◆ TEST_CHECK() [6/14]

TEST_CHECK ( memcmp(srn_sm_buffer_data(second.buffer->next), "version1", 8) = =0)

◆ TEST_CHECK() [7/14]

TEST_CHECK ( refused.maybe_error-> tag = =SM_BUFFER_ID_EXHAUSTED)

◆ TEST_CHECK() [8/14]

TEST_CHECK ( sm-> buffer_counts = =1)

◆ TEST_CHECK() [9/14]

TEST_CHECK ( srn_sm_buffer_data(result.buffer) [len] = ='\0')

◆ TEST_CHECK() [10/14]

Here is the call graph for this function:

◆ TEST_CHECK() [11/14]

TEST_CHECK ( srn_sm_buffer_len(again.buffer) = =9)

◆ TEST_CHECK() [12/14]

TEST_CHECK ( srn_sm_buffer_len(result.buffer) = =len+1)

◆ TEST_CHECK() [13/14]

TEST_CHECK ( srn_sm_buffer_len(second.buffer) = =9)

◆ TEST_CHECK() [14/14]

TEST_CHECK ( srn_sm_buffer_len(second.buffer->next) = =9)

◆ TEST_IN_FIBER() [1/5]

Here is the call graph for this function:

◆ TEST_IN_FIBER() [2/5]

TEST_IN_FIBER ( sm_buffer_nonexistent_file ,
{ srn_sm_t *sm=srn_sm_init(ctx);auto result=srn_sm_buffer_file(sm, "/tmp/srn_does_not_exist_xyz123abc", false);ASSERT_NOT_NULL(result.maybe_error);TEST_CHECK(result.maybe_error->tag==NOT_FOUND);TEST_CHECK(sm->buffer_counts==0);srn_sm_shutdown(sm);}  )
Here is the call graph for this function:

◆ TEST_IN_FIBER() [3/5]

Here is the call graph for this function:

◆ TEST_IN_FIBER() [4/5]

TEST_IN_FIBER ( sm_filename_is_owned ,
{ char path[PATH_MAX];TEST_ASSERT(sm_make_temp_file(path, "data")==0);char scratch[PATH_MAX];(void) snprintf(scratch, sizeof(scratch), "%s", path);srn_sm_t *sm=srn_sm_init(ctx);auto result=srn_sm_buffer_file(sm, scratch, false);TEST_NO_ERROR(result);memset(scratch, 'x', strlen(scratch));TEST_CHECK(strcmp(result.buffer->filename, path)==0);srn_sm_shutdown(sm);unlink(path);}  )
Here is the call graph for this function:

◆ TEST_IN_FIBER() [5/5]

TEST_IN_FIBER ( sm_get_buffer ,
{ char path[PATH_MAX];TEST_ASSERT(sm_make_temp_file(path, "test content")==0);srn_sm_t *sm=srn_sm_init(ctx);auto result=srn_sm_read_buffer_file(sm, path, false);TEST_NO_ERROR(result);srn_sm_buffer_t *buf=srn_sm_get_buffer(sm, result.id);ASSERT_NOT_NULL(buf);TEST_CHECK(srn_sm_buffer_len(buf)==13);TEST_CHECK(memcmp(srn_sm_buffer_data(buf), "test content", 12)==0);TEST_CHECK(strcmp(buf->filename, path)==0);srn_sm_shutdown(sm);unlink(path);}  )
Here is the call graph for this function:

◆ TEST_NO_ERROR() [1/5]

TEST_NO_ERROR ( accepted )

◆ TEST_NO_ERROR() [2/5]

TEST_NO_ERROR ( again )

◆ TEST_NO_ERROR() [3/5]

TEST_NO_ERROR ( first )

◆ TEST_NO_ERROR() [4/5]

TEST_NO_ERROR ( result )

◆ TEST_NO_ERROR() [5/5]

TEST_NO_ERROR ( second )

◆ test_sm_id_exhaustion_releases_lock()

void test_sm_id_exhaustion_releases_lock ( )
static

Definition at line 322 of file source_manager_tests.h.

322 {
323 MAKE_ENGINE(mm, engine);
324 MAKE_CONTEXT(engine, ctx);
325
326 bool done = false;
327 srn_fiber_spawn(ctx, sm_id_exhaustion_fiber, &done);
328 srn_sched_run(engine->scheduler, 1);
330
331 RELEASE_CONTEXT(ctx);
332 SHUTDOWN_ENGINE(mm, engine);
333}
#define TEST_CHECK(cond)
Definition acutest.h:95
#define RELEASE_CONTEXT(x)
Definition base.h:48
#define SHUTDOWN_ENGINE(mm, engine)
Definition base.h:40
#define MAKE_ENGINE(mm, engine)
Definition base.h:34
#define MAKE_CONTEXT(engine, x)
Definition base.h:44
srn_fiber_t * srn_fiber_spawn(srn_context_t *ctx, srn_fiber_entry_t entry, void *arg)
Make and schedule a fiber with every default, the engine's scheduler, the configured stack size,...
Definition fiber.c:250
void srn_sched_run(srn_scheduler_t *sched, size_t nworkers)
Run the scheduler with nworkers os threads draining it, returning once the pool goes quiescent (every...
Definition scheduler.c:875
Here is the call graph for this function:

◆ test_sm_init()

void test_sm_init ( )
static

Definition at line 69 of file source_manager_tests.h.

69 {
70 MAKE_ENGINE(mm, engine);
71 MAKE_CONTEXT(engine, ctx);
72
73 srn_sm_t *sm = srn_sm_init(ctx);
75 TEST_CHECK(sm->buffer_counts == 0);
76
78 TEST_CHECK(sm->buffer_counts == 0);
79
80 RELEASE_CONTEXT(ctx);
81 SHUTDOWN_ENGINE(mm, engine);
82}
#define ASSERT_NOT_NULL(x)
Definition base.h:30
srn_sm_t * srn_sm_init(srn_context_t *ctx)
Initialize the source manager, as an immortal data structure.
srn_sm_t * sm
srn_sm_shutdown(sm)
Here is the call graph for this function:

◆ unlink() [1/3]

unlink ( path )
Here is the caller graph for this function:

◆ unlink() [2/3]

unlink ( path1 )

◆ unlink() [3/3]

unlink ( path2 )

Variable Documentation

◆ accepted

auto accepted = srn_sm_buffer_file(sm, path2, false)

Definition at line 311 of file source_manager_tests.h.

◆ again

auto again = srn_sm_buffer_file(sm, path, false)

Definition at line 263 of file source_manager_tests.h.

◆ arg

void* arg
Initial value:
{
bool *done = arg
void * arg

Definition at line 296 of file source_manager_tests.h.

◆ buffer_counts

sm buffer_counts = UINT16_MAX

Definition at line 305 of file source_manager_tests.h.

◆ done

* done = true

Definition at line 318 of file source_manager_tests.h.

◆ failed

auto failed = srn_sm_buffer_file(sm, path, true)

Definition at line 259 of file source_manager_tests.h.

◆ fd

int fd = open(path, O_WRONLY | O_TRUNC)

Definition at line 202 of file source_manager_tests.h.

◆ first

auto first = srn_sm_buffer_file(sm, path, false)

Definition at line 198 of file source_manager_tests.h.

◆ len

const size_t len = sizeof(content) - 1

Definition at line 109 of file source_manager_tests.h.

◆ nullptr

return nullptr

Definition at line 319 of file source_manager_tests.h.

◆ path

char path[PATH_MAX]

Definition at line 111 of file source_manager_tests.h.

◆ path1

char path1[PATH_MAX]

Definition at line 298 of file source_manager_tests.h.

◆ path2

char path2[PATH_MAX]

Definition at line 299 of file source_manager_tests.h.

◆ poison

unsigned char* poison[8]

Definition at line 118 of file source_manager_tests.h.

◆ refused

auto refused = srn_sm_buffer_file(sm, path1, false)

Definition at line 306 of file source_manager_tests.h.

◆ result

auto result = srn_sm_buffer_file(sm, path, false)

Definition at line 127 of file source_manager_tests.h.

◆ second

auto second = srn_sm_buffer_file(sm, path, true)

Definition at line 207 of file source_manager_tests.h.

◆ sm

srn_sm_t * sm = srn_sm_init(ctx)

Definition at line 114 of file source_manager_tests.h.