#include #include #include #include #include #include #include #include #include #include extern void* mono_aot_module_mscorlib_info; extern void* mono_aot_module_System_Core_info; extern void* mono_aot_module_System_info; extern void* mono_aot_module_Mono_Posix_info; extern void* mono_aot_module_System_Configuration_info; extern void* mono_aot_module_System_Security_info; extern void* mono_aot_module_System_Xml_info; /* extern void* mono_aot_module_System_Threading_info; */ extern void* mono_aot_module_Mono_Security_info; extern void* mono_aot_module_Mono_Simd_info; extern void* mono_aot_module_TestDriver_info; extern void* mono_aot_module_basic_info; extern void* mono_aot_module_basic_float_info; extern void* mono_aot_module_basic_long_info; extern void* mono_aot_module_basic_calls_info; extern void* mono_aot_module_basic_simd_info; extern void* mono_aot_module_objects_info; extern void* mono_aot_module_arrays_info; extern void* mono_aot_module_basic_math_info; extern void* mono_aot_module_exceptions_info; extern void* mono_aot_module_devirtualization_info; extern void* mono_aot_module_generics_info; extern void* mono_aot_module_generics_variant_types_info; extern void* mono_aot_module_basic_simd_info; extern void* mono_aot_module_gc_stress_info; extern void* mono_aot_module_imt_big_iface_test_info; extern void* mono_aot_module_make_imt_test_info; /* extern void* mono_aot_module_thread_stress_info; */ extern void* mono_aot_module_iltests_info; extern void mono_aot_register_module(void *aot_info); extern void mono_aot_init(void); extern void mono_jit_set_aot_only(mono_bool aot_only); extern MonoDomain * mini_init (const char *filename, const char *runtime_version); int run_all_test_methods(MonoClass *klass) { void * iter = NULL; MonoMethod *mm = NULL; int count = 0; int passed = 0; printf("Running test methods without reflection\n"); while (NULL != (mm = mono_class_get_methods(klass, &iter))) { long expected_result; const char *name = mono_method_get_name(mm); char *end = NULL; if (strncmp(name, "test_", 5)) continue; printf("=== Test %d, method %s\n", count, mono_method_get_name(mm)); expected_result = strtol(name + 5, &end, 10); if (name == end) { printf(" warning: could not determine expected return value\n"); expected_result = 0; } MonoObject *mo = mono_runtime_invoke(mm, NULL, NULL, NULL); int *ret = mono_object_unbox(mo); if (ret && *ret == expected_result) { printf(" passed!\n"); passed++; } else { printf(" FAILED, expected %d, returned %p, %d\n", expected_result, ret, ret != NULL ? *ret : 0); } count++; } if (count > 0) { printf("============================================\n"); printf("Final count: %d tests, %d pass, %.2f%%\n", count, passed, (double)passed / count * 100.0); } else { printf("no test methods found.\n"); } return count; } #if defined(__native_client__) extern void* mono_aot_module_nacl_info; extern char* nacl_mono_path; char *load_corlib_data() { FILE *mscorlib; static char *corlib_data = NULL; if (corlib_data) return corlib_data; mscorlib = fopen("mscorlib.dll", "r"); if (NULL != mscorlib) { size_t size; struct stat st; if (0 == stat("mscorlib.dll", &st)) { size = st.st_size; printf("reading mscorlib.dll, size %ld\n", size); corlib_data = malloc(size); if (corlib_data != NULL) { while (fread(corlib_data, 1, size, mscorlib) != 0) ; if (!ferror(mscorlib)) { mono_set_corlib_data(corlib_data, size); } else { perror("error reading mscorlib.dll"); free(corlib_data); corlib_data = NULL; } } else { perror("Could not allocate memory"); } } else { perror("stat error"); } fclose(mscorlib); } return corlib_data; } #endif /* Initialize Mono. Must run only once per process */ MonoDomain *init_mono(char *mname) { MonoDomain *domain = NULL; #ifdef AOT_VERSION mono_jit_set_aot_only(1); mono_aot_register_module(mono_aot_module_mscorlib_info); mono_aot_register_module(mono_aot_module_TestDriver_info); mono_aot_register_module(mono_aot_module_System_Core_info); mono_aot_register_module(mono_aot_module_System_info); mono_aot_register_module(mono_aot_module_Mono_Posix_info); mono_aot_register_module(mono_aot_module_System_Configuration_info); mono_aot_register_module(mono_aot_module_System_Security_info); mono_aot_register_module(mono_aot_module_System_Xml_info); mono_aot_register_module(mono_aot_module_Mono_Security_info); /* mono_aot_register_module(mono_aot_module_System_Threading_info); */ mono_aot_register_module(mono_aot_module_Mono_Simd_info); mono_aot_register_module(mono_aot_module_basic_info); mono_aot_register_module(mono_aot_module_basic_float_info); mono_aot_register_module(mono_aot_module_basic_long_info); mono_aot_register_module(mono_aot_module_basic_calls_info); mono_aot_register_module(mono_aot_module_basic_simd_info); mono_aot_register_module(mono_aot_module_objects_info); mono_aot_register_module(mono_aot_module_arrays_info); mono_aot_register_module(mono_aot_module_basic_math_info); mono_aot_register_module(mono_aot_module_exceptions_info); mono_aot_register_module(mono_aot_module_devirtualization_info); mono_aot_register_module(mono_aot_module_generics_info); mono_aot_register_module(mono_aot_module_generics_variant_types_info); mono_aot_register_module(mono_aot_module_gc_stress_info); mono_aot_register_module(mono_aot_module_imt_big_iface_test_info); mono_aot_register_module(mono_aot_module_iltests_info); #endif /* mono_aot_register_module(mono_aot_module_make_imt_test_info); */ /* mono_aot_register_module(mono_aot_module_thread_stress_info); */ #if defined(__native_client__) #ifdef AOT_VERSION mono_aot_register_module(mono_aot_module_nacl_info); #endif /* Test file-less shortcut for loading mscorlib metadata */ load_corlib_data(); nacl_mono_path = strdup("."); #endif /* Uncomment the following if something is going wrong */ /* mono_trace_set_level_string("info"); */ domain = mono_jit_init(mname); if (NULL == domain) { printf("ERROR: mono_jit_init failure\n"); exit(-1); } return domain; } /* Run all tests from one assembly file */ int try_one(char *mname, MonoDomain *domain) { MonoAssembly *ma; MonoImage *mi; MonoClass *mc; MonoMethodDesc *mmd; MonoMethod *mm; MonoObject *mo; MonoString *monostring_arg; MonoArray *arg_array; int *failures = NULL; const int kUseTestDriver = 1; int test_count = 0; void *args [1]; char *cstr_arg = "--timing"; ma = mono_domain_assembly_open(domain, mname); if (NULL == ma) { printf("ERROR: could not open mono assembly\n"); exit(-1); } mi = mono_assembly_get_image(ma); if (NULL == mi) { printf("ERROR: could not get assembly image\n"); exit(-1); } monostring_arg = mono_string_new(domain, cstr_arg); mc = mono_class_from_name(mono_get_corlib(), "System", "String"); if (0 == mc) { printf("ERROR: could not mono string class\n"); exit(-1); } // to pass a string argument, change the 0 to a 1 and uncomment // mono_array_setref below arg_array = mono_array_new(domain, mc, 0); //mono_array_setref(arg_array, 0, monostring_arg); args[0] = arg_array; if (!kUseTestDriver) { mc = mono_class_from_name(mi, "", "Tests"); if (NULL == mc) { printf("could not open Tests class\n"); exit(-1); } test_count = run_all_test_methods(mc); } /* If run_all_test_methods didn't find any tests, try Main */ if (kUseTestDriver || test_count == 0) { mmd = mono_method_desc_new("Tests:Main()", 1); mm = mono_method_desc_search_in_image(mmd, mi); if (0 == mm) { mmd = mono_method_desc_new("Tests:Main(string[])", 1); mm = mono_method_desc_search_in_image(mmd, mi); if (0 == mm) { printf("Couldn't find Tests:Main() or Tests:Main(string[])\n"); exit(-1); } } mo = mono_runtime_invoke(mm, NULL, args, NULL); failures = mo != NULL ? mono_object_unbox(mo) : NULL; if (NULL == failures || *failures != 0) { printf("--------------------> Failed"); } } return failures != NULL ? failures : 1; } int main(int argc, char *argv[]) { MonoDomain *domain; int failures = 0; if (argc < 2) { printf("no test specified; running basic.exe\n"); printf("================================\n"); domain = init_mono("basic.exe"); try_one("basic.exe", domain); } else { domain = init_mono(argv[1]); int i; for (i = 1; i < argc; i++) { printf("\nRunning tests from %s:\n", argv[i]); printf("===============================\n\n"); failures += try_one(argv[i], domain); } } mono_jit_cleanup(domain); return failures; }