diff options
Diffstat (limited to 'tests')
-rwxr-xr-x | tests/runner.py | 76 | ||||
-rwxr-xr-x | tests/socket_server.sh | 3 | ||||
-rw-r--r-- | tests/websockets.c | 125 |
3 files changed, 199 insertions, 5 deletions
diff --git a/tests/runner.py b/tests/runner.py index e5b2eada..94328ac8 100755 --- a/tests/runner.py +++ b/tests/runner.py @@ -7707,6 +7707,10 @@ fscanfed: 10 - hello elif 'browser' in str(sys.argv): # Browser tests. + print + print 'Running the browser tests. Make sure the browser allows popups from localhost.' + print + # Run a server and a web page. When a test runs, we tell the server about it, # which tells the web page, which then opens a window with the test. Doing # it this way then allows the page to close() itself when done. @@ -7798,7 +7802,7 @@ elif 'browser' in str(sys.argv): print '(moving on..)' def with_report_result(self, code): - return ''' + return r''' #define REPORT_RESULT_INTERNAL(sync) \ char output[1000]; \ sprintf(output, \ @@ -8626,6 +8630,52 @@ elif 'browser' in str(sys.argv): ''') self.btest('pre_run_deps.cpp', expected='10', args=['--pre-js', 'pre.js']) + class WebsockHarness: + def __enter__(self): + self.pids = [] + + def server_func(q): + proc = Popen([path_from_root('tests', 'socket_server.sh')]) + q.put(proc.pid) + proc.communicate() + + server_queue = multiprocessing.Queue() + self.server = multiprocessing.Process(target=server_func, args=(server_queue,)) + self.server.start() + self.pids.append(self.server.pid) + while True: + if not server_queue.empty(): + self.pids.append(server_queue.get()) + break + time.sleep(0.1) + print '[Socket server on processes %s]' % str(self.pids[-2:]) + + def websockify_func(q): + proc = Popen([path_from_root('third_party', 'websockify', 'other', 'websockify'), '-vvv', '8991', '127.0.0.1:8990']) + q.put(proc.pid) + proc.communicate() + + websockify_queue = multiprocessing.Queue() + self.websockify = multiprocessing.Process(target=websockify_func, args=(websockify_queue,)) + self.websockify.start() + self.pids.append(self.websockify.pid) + while True: + if not websockify_queue.empty(): + self.pids.append(websockify_queue.get()) + break + time.sleep(0.1) + print '[Websockify on processes %s]' % str(self.pids[-2:]) + + def __exit__(self, *args, **kwargs): + import signal + for pid in self.pids: + #os.kill(pid, signal.SIGTERM) # With this commented, we leave no children, but we hang the test harness on exit XXX + print '[%d should be cleaned up automatically]' % pid + + def test_websockets(self): + with self.WebsockHarness(): + self.btest('websockets.c', expected='571') + elif 'benchmark' in str(sys.argv): # Benchmarks. Run them with argument |benchmark|. To run a specific test, do # |benchmark.test_X|. @@ -9007,11 +9057,27 @@ elif 'sanity' in str(sys.argv): self.assertContained('Welcome to Emscripten!', output) self.assertContained('This is the first time any of the Emscripten tools has been run.', output) self.assertContained('A settings file has been copied to %s, at absolute path: %s' % (EM_CONFIG, CONFIG_FILE), output) - self.assertContained('Please edit that file and change the paths to fit your system', output) - self.assertContained('make sure LLVM_ROOT and NODE_JS are correct', output) + self.assertContained('It contains our best guesses for the important paths, which are:', output) + self.assertContained('LLVM_ROOT', output) + self.assertContained('NODE_JS', output) + self.assertContained('Please edit the file if any of those are incorrect', output) self.assertContained('This command will now exit. When you are done editing those paths, re-run it.', output) assert output.split()[-1].endswith('===='), 'We should have stopped: ' + output - assert (open(CONFIG_FILE).read() == open(path_from_root('tools', 'settings_template_readonly.py')).read()), 'Settings should be copied from tools/settings_template_readonly.py' + config_file = open(CONFIG_FILE).read() + template_file = open(path_from_root('tools', 'settings_template_readonly.py')).read() + self.assertNotContained('~/.emscripten', config_file) + self.assertContained('~/.emscripten', template_file) + self.assertNotContained('{{{', config_file) + self.assertNotContained('}}}', config_file) + self.assertContained('{{{', template_file) + self.assertContained('}}}', template_file) + for content in ['EMSCRIPTEN_ROOT', 'LLVM_ROOT', 'NODE_JS', 'TEMP_DIR', 'COMPILER_ENGINE', 'JS_ENGINES']: + self.assertContained(content, config_file) + + # The guessed config should be ok XXX This depends on your local system! it is possible `which` guesses wrong + try_delete('a.out.js') + output = Popen(['python', EMCC, path_from_root('tests', 'hello_world.c')], stdout=PIPE, stderr=PIPE).communicate() + self.assertContained('hello, world!', run_js('a.out.js'), output) # Second run, with bad EM_CONFIG for settings in ['blah', 'LLVM_ROOT="blarg"; JS_ENGINES=[]; COMPILER_ENGINE=NODE_JS=SPIDERMONKEY_ENGINE=[]']: @@ -9059,7 +9125,7 @@ elif 'sanity' in str(sys.argv): restore() # Clang should report the version number we expect, and emcc should not warn - assert ('clang version ' + '.'.join(map(str, EXPECTED_LLVM_VERSION))) in Popen([CLANG, '-v'], stderr=PIPE).communicate()[1] + assert check_clang_version() output = self.check_working(EMCC) assert LLVM_WARNING not in output, output diff --git a/tests/socket_server.sh b/tests/socket_server.sh new file mode 100755 index 00000000..a8a3aa50 --- /dev/null +++ b/tests/socket_server.sh @@ -0,0 +1,3 @@ +#!/bin/sh +while true; do (/bin/echo -en "te\x01\xff\x79st\x02") | nc -vvvl 127.0.0.1 8990; done; + diff --git a/tests/websockets.c b/tests/websockets.c new file mode 100644 index 00000000..6e81eb47 --- /dev/null +++ b/tests/websockets.c @@ -0,0 +1,125 @@ +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#if EMSCRIPTEN +#include <emscripten.h> +#endif + +#define EXPECTED_BYTES 5 + +int SocketFD; + +unsigned int get_all_buf(int sock, char* output, unsigned int maxsize) +{ + int bytes; + if (ioctl(sock, FIONREAD, &bytes)) return 0; + if (bytes == 0) return 0; + + char buffer[1024]; + int n; + unsigned int offset = 0; + while((errno = 0, (n = recv(sock, buffer, sizeof(buffer), 0))>0) || + errno == EINTR) { + if(n>0) + { + if (((unsigned int) n)+offset > maxsize) { fprintf(stderr, "too much data!"); exit(EXIT_FAILURE); } + memcpy(output+offset, buffer, n); + offset += n; + } + } + + if(n < 0) { + fprintf(stderr, "error in get_all_buf!"); + exit(EXIT_FAILURE); + } + return offset; +} + +int done = 0; + +void iter(void *arg) { + /* perform read write operations ... */ + static char out[1024*2]; + static int pos = 0; + int n = get_all_buf(SocketFD, out+pos, 1024-pos); + if (n) printf("read! %d\n", n); + pos += n; + if (pos >= EXPECTED_BYTES) { + int i, sum = 0; + for (i=0; i < pos; i++) { + printf("%x\n", out[i]); + sum += out[i]; + } + + shutdown(SocketFD, SHUT_RDWR); + + close(SocketFD); + + done = 1; + + printf("sum: %d\n", sum); + +#if EMSCRIPTEN + int result = sum; + REPORT_RESULT(); +#endif + } +} + +int main(void) +{ + struct sockaddr_in stSockAddr; + int Res; + SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); + + if (-1 == SocketFD) + { + perror("cannot create socket"); + exit(EXIT_FAILURE); + } + + memset(&stSockAddr, 0, sizeof(stSockAddr)); + + stSockAddr.sin_family = AF_INET; + stSockAddr.sin_port = htons( +#if EMSCRIPTEN + 8991 +#else + 8990 +#endif + ); + Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr); + + if (0 > Res) { + perror("error: first parameter is not a valid address family"); + close(SocketFD); + exit(EXIT_FAILURE); + } else if (0 == Res) { + perror("char string (second parameter does not contain valid ipaddress)"); + close(SocketFD); + exit(EXIT_FAILURE); + } + + if (-1 == connect(SocketFD, (struct sockaddr *)&stSockAddr, sizeof(stSockAddr))) { + perror("connect failed"); + close(SocketFD); + exit(EXIT_FAILURE); + + } + +#if EMSCRIPTEN + emscripten_set_main_loop(iter, 0); +#else + while (!done) iter(NULL); +#endif + + return EXIT_SUCCESS; +} + |