def check_self_assemblation() -> List[Check]: return check_execution('./selfie -c selfie.c -s selfie1.s', 'preparation: selfie can compile and assemble its own source', mandatory=True) + \ check_execution('./selfie -a selfie1.s -o selfie1.m -m 128 -c selfie.c -o selfie2.m', 'selfie can re-assemble its own binary file', mandatory=True) + \ check_execution('diff -q selfie1.m selfie2.m', 'both binary files are exactly the same', mandatory=True)
def check_treiber_stack() -> List[Check]: return check_riscv_instruction(LR_INSTRUCTION, 'load-reserved.c') + \ check_riscv_instruction(SC_INSTRUCTION, 'store-conditional.c') + \ check_execution('./selfie -c treiber-stack.c <assignment>stack-push.c -m 128', 'all pushed elements are actually in the treiber-stack', success_criteria=lambda code, out: is_permutation_of(out, [0, 1, 2, 3, 4, 5, 6, 7])) + \ check_execution('./selfie -c treiber-stack.c <assignment>stack-pop.c -m 128', 'all treiber-stack elements can be popped ', success_criteria=lambda code, out: is_permutation_of(out, [0, 1, 2, 3, 4, 5, 6, 7]))
def check_assembler_parser() -> List[Check]: return check_execution('./selfie -c selfie.c -s selfie.s -a selfie.s', 'selfie can parse its own implementation in assembly') + \ check_execution('./selfie -a <assignment>missing-address.s', 'assembly file with a missing address is not parseable', success_criteria=False) + \ check_execution('./selfie -a <assignment>missing-instruction.s', 'assembly file with a missing instruction is not parseable', success_criteria=False) + \ check_execution('./selfie -a <assignment>missing-literal.s', 'assembly file with a missing literal is not parseable', success_criteria=False)
def check_threads() -> List[Check]: return check_execution('./selfie -c <assignment>syscalls.c -m 128', 'creates a thread, where the parent can join the thread with MIPSTER', success_criteria=70) + \ check_execution('./selfie -c selfie.c -m 128 -c <assignment>syscalls.c -y 64', 'creates a thread, where the parent can join the thread with HYPSTER', success_criteria=70) + \ check_mipster_execution('shared-data.c', 42, 'data section is shared for threads on MIPSTER') + \ check_hypster_execution('shared-data.c', 42, 'data section is shared for threads on HYPSTER') + \ check_mipster_execution('shared-heap.c', 42, 'heap data is shared for threads on MIPSTER') + \ check_hypster_execution('shared-heap.c', 42, 'heap data is shared for threads on HYPSTER')
def check_lock() -> List[Check]: return check_execution('./selfie -c <assignment>print-without-lock.c -m 128', '16 processes are running concurrently on MIPSTER', success_criteria=lambda code, out: is_interleaved_output(out, 'Hello World! ', 8)) + \ check_execution('./selfie -c selfie.c -m 128 -c <assignment>print-without-lock.c -y 10', '16 processes are running concurrently on HYPSTER', success_criteria=lambda code, out: is_interleaved_output(out, 'Hello World! ', 8)) + \ check_execution('./selfie -c <assignment>print-with-lock.c -m 128', '16 processes are printing in sequential order with the use of locks on MIPSTER', success_criteria='Hello World! ' * 8) + \ check_execution('./selfie -c selfie.c -m 128 -c <assignment>print-with-lock.c -y 10', '16 processes are printing in sequential order with the use of locks on HYPSTER', success_criteria='Hello World! ' * 8)
def check_lock() -> List[Check]: return check_execution('./selfie -c <assignment>print-without-lock.c -m 128', '16 processes are running concurrently on MIPSTER', success_criteria=lambda code, out: is_interleaved_output(out, 'Hello World! ', 8)) + \ check_execution('./selfie -c selfie.c -m 128 -c <assignment>print-without-lock.c -y 10', '16 processes are running concurrently on HYPSTER', success_criteria=lambda code, out: is_interleaved_output(out, 'Hello World! ', 8)) + \ check_execution('./selfie -c <assignment>print-with-lock.c -m 128', '16 processes are printing in sequential order with the use of locks on MIPSTER', success_criteria='Hello World! ' * 8) + \ check_execution('./selfie -c selfie.c -m 128 -c <assignment>print-with-lock.c -y 10', '16 processes are printing in sequential order with the use of locks on HYPSTER', success_criteria='Hello World! ' * 8) + \ check_execution('./selfie -c <assignment>release-after-exit.c -m 128', 'Lock is granted to a process after a terminated process did not release its lock', success_criteria='Hello child! Hello parent! ', timeout=5)
def check_threads() -> List[Check]: return check_execution('./selfie -c <assignment>syscalls.c -m 128', 'creates a thread, where the parent can join the thread with MIPSTER', success_criteria=70) + \ check_execution('./selfie -c selfie.c -m 128 -c <assignment>syscalls.c -y 64', 'creates a thread, where the parent can join the thread with HYPSTER', success_criteria=70) + \ check_mipster_execution('shared-data.c', 42, 'data section is shared for threads on MIPSTER') + \ check_hypster_execution('shared-data.c', 42, 'data section is shared for threads on HYPSTER') + \ check_mipster_execution('shared-heap.c', 42, 'heap data is shared for threads on MIPSTER') + \ check_hypster_execution('shared-heap.c', 42, 'heap data is shared for threads on HYPSTER') + \ check_mipster_execution('sum-integer-dekker.c', 210, 'two threads correctly calculate the sum from 1 to 20 with Dekker\'s algorithm on MIPSTER') +\ check_hypster_execution('sum-integer-dekker.c', 210, 'two threads correctly calculate the sum from 1 to 20 with Dekker\'s algorithm on HYPSTER')
def check_assembler_parser() -> List[Check]: return check_execution('./selfie -c selfie.c -s selfie.s -a selfie.s', 'selfie can parse its own implementation in assembly') + \ check_execution('./selfie -a <assignment>valid-registers-add.s', 'assembly file with valid register access for RISC-U add instruction') + \ check_execution('./selfie -a <assignment>valid-registers-addi.s', 'assembly file with valid register access for RISC-U addi instruction') + \ check_execution('./selfie -a <assignment>valid-hex.s', 'assembly file with valid hex numbers') + \ check_execution('./selfie -a <assignment>invalid-argument-add.s', 'assembly file with a invalid argument is not parseable', should_succeed=False) + \ check_execution('./selfie -a <assignment>missing-instruction.s', 'assembly file with a missing instruction is not parseable', should_succeed=False) + \ check_execution('./selfie -a <assignment>missing-literal.s', 'assembly file with a missing literal is not parseable', should_succeed=False)
def check_print_your_name() -> List[Check]: return check_execution( './selfie -c selfie.c -m 128', 'selfie prints first and second name', success_criteria=lambda code, out: contains_name(out))
def check_self_compilation(mandatory=False) -> List[Check]: return check_execution('make clean selfie', 'cc compiles selfie.c', mandatory=mandatory) + \ check_compile_warnings( 'selfie.c', 'self-compilation does not lead to warnings or syntax errors', mandatory=mandatory)
def check_self_assemblation() -> List[Check]: return check_execution('./selfie -c selfie.c -s selfie1.s -a selfie1.s -o selfie1.m -m 128 -c selfie.c -o selfie2.m', 'selfie can re-assemble its own binary file') + \ check_execution('diff -q selfie1.m selfie2.m', 'both binary files are exactly the same')