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.
* configure.ac: Add new test Makefiles. * Makefile.am: Add SUBDIRS. * tests/Makeconf.am: Automake definitions shared by all test subdirectories. * tests/test_lib.sh: Library of functions shared by all test drivers. * tests/good/run_good_test.sh: Script to run valid definition files. * tests/good/Makefile.am: New file. * tests/bad/run_bad_test.sh: Script to run invalid definition files. * tests/bad/Makefile.am: New file. * tests/generate-only/run_generate_only.sh: Script to run valid definition files that should be generated only. * tests/generate-only/Makefile.am: New file. * 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. --- Hey, On Wed, Mar 23, 2016 at 11:17:03AM +0100, Justus Winter wrote: > Quoting Flavio Cruz (2016-03-23 01:31:13) > > 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. > > Love the idea, but 1/ this breaks out of tree (vpath) builds, 2/ I > believe the traditional GNU make target for tests is 'check', 3/ the > test suite fails on Linux b/c of missing mach/mig_support.h, finally > 4/ automake has a test driver that might be useful. Thanks for the comments! I think I have addressed all of them. Let me know if there's anything else missing. Thanks diff --git a/Makefile.am b/Makefile.am index 65737be..5d924da 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,6 +9,8 @@ EXTRA_DIST = gensym.awk cpu.sym CLEANFILES = cpu.h *.sym[co] lexxer.c parser.c parser.h +SUBDIRS = tests + AWK_V = $(AWK_V_$(V)) AWK_V_ = $(AWK_V_$(AM_DEFAULT_VERBOSITY)) AWK_V_0 = @echo " AWK $@"; diff --git a/configure.ac b/configure.ac index 6ffbeda..897d11c 100644 --- a/configure.ac +++ b/configure.ac @@ -59,4 +59,7 @@ AC_SUBST([MIGCOM]) [MIG=`echo mig | sed "$program_transform_name"`] AC_SUBST([MIG]) -AC_OUTPUT([Makefile mig]) +AC_OUTPUT([Makefile mig tests/Makefile \ + tests/good/Makefile \ + tests/generate-only/Makefile \ + tests/bad/Makefile]) diff --git a/tests/Makeconf.am b/tests/Makeconf.am new file mode 100644 index 0000000..d1c202b --- /dev/null +++ b/tests/Makeconf.am @@ -0,0 +1,5 @@ +MOSTLYCLEANFILES = *.[coh] + +TEST_EXTENSIONS = .defs +AM_TESTS_ENVIRONMENT = SRCDIR='$(top_srcdir)' BUILDDIR='$(top_builddir)' \ + CC='$(CC)' diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..453aed0 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = good generate-only bad diff --git a/tests/bad/Makefile.am b/tests/bad/Makefile.am new file mode 100644 index 0000000..ea6dd9a --- /dev/null +++ b/tests/bad/Makefile.am @@ -0,0 +1,4 @@ +TESTS = invalid_subsystem.defs no_request_port.defs no_subsystem.defs +DEFS_LOG_COMPILER = sh ./$(srcdir)/run_bad_test.sh + +include $(srcdir)/../Makeconf.am 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/bad/run_bad_test.sh b/tests/bad/run_bad_test.sh new file mode 100755 index 0000000..84c18c1 --- /dev/null +++ b/tests/bad/run_bad_test.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +. $SRCDIR/tests/test_lib.sh + +file=$1 +module="$(basename $file .defs)" +if run_mig $file $module; then + failure "$module was supposed to fail" + exit 1 +fi 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/Makefile.am b/tests/generate-only/Makefile.am new file mode 100644 index 0000000..8b6f2ca --- /dev/null +++ b/tests/generate-only/Makefile.am @@ -0,0 +1,4 @@ +TESTS = subsystem-kernel.defs subsystem-user.defs +DEFS_LOG_COMPILER = sh ./$(srcdir)/run_generate_only_test.sh + +include $(srcdir)/../Makeconf.am diff --git a/tests/generate-only/run_generate_only_test.sh b/tests/generate-only/run_generate_only_test.sh new file mode 100755 index 0000000..3456dd3 --- /dev/null +++ b/tests/generate-only/run_generate_only_test.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +. $SRCDIR/tests/test_lib.sh + +file=$1 +module="$(basename $file .defs)" +if ! run_mig $file $module; then + failure "Could not generate stubs for $module" + exit 1 +fi 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/Makefile.am b/tests/good/Makefile.am new file mode 100644 index 0000000..01fa9a4 --- /dev/null +++ b/tests/good/Makefile.am @@ -0,0 +1,5 @@ +TESTS = case.defs complex-types.defs directions.defs import.defs \ + routine.defs types.defs waittime.defs +DEFS_LOG_COMPILER = sh ./$(srcdir)/run_good_test.sh + +include $(srcdir)/../Makeconf.am 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..5bfab73 --- /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 "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..7c7d213 --- /dev/null +++ b/tests/good/import.defs @@ -0,0 +1,6 @@ +/* Tests the different import statements. */ +subsystem myimport 100; + +simport "server.h"; +uimport "user.h"; +import "all.h"; diff --git a/tests/good/routine.defs b/tests/good/routine.defs new file mode 100644 index 0000000..222a4cd --- /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/run_good_test.sh b/tests/good/run_good_test.sh new file mode 100755 index 0000000..9ff8fc1 --- /dev/null +++ b/tests/good/run_good_test.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +. $SRCDIR/tests/test_lib.sh + +file=$1 +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 diff --git a/tests/good/types.defs b/tests/good/types.defs new file mode 100644 index 0000000..1114ad6 --- /dev/null +++ b/tests/good/types.defs @@ -0,0 +1,56 @@ +/* Tests simple types and port types. */ +subsystem types 0; + +import <stdint.h>; +import "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/mach/mig_support.h b/tests/includes/mach/mig_support.h new file mode 100644 index 0000000..e725a63 --- /dev/null +++ b/tests/includes/mach/mig_support.h @@ -0,0 +1 @@ +/* This file allows the testsuite to compile under Linux. */ 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/test_lib.sh b/tests/test_lib.sh new file mode 100644 index 0000000..8593fb5 --- /dev/null +++ b/tests/test_lib.sh @@ -0,0 +1,25 @@ +#!/bin/sh + +MIGCOM="$BUILDDIR/migcom" +TEST_DIR="$SRCDIR/tests" +CFLAGS="-I$TEST_DIR/includes" + +failure () { + msg="$1" + echo "ERROR: $msg" + return 0 +} + +run_mig () { + file="$1" + module="$2" + echo "Generating stubs for $module..." + cpp $file -I$TEST_DIR | $MIGCOM -server $module-server.c -user $module-user.c -header $module-header.h +} + +test_module () { + module="$1" + echo "Compiling stubs for $module..." + $CC $CFLAGS -c $module-server.c -o $module-server.o && + $CC $CFLAGS -c $module-user.c -o $module-user.o +} -- 2.6.4