This includes a set of valid and invalid definition files that MIG will try to process. For valid definitions, GCC will compile the stubs to check if valid C code was generated.
* Makefile.am: Add test target and new files that need to cleaned. * tests/includes/*.h: Test header files that are included by test stubs. * tests/good/*.defs: Valid definition files where generated stubs can be compiled. * tests/generate_only/*.defs: Valid definition files that can be generated but no compilation should be attempted. * tests/bad/*.defs: Definition files with some mistakes that should be recognized by MIG. --- Makefile.am | 8 ++++- tests/bad/invalid_subsystem.defs | 2 ++ tests/bad/no_request_port.defs | 6 ++++ tests/bad/no_subsystem.defs | 3 ++ tests/base_types.defs | 4 +++ tests/generate-only/subsystem-kernel.defs | 2 ++ tests/generate-only/subsystem-user.defs | 2 ++ tests/good/case.defs | 9 +++++ tests/good/complex-types.defs | 22 ++++++++++++ tests/good/directions.defs | 44 +++++++++++++++++++++++ tests/good/import.defs | 6 ++++ tests/good/routine.defs | 17 +++++++++ tests/good/types.defs | 56 +++++++++++++++++++++++++++++ tests/good/waittime.defs | 18 ++++++++++ tests/includes/all.h | 0 tests/includes/server.h | 0 tests/includes/types.h | 23 ++++++++++++ tests/includes/user.h | 0 tests/run_tests.sh | 58 +++++++++++++++++++++++++++++++ 19 files changed, 279 insertions(+), 1 deletion(-) create mode 100644 tests/bad/invalid_subsystem.defs create mode 100644 tests/bad/no_request_port.defs create mode 100644 tests/bad/no_subsystem.defs create mode 100644 tests/base_types.defs create mode 100644 tests/generate-only/subsystem-kernel.defs create mode 100644 tests/generate-only/subsystem-user.defs create mode 100644 tests/good/case.defs create mode 100644 tests/good/complex-types.defs create mode 100644 tests/good/directions.defs create mode 100644 tests/good/import.defs create mode 100644 tests/good/routine.defs create mode 100644 tests/good/types.defs create mode 100644 tests/good/waittime.defs create mode 100644 tests/includes/all.h create mode 100644 tests/includes/server.h create mode 100644 tests/includes/types.h create mode 100644 tests/includes/user.h create mode 100755 tests/run_tests.sh diff --git a/Makefile.am b/Makefile.am index 65737be..4dc9cf9 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,7 @@ AM_YFLAGS = -d EXTRA_DIST = gensym.awk cpu.sym -CLEANFILES = cpu.h *.sym[co] lexxer.c parser.c parser.h +CLEANFILES = cpu.h *.sym[co] lexxer.c parser.c parser.h tests/output/*.[cho] AWK_V = $(AWK_V_$(V)) AWK_V_ = $(AWK_V_$(AM_DEFAULT_VERBOSITY)) @@ -58,3 +58,9 @@ gen-ChangeLog: || exit $$?; \ done; \ fi + +test: $(libexec_PROGRAMS) + cd tests && ./run_tests.sh + +clean-local: + rm -rf tests/output diff --git a/tests/bad/invalid_subsystem.defs b/tests/bad/invalid_subsystem.defs new file mode 100644 index 0000000..e90204a --- /dev/null +++ b/tests/bad/invalid_subsystem.defs @@ -0,0 +1,2 @@ +/* We define a bad subsystem. */ +subsystem mysubsystem a; diff --git a/tests/bad/no_request_port.defs b/tests/bad/no_request_port.defs new file mode 100644 index 0000000..675744d --- /dev/null +++ b/tests/bad/no_request_port.defs @@ -0,0 +1,6 @@ +/* No request port is specified. */ +subsystem test 100; + +#include "../base_types.defs" + +routine myroutine(n : int64_t); diff --git a/tests/bad/no_subsystem.defs b/tests/bad/no_subsystem.defs new file mode 100644 index 0000000..dfa77f1 --- /dev/null +++ b/tests/bad/no_subsystem.defs @@ -0,0 +1,3 @@ +/* No subsystem is specified. */ + +#include "../base_types.defs" diff --git a/tests/base_types.defs b/tests/base_types.defs new file mode 100644 index 0000000..a226056 --- /dev/null +++ b/tests/base_types.defs @@ -0,0 +1,4 @@ +type int = MACH_MSG_TYPE_INTEGER_32; +type int64_t = MACH_MSG_TYPE_INTEGER_64; +type int32_t = MACH_MSG_TYPE_INTEGER_32; +type mach_port_t = MACH_MSG_TYPE_COPY_SEND; diff --git a/tests/generate-only/subsystem-kernel.defs b/tests/generate-only/subsystem-kernel.defs new file mode 100644 index 0000000..f371c87 --- /dev/null +++ b/tests/generate-only/subsystem-kernel.defs @@ -0,0 +1,2 @@ +/* Tests a kernel server subsystem. */ +subsystem KernelServer server 100; diff --git a/tests/generate-only/subsystem-user.defs b/tests/generate-only/subsystem-user.defs new file mode 100644 index 0000000..8e607d8 --- /dev/null +++ b/tests/generate-only/subsystem-user.defs @@ -0,0 +1,2 @@ +/* Tests a kernel user subsystem. */ +subsystem KernelUser user 100; diff --git a/tests/good/case.defs b/tests/good/case.defs new file mode 100644 index 0000000..f05892b --- /dev/null +++ b/tests/good/case.defs @@ -0,0 +1,9 @@ +/* Tests some keywords with different casing. */ +SUBSYSTEM myroutine 100; + +TyPe int = MACH_MSG_TYPE_INTEGER_64; +typE mach_port_t = MACH_MSG_TYPE_COPY_SEND; + +RouTine factorial(port : mach_port_t; + n : int; + out result : int); diff --git a/tests/good/complex-types.defs b/tests/good/complex-types.defs new file mode 100644 index 0000000..8de83de --- /dev/null +++ b/tests/good/complex-types.defs @@ -0,0 +1,22 @@ +/* Tests complex types such as pointers, arrays and structs. */ +subsystem types 0; + +import <stdint.h>; +import "../includes/types.h"; + +type char = MACH_MSG_TYPE_BYTE; +type intptr_t = ^char; +type pointer_t = ^array[] of MACH_MSG_TYPE_BYTE + ctype: vm_offset_t; + +type mach_port_t = MACH_MSG_TYPE_COPY_SEND; +type mach_port_array_t = array[] of mach_port_t; +type char_struct_t = struct[4] of char; +type string_t = array[256] of char; + +routine callcomplex(port : mach_port_t; + p : pointer_t; + q : intptr_t; + str : char_struct_t; + strt : string_t; + out vec : mach_port_array_t); diff --git a/tests/good/directions.defs b/tests/good/directions.defs new file mode 100644 index 0000000..64f810a --- /dev/null +++ b/tests/good/directions.defs @@ -0,0 +1,44 @@ +/* Tests arguments with different directions. */ +subsystem directions 100; + +type char = MACH_MSG_TYPE_BYTE; +type int = MACH_MSG_TYPE_INTEGER_32; + +type mach_port_t = MACH_MSG_TYPE_COPY_SEND; +type mach_port_array_t = array[] of mach_port_t; + +routine callinout(port : mach_port_t; + in n : int; + out result : int); + +routine multiplein(port : mach_port_t; + in n1 : int; + in n2 : int; + in n3 : int; + out result : int); + +routine multipleout(port : mach_port_t; + in n : int; + out result1 : int; + out result2 : int; + out result3 : int); + +routine serverreplyport(port : mach_port_t; + sreplyport server_port : mach_port_t; + in n : int; + out result : int); + +routine userreplyport(port : mach_port_t; + ureplyport user_port : mach_port_t; + out result : int); + +routine myrequestport(requestport port : mach_port_t; + new_port : mach_port_t); + +routine singleinandout(port : mach_port_t; + inout n : int); + +routine multipleinandout(port : mach_port_t; + inout n1 : int; + inout n2 : int; + out result : int); diff --git a/tests/good/import.defs b/tests/good/import.defs new file mode 100644 index 0000000..bb96a72 --- /dev/null +++ b/tests/good/import.defs @@ -0,0 +1,6 @@ +/* Tests the different import statements. */ +subsystem myimport 100; + +simport "../includes/server.h"; +uimport "../includes/user.h"; +import "../includes/all.h"; diff --git a/tests/good/routine.defs b/tests/good/routine.defs new file mode 100644 index 0000000..c80773b --- /dev/null +++ b/tests/good/routine.defs @@ -0,0 +1,17 @@ +/* Tests simple routines. */ +subsystem myroutine 100; + +import <stdint.h>; +#include "../base_types.defs" + +routine factorial(port : mach_port_t; + n : int64_t; + out result : int64_t); + +routine timedoutfactorial(port : mach_port_t; + n : int64_t; + waittime timeout : int32_t; + out result : int64_t); + +simpleroutine simple_factorial(port : mach_port_t; + n : int64_t); diff --git a/tests/good/types.defs b/tests/good/types.defs new file mode 100644 index 0000000..3c43641 --- /dev/null +++ b/tests/good/types.defs @@ -0,0 +1,56 @@ +/* Tests simple types and port types. */ +subsystem types 0; + +import <stdint.h>; +import "../includes/types.h"; +#include "../base_types.defs" + +type char = MACH_MSG_TYPE_CHAR; +type int16_t = MACH_MSG_TYPE_INTEGER_16; +type boolean_t = MACH_MSG_TYPE_BOOLEAN; +type uint16_t = MACH_MSG_TYPE_INTEGER_16; +type uint32_t = MACH_MSG_TYPE_INTEGER_32; +type uint64_t = MACH_MSG_TYPE_INTEGER_64; +type move_receive_t = MACH_MSG_TYPE_MOVE_RECEIVE + ctype: mach_port_t; +type copy_send_t = MACH_MSG_TYPE_COPY_SEND + ctype: mach_port_t; +type move_send_t = MACH_MSG_TYPE_MOVE_SEND + ctype: mach_port_t; +type move_send_once_t = MACH_MSG_TYPE_MOVE_SEND_ONCE + ctype : mach_port_t; +type port_send_t = MACH_MSG_TYPE_PORT_SEND + ctype : mach_port_t; + +type another_int = int + cusertype: int32_t + cservertype: uint32_t; + +type trans_int = int + ctype: int + intran: int8_t int_to_int8(int) + outtran: int int8_to_int(int8_t); + +routine alltypes(port : mach_port_t; + c : char; s : int16_t; i : int; + i32 : int32_t; i64 : int64_t; bool : boolean_t; + ui16 : uint16_t; ui32 : uint32_t; ui64 : uint64_t); + +/* This should fail. */ +/* routine receive(port : move_receive_t); */ + +routine movereceive(port : mach_port_t; copy : move_receive_t); + +routine movesend(port : mach_port_t; copy : move_send_t); + +routine movesendonce(port : mach_port_t; move : move_send_once_t); + +routine copysend(port : mach_port_t; receive : copy_send_t); + +routine portsend(port : mach_port_t; send : port_send_t); + +routine another(port : mach_port_t; + n : another_int); + +routine dotrans(port : mach_port_t; + inout n : trans_int); diff --git a/tests/good/waittime.defs b/tests/good/waittime.defs new file mode 100644 index 0000000..d0d24c7 --- /dev/null +++ b/tests/good/waittime.defs @@ -0,0 +1,18 @@ +/* Tests the wait time directive. */ +subsystem timeout 100; + +import <stdint.h>; +#include "../base_types.defs" + +/* All routines will have this timeout. */ +waittime 2; + +routine factorial(port : mach_port_t; + n : int64_t; + out result : int64_t); + +/* This routine has a waittime argument. */ +routine factorial_waittime(port : mach_port_t; + waittime wait : int32_t; + n : int64_t; + out result : int64_t); diff --git a/tests/includes/all.h b/tests/includes/all.h new file mode 100644 index 0000000..e69de29 diff --git a/tests/includes/server.h b/tests/includes/server.h new file mode 100644 index 0000000..e69de29 diff --git a/tests/includes/types.h b/tests/includes/types.h new file mode 100644 index 0000000..fba9fa7 --- /dev/null +++ b/tests/includes/types.h @@ -0,0 +1,23 @@ +#ifndef TEST_TYPES_H +#define TEST_TYPES_H + +typedef int another_int; + +typedef struct char_struct { + char c1; + char c2; + char c3; + char c4; +} char_struct_t; + +typedef char* string_t; + +static inline int8_t int_to_int8(int n) { + return (int8_t) n; +} + +static inline int int8_to_int(int8_t n) { + return (int) n; +} + +#endif diff --git a/tests/includes/user.h b/tests/includes/user.h new file mode 100644 index 0000000..e69de29 diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100755 index 0000000..15bf2c6 --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,58 @@ +#!/bin/bash + +migcom="../migcom" +output_dir="$PWD/output" + +failure () { + msg="$1" + echo "ERROR: $msg" + return 0 +} + +run_mig () { + file="$1" + module="$2" + echo "Generating stubs for $module..." + mkdir -p $output_dir + cpp $file | $migcom -server $output_dir/$module-server.c -user $output_dir/$module-user.c -header $output_dir/$module-header.h +} + +test_module () { + module="$1" + echo "Compiling stubs for $module..." + gcc -c $output_dir/$module-server.c -o $output_dir/$module-server.o && + gcc -c $output_dir/$module-user.c -o $output_dir/$module-user.o +} + +echo "==> Running good tests..." +for file in `ls good/*.defs`; do + module="$(basename $file .defs)" + if ! run_mig $file $module; then + failure "Could not generate stubs for $module" + exit 1 + fi + if ! test_module $module; then + failure "Could not compile stubs for $module" + exit 1 + fi +done + +echo "==> Running generate_only tests..." +for file in `ls generate-only/*.defs`; do + module="$(basename $file .defs)" + if ! run_mig $file $module; then + failure "Could not generate stubs for $module" + exit 1 + fi +done + +echo "==> Running bad tests..." +for file in `ls bad/*.defs`; do + module="$(basename $file defs)" + if run_mig $file $module; then + failure "$module was supposed to fail" + exit 1 + fi +done + +echo "ALL OK." -- 2.6.4