aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rwxr-xr-xtests/runner.py76
-rwxr-xr-xtests/socket_server.sh3
-rw-r--r--tests/websockets.c125
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;
+}
+