-
Notifications
You must be signed in to change notification settings - Fork 5
Fixing unit tests for mem-cpy, -move and -set functions #112
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
665c46b
9cc3c28
31dc5b4
7a7c69a
661e73d
f1e6208
a32ba0c
dec8ed9
bff191d
5935f18
043e4db
0547e80
3e652bf
f40b0e7
23496e5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -13,34 +13,6 @@ | |
| #include <dice/pubsub.h> | ||
| #include <dice/events/memcpy.h> | ||
|
|
||
| static void *symbol; | ||
| /* we need to declare this as noinline, otherwise the optimization of the | ||
| * compiler gets rid of the symbol. */ | ||
| static __attribute__((noinline)) void | ||
| enable(void *foo) | ||
| { | ||
| symbol = foo; | ||
| } | ||
| static __attribute__((noinline)) void | ||
| disable(void) | ||
| { | ||
| symbol = NULL; | ||
| } | ||
| static inline bool | ||
| enabled(void) | ||
| { | ||
| return symbol != NULL; | ||
| } | ||
|
|
||
| void * | ||
| real_sym(const char *name, const char *ver) | ||
| { | ||
| (void)ver; | ||
| if (!enabled()) | ||
| return _real_sym(name, ver); | ||
| return symbol; | ||
| } | ||
|
|
||
| /* Expects struct to match this: | ||
| * | ||
| * struct memcpy_event { | ||
|
|
@@ -72,151 +44,113 @@ struct memmove_event E_memmove; | |
| */ | ||
| struct memset_event E_memset; | ||
|
|
||
| /* mock implementation of functions */ | ||
| void * | ||
| fake_memcpy(void *dest ,const void *src ,size_t num) | ||
| { | ||
| /* check that every argument is as expected */ | ||
| ensure(dest == E_memcpy.dest); | ||
| ensure(src == E_memcpy.src); | ||
| ensure(num == E_memcpy.num); | ||
| /* return expected value */ | ||
| return E_memcpy.ret; | ||
| } | ||
| void * | ||
| fake_memmove(void *dest ,const void *src ,size_t count) | ||
| { | ||
| /* check that every argument is as expected */ | ||
| ensure(dest == E_memmove.dest); | ||
| ensure(src == E_memmove.src); | ||
| ensure(count == E_memmove.count); | ||
| /* return expected value */ | ||
| return E_memmove.ret; | ||
| } | ||
| void * | ||
| fake_memset(void *ptr, int value, size_t num) | ||
| { | ||
| /* check that every argument is as expected */ | ||
| ensure(ptr == E_memset.ptr); | ||
| ensure(value == E_memset.value); | ||
| ensure(num == E_memset.num); | ||
| /* return expected value */ | ||
| return E_memset.ret; | ||
| } | ||
|
|
||
| #define ASSERT_FIELD_EQ(E, field) \ | ||
| ensure(memcmp(&ev->field, &(E)->field, sizeof(__typeof((E)->field))) == 0); | ||
| ensure(memcmp(&ev->field, &(E)->field, sizeof((E)->field)) == 0); | ||
|
|
||
| PS_SUBSCRIBE(INTERCEPT_BEFORE, EVENT_MEMCPY, { | ||
| if (!enabled()) | ||
| return PS_STOP_CHAIN; | ||
| struct memcpy_event *ev = EVENT_PAYLOAD(ev); | ||
| log_printf("ev->dest %p\n", &ev->dest); | ||
| log_printf("&(&E_memcpy)->dest %p\n", &(&E_memcpy)->dest); | ||
| log_printf("memcmp(&ev->dest, &(&E_memcpy)->dest, sizeof((&E_memcpy)->dest)) == 0 %d\n", memcmp(&ev->dest, &(&E_memcpy)->dest, sizeof(__typeof((&E_memcpy)->dest))) == 0); | ||
| ASSERT_FIELD_EQ(&E_memcpy, dest); | ||
| ASSERT_FIELD_EQ(&E_memcpy, src); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we add some check that the interceptor really got called? Or is that already checked elsewhere? |
||
| ASSERT_FIELD_EQ(&E_memcpy, num); | ||
| }) | ||
|
|
||
| PS_SUBSCRIBE(INTERCEPT_AFTER, EVENT_MEMCPY, { | ||
| if (!enabled()) | ||
| return PS_STOP_CHAIN; | ||
| struct memcpy_event *ev = EVENT_PAYLOAD(ev); | ||
| log_printf("ev->dest %p\n", &ev->dest); | ||
| log_printf("&(&E_memcpy)->dest %p\n", &(&E_memcpy)->dest); | ||
| log_printf("memcmp(&ev->dest, &(&E_memcpy)->dest, sizeof((&E_memcpy)->dest)) == 0 %d\n", memcmp(&ev->dest, &(&E_memcpy)->dest, sizeof(__typeof((&E_memcpy)->dest))) == 0); | ||
| ASSERT_FIELD_EQ(&E_memcpy, dest); | ||
| ASSERT_FIELD_EQ(&E_memcpy, src); | ||
| ASSERT_FIELD_EQ(&E_memcpy, num); | ||
| ASSERT_FIELD_EQ(&E_memcpy, ret); | ||
| ensure(E_memcpy.dest == E_memcpy.ret); | ||
| }) | ||
| PS_SUBSCRIBE(INTERCEPT_BEFORE, EVENT_MEMMOVE, { | ||
| if (!enabled()) | ||
| return PS_STOP_CHAIN; | ||
| struct memmove_event *ev = EVENT_PAYLOAD(ev); | ||
| ASSERT_FIELD_EQ(&E_memmove, dest); | ||
| ASSERT_FIELD_EQ(&E_memmove, src); | ||
| ASSERT_FIELD_EQ(&E_memmove, count); | ||
| }) | ||
|
|
||
| PS_SUBSCRIBE(INTERCEPT_AFTER, EVENT_MEMMOVE, { | ||
| if (!enabled()) | ||
| return PS_STOP_CHAIN; | ||
| struct memmove_event *ev = EVENT_PAYLOAD(ev); | ||
| ASSERT_FIELD_EQ(&E_memmove, dest); | ||
| ASSERT_FIELD_EQ(&E_memmove, src); | ||
| ASSERT_FIELD_EQ(&E_memmove, count); | ||
| ASSERT_FIELD_EQ(&E_memmove, ret); | ||
| }) | ||
| PS_SUBSCRIBE(INTERCEPT_BEFORE, EVENT_MEMSET, { | ||
| if (!enabled()) | ||
| return PS_STOP_CHAIN; | ||
| struct memset_event *ev = EVENT_PAYLOAD(ev); | ||
| ASSERT_FIELD_EQ(&E_memset, ptr); | ||
| ASSERT_FIELD_EQ(&E_memset, value); | ||
| ASSERT_FIELD_EQ(&E_memset, num); | ||
| }) | ||
|
|
||
| PS_SUBSCRIBE(INTERCEPT_AFTER, EVENT_MEMSET, { | ||
| if (!enabled()) | ||
| return PS_STOP_CHAIN; | ||
| struct memset_event *ev = EVENT_PAYLOAD(ev); | ||
| ASSERT_FIELD_EQ(&E_memset, ptr); | ||
| ASSERT_FIELD_EQ(&E_memset, value); | ||
| ASSERT_FIELD_EQ(&E_memset, num); | ||
| ASSERT_FIELD_EQ(&E_memset, ret); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. whitespace? |
||
| }) | ||
|
|
||
|
|
||
| static void | ||
| event_init(void *ptr, size_t n) | ||
| { | ||
| char *buf = ptr; | ||
| for (size_t i = 0; i < n; i++) | ||
| buf[i] = rand() % 256; | ||
| } | ||
|
|
||
| /* test case */ | ||
| /* test cases */ | ||
|
|
||
| static void | ||
| test_memcpy(void) | ||
| { | ||
| /* initialize event with random content */ | ||
| event_init(&E_memcpy, sizeof(struct memcpy_event)); | ||
| /* call memcpy with arguments */ | ||
| enable(fake_memcpy); | ||
| E_memcpy.dest = malloc(10); | ||
| char hello[] = "Hello!"; | ||
| E_memcpy.src= hello; | ||
| E_memcpy.num = strlen(E_memcpy.src) + 1; | ||
| E_memcpy.ret = E_memcpy.dest; | ||
| void * ret = // | ||
| memcpy( // | ||
| E_memcpy.dest, // | ||
| E_memcpy.src, // | ||
| E_memcpy.num ); | ||
| ensure(ret == E_memcpy.ret); | ||
| disable(); | ||
| ensure(ret == E_memcpy.dest); | ||
| ensure(strcmp(E_memcpy.dest, E_memcpy.src) == 0); | ||
| free(E_memcpy.dest); | ||
| E_memcpy.dest = NULL; | ||
| } | ||
| static void | ||
| test_memmove(void) | ||
| { | ||
| /* initialize event with random content */ | ||
| event_init(&E_memmove, sizeof(struct memmove_event)); | ||
| /* call memmove with arguments */ | ||
| enable(fake_memmove); | ||
| E_memmove.dest = malloc(10); | ||
| char hello[] = "Hi there!"; | ||
| E_memmove.src= hello; | ||
| E_memmove.count = 2; | ||
| E_memmove.ret = E_memmove.dest; | ||
| void * ret = // | ||
| memmove( // | ||
| E_memmove.dest, // | ||
| E_memmove.src, // | ||
| E_memmove.count ); | ||
| ensure(ret == E_memmove.ret); | ||
| disable(); | ||
| ensure(ret == E_memmove.dest); | ||
| log_printf("memmove res %s\n", (char *)E_memmove.dest); | ||
| ensure(strncmp((char *)E_memmove.dest, "Hi", 2) == 0); | ||
| free(E_memmove.dest); | ||
| E_memmove.dest = NULL; | ||
| } | ||
| static void | ||
| test_memset(void) | ||
| { | ||
| /* initialize event with random content */ | ||
| event_init(&E_memset, sizeof(struct memset_event)); | ||
| /* call memset with arguments */ | ||
| enable(fake_memset); | ||
| E_memset.ptr = malloc(5); | ||
| E_memset.value= 3; | ||
| E_memset.num = 2; | ||
|
||
| E_memset.ret = E_memset.ptr; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think they are always equal, so we should probably remove this .ret field and just compare with E_memset.ptr There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. E_memset.ret is null without this and it is checked somewhere in the main test: ensure(ret == E_memset.ptr); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean there's no point to have the field at all, it can be removed from the struct. Then you can still |
||
| void * ret = // | ||
| memset( // | ||
| E_memset.ptr, // | ||
| E_memset.value, // | ||
| E_memset.num ); | ||
| ensure(ret == E_memset.ret); | ||
| disable(); | ||
| ensure(ret == E_memset.ptr); | ||
| free(E_memset.ptr); | ||
| E_memset.ptr = NULL; | ||
| } | ||
|
|
||
| int | ||
|
|
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
redundant typeof() ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we really commit these log messages?
If yes, I recommend defining a macro to avoid writing the same text twice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, I am not planning to merge with these. I want to understand better why for the arm with clang the next ensure fails: https://github.com/open-s4c/dice/actions/runs/18745327427/job/53480906689