Clean up tests
This commit is contained in:
parent
54c9c5d73b
commit
ec5ccea70c
23
include/test_helper.h
Normal file
23
include/test_helper.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef __TEST_HELPER_H
|
||||
#define __TEST_HELPER_H
|
||||
|
||||
#include <aos/aos.h>
|
||||
#include <mm/mm.h>
|
||||
|
||||
#define CHECK_ERR(expr) do { \
|
||||
errval_t _err = expr; \
|
||||
if (err_is_fail(_err)) { \
|
||||
USER_PANIC_ERR(_err, "Test failed."); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
extern struct mm *testmm;
|
||||
|
||||
void *alloc_frame(
|
||||
size_t bytes,
|
||||
size_t alignment,
|
||||
struct capref *ram_cap_ret,
|
||||
struct capref *frame_cap_ret
|
||||
);
|
||||
|
||||
#endif /* __TEST_HELPER_H */
|
||||
@ -2,14 +2,7 @@
|
||||
#define __TEST_MM_H
|
||||
|
||||
#include <aos/aos.h>
|
||||
#include <mm/mm.h>
|
||||
|
||||
uint8_t test_mm_run(errval_t func(struct mm *), char *name, struct mm *mm);
|
||||
errval_t test_mm_small(struct mm *mm);
|
||||
errval_t test_mm_track_slots(struct mm *mm);
|
||||
errval_t test_mm_fragments(struct mm *mm);
|
||||
errval_t test_mm_rand(struct mm *mm);
|
||||
errval_t test_mm_many(struct mm *mm);
|
||||
errval_t test_mm_oom(struct mm *mm);
|
||||
void do_test_mm(void);
|
||||
|
||||
#endif /* __TEST_MM_H */
|
||||
|
||||
@ -3,9 +3,6 @@
|
||||
|
||||
#include <aos/aos.h>
|
||||
|
||||
uint8_t test_paging_run(errval_t func(void), char *name);
|
||||
errval_t test_paging_full_l3(void);
|
||||
errval_t test_paging_full_l2(void);
|
||||
errval_t test_paging_big_regions(void);
|
||||
void do_test_paging(void);
|
||||
|
||||
#endif /* __PAGING_TESTS_H */
|
||||
@ -16,6 +16,7 @@
|
||||
cFiles = [
|
||||
"rpc.c",
|
||||
"grading.c",
|
||||
"test_helper.c",
|
||||
"test_mm.c",
|
||||
"test_paging.c"
|
||||
],
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
#include <grading.h>
|
||||
#include <spawn/spawn.h>
|
||||
|
||||
#include <test_helper.h>
|
||||
#include <test_mm.h>
|
||||
#include <test_paging.h>
|
||||
|
||||
@ -23,106 +24,12 @@ void
|
||||
grading_setup_noninit(int *argc, char ***argv) {
|
||||
}
|
||||
|
||||
static void check_err(errval_t err) {
|
||||
if (err_is_fail(err)) {
|
||||
USER_PANIC_ERR(err, "Test failed.");
|
||||
}
|
||||
}
|
||||
|
||||
static struct mm *testmm;
|
||||
|
||||
static void *alloc_frame(size_t bytes, size_t alignment,
|
||||
struct capref *ram_cap_ret, struct capref *frame_cap_ret) {
|
||||
struct capref ram_cap;
|
||||
if (ram_cap_ret == NULL) ram_cap_ret = &ram_cap;
|
||||
struct capref frame_cap;
|
||||
if (frame_cap_ret == NULL) frame_cap_ret = &frame_cap;
|
||||
|
||||
assert(bytes == ROUND_UP(bytes, BASE_PAGE_SIZE));
|
||||
check_err(mm_alloc_aligned(testmm, bytes, alignment, ram_cap_ret));
|
||||
|
||||
check_err(slot_alloc(frame_cap_ret));
|
||||
check_err(cap_retype(*frame_cap_ret, *ram_cap_ret, 0, ObjType_Frame, bytes, 1));
|
||||
|
||||
struct paging_state *paging_state = get_current_paging_state();
|
||||
void *vaddr;
|
||||
check_err(paging_map_frame_attr(
|
||||
paging_state, &vaddr,
|
||||
bytes, *frame_cap_ret, VREGION_FLAGS_READ_WRITE
|
||||
));
|
||||
return vaddr;
|
||||
}
|
||||
|
||||
void
|
||||
grading_test_mm(struct mm *test) {
|
||||
errval_t err;
|
||||
testmm = test;
|
||||
|
||||
struct capref *caplist = alloc_frame(sizeof(struct capref) * 1024*1024, 16, NULL, NULL);
|
||||
size_t alloc_count = 0;
|
||||
|
||||
// Test partial free
|
||||
struct capref big_block;
|
||||
struct capref part1_of_big_block;
|
||||
struct capref part2_of_big_block;
|
||||
check_err(mm_alloc_aligned(testmm, 16*4096, 4096, &big_block));
|
||||
check_err(slot_alloc(&part1_of_big_block));
|
||||
check_err(slot_alloc(&part2_of_big_block));
|
||||
check_err(cap_retype(part1_of_big_block, big_block, 0, ObjType_RAM, 4096, 1));
|
||||
check_err(cap_retype(part2_of_big_block, big_block, 4096, ObjType_RAM, 15*4096, 1));
|
||||
check_err(cap_destroy(big_block));
|
||||
check_err(mm_free(testmm, part2_of_big_block));
|
||||
|
||||
// Allocate all available RAM and then deallocate it again, multiple times.
|
||||
for (int it = 0; it < 5; it++) {
|
||||
for (; alloc_count < 1024*1024; alloc_count++) {
|
||||
err = mm_alloc_aligned(testmm, 256*BASE_PAGE_SIZE, BASE_PAGE_SIZE, &caplist[alloc_count]);
|
||||
if (err_is_fail(err)) {
|
||||
assert(err == MM_ERR_OUT_OF_RAM);
|
||||
break;
|
||||
}
|
||||
if (alloc_count % 10000 == 0) debug_printf("TEST: allocated %lu\n", alloc_count);
|
||||
}
|
||||
debug_printf("TEST: Allocated %"PRIu64" MB of RAM.\n", alloc_count * 256*BASE_PAGE_SIZE / 1024 / 1024);
|
||||
while (alloc_count > 0) {
|
||||
alloc_count--;
|
||||
check_err(mm_free(testmm, caplist[alloc_count]));
|
||||
if (alloc_count % 1000 == 0) debug_printf("TEST: freeing %lu\n", alloc_count);
|
||||
}
|
||||
}
|
||||
|
||||
// Test alignment ("e.g., a 4 KiB region must be aligned to a 1 MiB boundary.")
|
||||
for (; alloc_count < 10; alloc_count++) {
|
||||
check_err(mm_alloc_aligned(testmm, 4096, 1024*1024, &caplist[alloc_count]));
|
||||
struct capability c;
|
||||
check_err( cap_direct_identify(caplist[alloc_count], &c));
|
||||
genpaddr_t base = get_address(&c);
|
||||
assert(base % (1024*1024) == 0);
|
||||
}
|
||||
while (alloc_count > 0) {
|
||||
alloc_count--;
|
||||
check_err(mm_free(testmm, caplist[alloc_count]));
|
||||
}
|
||||
|
||||
test_mm_run(test_mm_small, "test_mm_small", test);
|
||||
test_mm_run(test_mm_track_slots, "test_mm_track_slots", test);
|
||||
test_mm_run(test_mm_fragments, "test_mm_fragments", test);
|
||||
test_mm_run(test_mm_rand, "test_mm_rand", test);
|
||||
test_mm_run(test_mm_many, "test_mm_many", test);
|
||||
test_mm_run(test_mm_oom, "test_mm_oom", test);
|
||||
|
||||
test_paging_run(test_paging_full_l3, "test_paging_full_l3");
|
||||
test_paging_run(test_paging_full_l2, "test_paging_full_l2");
|
||||
test_paging_run(test_paging_big_regions, "test_paging_big_regions");
|
||||
|
||||
// Test paging
|
||||
for (int i = 0; i < 40; i++) {
|
||||
debug_printf("TEST: page %lu\n", i);
|
||||
char *data = alloc_frame(5176*4096, 16, NULL, NULL);
|
||||
memset(data, 33, 5176*4096);
|
||||
}
|
||||
|
||||
debug_printf("TEST: Finished!\n");
|
||||
// do_test_mm();
|
||||
// do_test_paging();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
25
lib/grading/test_helper.c
Normal file
25
lib/grading/test_helper.c
Normal file
@ -0,0 +1,25 @@
|
||||
#include <test_helper.h>
|
||||
|
||||
struct mm *testmm;
|
||||
|
||||
void *alloc_frame(size_t bytes, size_t alignment,
|
||||
struct capref *ram_cap_ret, struct capref *frame_cap_ret) {
|
||||
struct capref ram_cap;
|
||||
if (ram_cap_ret == NULL) ram_cap_ret = &ram_cap;
|
||||
struct capref frame_cap;
|
||||
if (frame_cap_ret == NULL) frame_cap_ret = &frame_cap;
|
||||
|
||||
assert(bytes == ROUND_UP(bytes, BASE_PAGE_SIZE));
|
||||
CHECK_ERR(mm_alloc_aligned(testmm, bytes, alignment, ram_cap_ret));
|
||||
|
||||
CHECK_ERR(slot_alloc(frame_cap_ret));
|
||||
CHECK_ERR(cap_retype(*frame_cap_ret, *ram_cap_ret, 0, ObjType_Frame, bytes, 1));
|
||||
|
||||
struct paging_state *paging_state = get_current_paging_state();
|
||||
void *vaddr;
|
||||
CHECK_ERR(paging_map_frame_attr(
|
||||
paging_state, &vaddr,
|
||||
bytes, *frame_cap_ret, VREGION_FLAGS_READ_WRITE
|
||||
));
|
||||
return vaddr;
|
||||
}
|
||||
@ -1,4 +1,4 @@
|
||||
#include <aos/aos.h>
|
||||
#include <test_helper.h>
|
||||
#include <test_mm.h>
|
||||
#include <mm/mm.h>
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
|
||||
// this is outside of the functions because otherwise we have issues with
|
||||
// the function stack space in M1
|
||||
struct capref caps_big[TEST_MM_BIG_COUNT];
|
||||
struct capref caps[TEST_MM_SMALL_COUNT];
|
||||
static struct capref caps_big[TEST_MM_BIG_COUNT];
|
||||
static struct capref caps[TEST_MM_SMALL_COUNT];
|
||||
|
||||
uint8_t test_mm_run(errval_t func(struct mm *), char *name, struct mm *mm) {
|
||||
static void test_mm_run(errval_t func(struct mm *), char *name, struct mm *mm) {
|
||||
errval_t err;
|
||||
|
||||
// debug_printf("TEST_MM %19s: start\n", name);
|
||||
@ -19,17 +19,15 @@ uint8_t test_mm_run(errval_t func(struct mm *), char *name, struct mm *mm) {
|
||||
|
||||
if (err_is_ok(err)) {
|
||||
debug_printf("TEST_MM %19s: OK\n", name);
|
||||
return 1;
|
||||
} else {
|
||||
debug_printf("TEST_MM %19s: ERR\n", name);
|
||||
DEBUG_ERR(err, "Test Failed with Error");
|
||||
USER_PANIC_ERR(err, "Test Failed with Error");
|
||||
// mm_print_state(mm);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if small allocation sizes work (<4KiB)
|
||||
errval_t test_mm_small(struct mm *mm) {
|
||||
static errval_t test_mm_small(struct mm *mm) {
|
||||
errval_t err;
|
||||
|
||||
for(int i = 0; i < TEST_MM_SMALL_COUNT; ++i) {
|
||||
@ -50,7 +48,7 @@ errval_t test_mm_small(struct mm *mm) {
|
||||
}
|
||||
|
||||
// ASSESSMENT M1: show that free capability slots are tracked
|
||||
errval_t test_mm_track_slots(struct mm *mm) {
|
||||
static errval_t test_mm_track_slots(struct mm *mm) {
|
||||
errval_t err;
|
||||
|
||||
for(int i = 0; i < TEST_MM_SMALL_COUNT; ++i) {
|
||||
@ -67,7 +65,7 @@ errval_t test_mm_track_slots(struct mm *mm) {
|
||||
return err_push(err, MM_ERR_MM_FREE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(int i = 0; i < TEST_MM_SMALL_COUNT; ++i) {
|
||||
err = mm_alloc(mm, 1 << 21, &caps[i]);
|
||||
if(err_is_fail(err)) {
|
||||
@ -86,7 +84,7 @@ errval_t test_mm_track_slots(struct mm *mm) {
|
||||
}
|
||||
|
||||
// create fragmented memory and then free it
|
||||
errval_t test_mm_fragments(struct mm *mm) {
|
||||
static errval_t test_mm_fragments(struct mm *mm) {
|
||||
errval_t err;
|
||||
|
||||
// fragment some memory
|
||||
@ -118,7 +116,7 @@ errval_t test_mm_fragments(struct mm *mm) {
|
||||
|
||||
// ASSESSMENT M1: these tests demonstrate slot/slab refilling
|
||||
// allocate memory of random sizes
|
||||
errval_t test_mm_rand(struct mm *mm) {
|
||||
static errval_t test_mm_rand(struct mm *mm) {
|
||||
errval_t err;
|
||||
|
||||
for(int i = 0; i < TEST_MM_SMALL_COUNT; ++i) {
|
||||
@ -139,7 +137,7 @@ errval_t test_mm_rand(struct mm *mm) {
|
||||
}
|
||||
|
||||
// allocate loads of memory
|
||||
errval_t test_mm_many(struct mm *mm) {
|
||||
static errval_t test_mm_many(struct mm *mm) {
|
||||
errval_t err;
|
||||
|
||||
for(int i = 0; i < TEST_MM_BIG_COUNT; ++i) {
|
||||
@ -160,14 +158,70 @@ errval_t test_mm_many(struct mm *mm) {
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
errval_t test_mm_oom(struct mm *mm){
|
||||
static errval_t test_mm_oom(struct mm *mm){
|
||||
errval_t err;
|
||||
|
||||
// fail because of oom
|
||||
err = mm_alloc(mm, 1L << 31, &caps[0]);
|
||||
|
||||
|
||||
if(!err_is_fail(err) || err_no(err) != MM_ERR_OUT_OF_RAM) {
|
||||
return ERR_NOTIMP;
|
||||
}
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
}
|
||||
|
||||
void do_test_mm(void) {
|
||||
errval_t err;
|
||||
struct capref *caplist = alloc_frame(sizeof(struct capref) * 1024*1024, 16, NULL, NULL);
|
||||
size_t alloc_count = 0;
|
||||
|
||||
// Test partial free
|
||||
struct capref big_block;
|
||||
struct capref part1_of_big_block;
|
||||
struct capref part2_of_big_block;
|
||||
CHECK_ERR(mm_alloc_aligned(testmm, 16*4096, 4096, &big_block));
|
||||
CHECK_ERR(slot_alloc(&part1_of_big_block));
|
||||
CHECK_ERR(slot_alloc(&part2_of_big_block));
|
||||
CHECK_ERR(cap_retype(part1_of_big_block, big_block, 0, ObjType_RAM, 4096, 1));
|
||||
CHECK_ERR(cap_retype(part2_of_big_block, big_block, 4096, ObjType_RAM, 15*4096, 1));
|
||||
CHECK_ERR(cap_destroy(big_block));
|
||||
CHECK_ERR(mm_free(testmm, part2_of_big_block));
|
||||
|
||||
// Allocate all available RAM and then deallocate it again, multiple times.
|
||||
for (int it = 0; it < 5; it++) {
|
||||
for (; alloc_count < 1024*1024; alloc_count++) {
|
||||
err = mm_alloc_aligned(testmm, 256*BASE_PAGE_SIZE, BASE_PAGE_SIZE, &caplist[alloc_count]);
|
||||
if (err_is_fail(err)) {
|
||||
assert(err == MM_ERR_OUT_OF_RAM);
|
||||
break;
|
||||
}
|
||||
if (alloc_count % 10000 == 0) debug_printf("TEST: allocated %lu\n", alloc_count);
|
||||
}
|
||||
debug_printf("TEST: Allocated %"PRIu64" MB of RAM.\n", alloc_count * 256*BASE_PAGE_SIZE / 1024 / 1024);
|
||||
while (alloc_count > 0) {
|
||||
alloc_count--;
|
||||
CHECK_ERR(mm_free(testmm, caplist[alloc_count]));
|
||||
if (alloc_count % 1000 == 0) debug_printf("TEST: freeing %lu\n", alloc_count);
|
||||
}
|
||||
}
|
||||
|
||||
// Test alignment ("e.g., a 4 KiB region must be aligned to a 1 MiB boundary.")
|
||||
for (; alloc_count < 10; alloc_count++) {
|
||||
CHECK_ERR(mm_alloc_aligned(testmm, 4096, 1024*1024, &caplist[alloc_count]));
|
||||
struct capability c;
|
||||
CHECK_ERR( cap_direct_identify(caplist[alloc_count], &c));
|
||||
genpaddr_t base = get_address(&c);
|
||||
assert(base % (1024*1024) == 0);
|
||||
}
|
||||
while (alloc_count > 0) {
|
||||
alloc_count--;
|
||||
CHECK_ERR(mm_free(testmm, caplist[alloc_count]));
|
||||
}
|
||||
|
||||
test_mm_run(test_mm_small, "test_mm_small", testmm);
|
||||
test_mm_run(test_mm_track_slots, "test_mm_track_slots", testmm);
|
||||
test_mm_run(test_mm_fragments, "test_mm_fragments", testmm);
|
||||
test_mm_run(test_mm_rand, "test_mm_rand", testmm);
|
||||
test_mm_run(test_mm_many, "test_mm_many", testmm);
|
||||
test_mm_run(test_mm_oom, "test_mm_oom", testmm);
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
#include <aos/aos.h>
|
||||
#include <test_helper.h>
|
||||
#include <test_paging.h>
|
||||
#include <aos/paging.h>
|
||||
|
||||
// ASSESSMENT M1: these lines show mapping to fixed locations and read/write
|
||||
|
||||
// used to avoid conflicts between tests
|
||||
lvaddr_t vaddr = 0x0000100000000000L;
|
||||
static lvaddr_t vaddr = 0x0000100000000000L;
|
||||
|
||||
uint8_t test_paging_run(errval_t func(void), char *name) {
|
||||
static void test_paging_run(errval_t func(void), char *name) {
|
||||
errval_t err;
|
||||
|
||||
// debug_printf("TEST_PAGING %19s: start\n", name);
|
||||
@ -15,15 +15,13 @@ uint8_t test_paging_run(errval_t func(void), char *name) {
|
||||
|
||||
if (err_is_ok(err)) {
|
||||
debug_printf("TEST_PAGING %23s: OK\n", name);
|
||||
return 1;
|
||||
} else {
|
||||
debug_printf("TEST_PAGING %23s: ERR\n", name);
|
||||
DEBUG_ERR(err, "Test Failed with Error");
|
||||
return 0;
|
||||
USER_PANIC_ERR(err, "Test Failed with Error");
|
||||
}
|
||||
}
|
||||
|
||||
errval_t test_paging_full_l3(void) {
|
||||
static errval_t test_paging_full_l3(void) {
|
||||
errval_t err;
|
||||
|
||||
size_t mapping_size = BASE_PAGE_SIZE;
|
||||
@ -53,7 +51,7 @@ errval_t test_paging_full_l3(void) {
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
errval_t test_paging_full_l2(void) {
|
||||
static errval_t test_paging_full_l2(void) {
|
||||
errval_t err;
|
||||
|
||||
size_t mapping_size = BASE_PAGE_SIZE;
|
||||
@ -83,7 +81,7 @@ errval_t test_paging_full_l2(void) {
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
errval_t test_paging_big_regions(void) {
|
||||
static errval_t test_paging_big_regions(void) {
|
||||
errval_t err;
|
||||
|
||||
size_t mapping_size;
|
||||
@ -114,3 +112,16 @@ errval_t test_paging_big_regions(void) {
|
||||
|
||||
return SYS_ERR_OK;
|
||||
}
|
||||
|
||||
void do_test_paging(void) {
|
||||
test_paging_run(test_paging_full_l3, "test_paging_full_l3");
|
||||
test_paging_run(test_paging_full_l2, "test_paging_full_l2");
|
||||
test_paging_run(test_paging_big_regions, "test_paging_big_regions");
|
||||
|
||||
// Test paging
|
||||
for (int i = 0; i < 40; i++) {
|
||||
debug_printf("TEST: page %lu\n", i);
|
||||
char *data = alloc_frame(5176*4096, 16, NULL, NULL);
|
||||
memset(data, 33, 5176*4096);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user