1/* 2 * Copyright 2016, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(D61_BSD) 11 */ 12 13#include <autoconf.h> 14#ifdef CONFIG_REFOS_RUN_TESTS 15 16#include <stdlib.h> 17#include <string.h> 18#include <autoconf.h> 19#include <refos/test.h> 20#include "test.h" 21#include "test_process.h" 22#include "../system/process/pid.h" 23#include "../system/process/thread.h" 24#include "../system/process/proc_client_watch.h" 25#include "../state.h" 26#include "../common.h" 27 28/* ------------------------------- PID / ASID module test ------------------------------- */ 29 30static void 31test_pid_iteration_callback(struct proc_pcb *pcb, void *cookie) 32{ 33 assert(cookie); 34 int *result = (int*) cookie; 35 (*result)++; 36} 37 38int 39test_pid(void) 40{ 41 test_start("PID"); 42 43 uint32_t testPID; 44 uint32_t emptyIndex = 0; 45 uint32_t pidTable[PID_MAX]; 46 struct proc_pcb *pcb; 47 int count = 0, expectedCount = 0; 48 49 /* Assign _ALL_ the ID. */ 50 for (int i = 0; i < (PID_MAX - 1); i++) { 51 testPID = pid_alloc(&procServ.PIDList); 52 test_assert(testPID != PID_NULL); 53 54 /* Check no duplication. */ 55 for (int j = 0; j < i; j++) { 56 test_assert(pidTable[j] != testPID); 57 } 58 59 pidTable[i] = testPID; 60 expectedCount++; 61 } 62 63 /* Free all the even indexed ID. */ 64 for (int i = 0; i < (PID_MAX - 1); i += 2) { 65 pid_free(&procServ.PIDList, pidTable[i]); 66 pidTable[i] = PID_NULL; 67 expectedCount--; 68 } 69 70 /* Test PID iteration. */ 71 pid_iterate(&procServ.PIDList, test_pid_iteration_callback, (void*)(&count)); 72 test_assert(count == expectedCount); 73 74 /* Test find. */ 75 for (int i = 0; i < (PID_MAX - 1); i++) { 76 pcb = pid_get_pcb(&procServ.PIDList, pidTable[i]); 77 if (pidTable[i] == PID_NULL) { 78 test_assert(pcb == NULL); 79 } else { 80 test_assert(pcb != NULL); 81 } 82 } 83 84 /* Assign all the even ID again. */ 85 for (int i = 0; i < (PID_MAX - 1); i += 2) { 86 testPID = pid_alloc(&procServ.PIDList); 87 test_assert(testPID != PID_NULL); 88 89 /* Check no duplication. */ 90 for (int j = 0; j < (PID_MAX - 1); j++) { 91 if (pidTable[j] == PID_NULL) { 92 emptyIndex = j; 93 } 94 test_assert(pidTable[j] != testPID); 95 } 96 97 pidTable[emptyIndex] = testPID; 98 } 99 100 /* Test find again. */ 101 for (int i = 0; i < (PID_MAX - 1); i++) { 102 pcb = pid_get_pcb(&procServ.PIDList, pidTable[i]); 103 test_assert(pcb != NULL); 104 } 105 106 /* Free all the IDs. */ 107 for (int i = 0; i < (PID_MAX - 1); i++) { 108 pid_free(&procServ.PIDList, pidTable[i]); 109 } 110 111 return test_success(); 112} 113 114/* ------------------------------------- Thread module test ------------------------------------- */ 115 116int 117test_thread(void) 118{ 119 test_start("thread"); 120 const int numTestThreads = 32; 121 struct proc_tcb thr[numTestThreads]; 122 123 /* Create a vspace for threads to go into. */ 124 struct vs_vspace vs; 125 int error = vs_initialise(&vs, 31337); 126 test_assert(error == ESUCCESS); 127 test_assert(vs.magic == REFOS_VSPACE_MAGIC); 128 129 /* Create the threads. */ 130 for (int i = 0; i < numTestThreads; i++) { 131 int error = thread_config(&thr[i], 12, 1337, &vs); 132 test_assert(error == ESUCCESS); 133 test_assert(thr[i].magic == REFOS_PROCESS_THREAD_MAGIC); 134 test_assert(thr[i].priority == 12); 135 test_assert(thr[i].vspaceRef == &vs); 136 test_assert(thr[i].entryPoint == 1337); 137 138 /* Test that the vspace has been referenced. */ 139 test_assert(vs.magic == REFOS_VSPACE_MAGIC); 140 test_assert(vs.ref == 1 + 1 + i); 141 } 142 143 /* We can't really test starting them without causing a horrible mess of things. */ 144 145 /* Free all the threads. */ 146 for (int i = 0; i < numTestThreads; i++) { 147 thread_release(&thr[i]); 148 test_assert(thr[i].magic != REFOS_PROCESS_THREAD_MAGIC); 149 } 150 151 /* Free the vspace. */ 152 test_assert(vs.ref == 1); 153 vs_unref(&vs); 154 test_assert(vs.ref == 0); 155 test_assert(vs.magic != REFOS_VSPACE_MAGIC); 156 157 return test_success(); 158} 159 160/* ------------------------------- Proc Watch Client module test -------------------------------- */ 161 162int 163test_proc_client_watch(void) 164{ 165 test_start("client watch"); 166 struct proc_watch_list wl; 167 client_watch_init(&wl); 168 169 const uint32_t dummyPIDs[] = {0x312, 0x32, 0xF2, 0x6F}; 170 vka_object_t dummyEP[4]; 171 cspacepath_t dummyEPMinted[4]; 172 173 /* Create dummy async EPs to test with. */ 174 for (int i = 0; i < 4; i++) { 175 /* Create endpoint. */ 176 int error = vka_alloc_notification(&procServ.vka, &dummyEP[i]); 177 test_assert(!error); 178 test_assert(dummyEP[i].cptr != 0); 179 180 /* Copy a copy of the endpoint. */ 181 cspacepath_t srcPath; 182 vka_cspace_make_path(&procServ.vka, dummyEP[i].cptr, &srcPath); 183 error = vka_cspace_alloc_path(&procServ.vka, &dummyEPMinted[i]); 184 test_assert(!error); 185 error = vka_cnode_mint(&dummyEPMinted[i], &srcPath, seL4_AllRights, 186 seL4_CapData_Badge_new(123)); 187 test_assert(!error); 188 } 189 190 /* Watch a bunch of test clients and dummy notify EPs. */ 191 for (int i = 0; i < 4; i++) { 192 int error = client_watch(&wl, dummyPIDs[i], dummyEPMinted[i].capPtr); 193 test_assert(error == ESUCCESS); 194 } 195 196 /* Test that getting an invalid PID results in a NULL CPtr. */ 197 seL4_CPtr cpInvalid = client_watch_get(&wl, 0x2FF); 198 test_assert(cpInvalid == 0); 199 200 /* Get our PIDs and see if we get out EPs back. */ 201 for (int i = 0; i < 4; i++) { 202 seL4_CPtr cp = client_watch_get(&wl, dummyPIDs[i]); 203 test_assert(cp == dummyEPMinted[i].capPtr); 204 /* Unwatch the client and see if we still get it. */ 205 client_unwatch(&wl, dummyPIDs[i]); 206 cp = client_watch_get(&wl, dummyPIDs[i]); 207 test_assert(cp == 0); 208 } 209 210 /* Release all allocated endpoints. Note that the client_watch call takes ownership of the 211 minted caps along with their cslots, so we do NOT need to free those here. */ 212 for (int i = 0; i < 4; i++) { 213 cspacepath_t path; 214 vka_cspace_make_path(&procServ.vka, dummyEP[i].cptr, &path); 215 vka_cnode_revoke(&path); 216 vka_cnode_delete(&path); 217 vka_free_object(&procServ.vka, &dummyEP[i]); 218 } 219 220 client_watch_release(&wl); 221 return test_success(); 222} 223 224#endif /* CONFIG_REFOS_RUN_TESTS */ 225