Add a rudimentary testsuite.

This adds a very primitive test harness and tests relevant to the recent
changes to how program startup works, as well as the upcoming changes
to support LTO.
pull/92/head
Dan Gohman 5 years ago
parent 2bfea0cc96
commit 21657b7a78

2
tests/.gitignore vendored

@ -0,0 +1,2 @@
*.observed
*.wasm

@ -0,0 +1,19 @@
#include <stdio.h>
#include <limits.h>
extern void __dso_handle;
extern void __data_end;
extern void __global_base;
extern void __heap_base;
int main(int argc, char *argv[]) {
printf("NULL=%p\n", NULL);
printf("__dso_handle=%p\n", &__dso_handle);
printf("__data_end=%p\n", &__data_end);
printf("__global_base=%p\n", &__global_base);
printf("__heap_base=%p\n", &__heap_base);
printf("__builtin_frame_address(0)=%p\n", __builtin_frame_address(0));
printf("__builtin_alloca(0)=%p\n", __builtin_alloca(0));
printf("__builtin_wasm_memory_size(0)=%p\n", (void *)(__builtin_wasm_memory_size(0) * PAGE_SIZE));
return 0;
}

@ -0,0 +1,13 @@
(module
(type (;0;) (func))
(type (;1;) (func (result i32)))
(func $__wasm_call_ctors (type 0))
(func $_start (type 0)
call $__wasm_call_ctors)
(func $__main_void (type 1) (result i32)
i32.const 0)
(table (;0;) 1 1 funcref)
(memory (;0;) 2)
(global (;0;) (mut i32) (i32.const 66560))
(export "memory" (memory 0))
(export "_start" (func $_start)))

@ -0,0 +1,6 @@
#include <stdio.h>
int main(int argc, char *argv[]) {
puts("hello from argc argv main!");
return 0;
}

@ -0,0 +1,6 @@
#include <stdio.h>
int main(int argc, char *argv[]) {
puts("hello from C++ argc argv main!");
return 0;
}

@ -0,0 +1 @@
hello from C++ argc argv main!

@ -0,0 +1,52 @@
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <errno.h>
extern char **environ;
static void from_atexit(void) {
printf("hello from_atexit\n");
}
static void another_from_atexit(void) {
printf("hello another_from_atexit\n");
}
__attribute__((constructor)) static void from_constructor(void) {
printf("hello from_constructor\n");
}
__attribute__((constructor(101))) static void from_constructor_101(void) {
assert(errno == 0);
printf("hello from_constructor101\n");
assert(environ && "environment should be initialized by this point");
}
__attribute__((constructor(65535))) static void from_constructor_65535(void) {
printf("hello from_constructor65535\n");
}
__attribute__((destructor)) static void from_destructor(void) {
printf("hello from_destructor\n");
}
__attribute__((destructor(101))) static void from_destructor101(void) {
printf("hello from_destructor101\n");
}
__attribute__((destructor(65535))) static void from_destructor65535(void) {
printf("hello from_destructor65535\n");
}
int main(int argc, char *argv[]) {
printf("hello main\n");
assert(argc != 0);
assert(argv != NULL);
assert(argv[argc] == NULL);
atexit(from_atexit);
atexit(another_from_atexit);
printf("goodbye main\n");
return 0;
}

@ -0,0 +1,10 @@
hello from_constructor101
hello from_constructor
hello from_constructor65535
hello main
goodbye main
hello another_from_atexit
hello from_atexit
hello from_destructor65535
hello from_destructor
hello from_destructor101

@ -0,0 +1,16 @@
#include "ctors_dtors.c"
struct StaticObject {
StaticObject();
~StaticObject();
};
StaticObject::StaticObject() {
printf("hello StaticObject::StaticObject\n");
}
StaticObject::~StaticObject() {
printf("hello StaticObject::~StaticObject\n");
}
static StaticObject static_object;

@ -0,0 +1,12 @@
hello from_constructor101
hello from_constructor
hello from_constructor65535
hello StaticObject::StaticObject
hello main
goodbye main
hello another_from_atexit
hello from_atexit
hello from_destructor65535
hello from_destructor
hello StaticObject::~StaticObject
hello from_destructor101

@ -0,0 +1 @@
int main(void) { return 0; }

@ -0,0 +1,6 @@
#include <iostream>
int main() {
std::cout << "hello from C++ main with cout!" << std::endl;
return 0;
}

@ -0,0 +1 @@
hello from C++ main with cout!

@ -0,0 +1,12 @@
#include <stdio.h>
#include <errno.h>
#include <string.h>
// It isn't required that errno be zero on entry to main, but
// for tidiness' sake, if we ever do things during startup that
// do set errno, we should reset it for tidiness' sake.
int main(void) {
int n = errno;
printf("initial errno is %d: %s\n", n, strerror(n));
return 0;
}

@ -0,0 +1 @@
initial errno is 0: Success

@ -0,0 +1,6 @@
#include <stdio.h>
int main() {
puts("hello from no-arg main!");
return 0;
}

@ -0,0 +1,6 @@
#include <stdio.h>
int main() {
puts("hello from C++ no-arg main!");
return 0;
}

@ -0,0 +1 @@
hello from C++ no-arg main!

@ -0,0 +1,6 @@
#include <stdio.h>
int main(void) {
puts("hello from void main!");
return 0;
}

@ -0,0 +1,6 @@
#include <stdio.h>
int main(void) {
puts("hello from C++ void main!");
return 0;
}

@ -0,0 +1 @@
hello from C++ void main!

@ -0,0 +1,32 @@
#!/bin/bash
set -ueo pipefail
runwasm="$1"
cd compile-only
for options in -O0 -O2 "-O2 -flto"; do
echo "===== Testing compile-only with $options ====="
for file in *.c; do
echo "Testing compile-only $file..."
../testcase.sh true clang "$options" "$file"
done
for file in *.cc; do
echo "Testing compile-only $file..."
../testcase.sh true clang++ "$options" "$file"
done
done
cd - >/dev/null
cd general
for options in -O0 -O2 "-O2 -flto"; do
echo "===== Testing with $options ====="
for file in *.c; do
echo "Testing $file..."
../testcase.sh "$runwasm" clang "$options" "$file"
done
for file in *.cc; do
echo "Testing $file..."
../testcase.sh "$runwasm" clang++ "$options" "$file"
done
done
cd - >/dev/null

@ -0,0 +1,57 @@
#!/bin/bash
set -ueo pipefail
# A simple testcase runner that runs a command, captures all its command-line
# outputs, and compares them against expected outputs.
runwasm="$1"
clang="$2"
options="$3"
input="$4"
wasm="$input.$options.wasm"
stdout_observed="$input.$options.stdout.observed"
stderr_observed="$input.$options.stderr.observed"
exit_status_observed="$input.$options.exit_status.observed"
if [ -e "$input.options" ]; then
file_options=$(cat "$inpit.options")
else
file_options=
fi
echo "Testing $input..."
"$clang" $options $file_options "$input" -o "$wasm"
if [ -e "$input.stdin" ]; then
stdin="$input.stdin"
else
stdin="/dev/null"
fi
exit_status=0
"$runwasm" "$wasm" \
< "$stdin" \
> "$stdout_observed" \
2> "$stderr_observed" \
|| exit_status=$?
echo $exit_status > "$exit_status_observed"
if [ -e "$input.stdout.expected" ]; then
stdout_expected="$input.stdout.expected"
else
stdout_expected="/dev/null"
fi
if [ -e "$input.stderr.expected" ]; then
stderr_expected="$input.stderr.expected"
else
stderr_expected="/dev/null"
fi
if [ -e "$input.exit_status.expected" ]; then
exit_status_expected="$input.exit_status.expected"
else
exit_status_expected=../exit_status_zero
fi
diff -u "$stderr_expected" "$stderr_observed"
diff -u "$stdout_expected" "$stdout_observed"
diff -u "$exit_status_expected" "$exit_status_observed"
Loading…
Cancel
Save