-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathe2e.py
executable file
·133 lines (97 loc) · 3.91 KB
/
e2e.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python3
import os
import platform
import random
import shlex
import signal
import subprocess
import time
def FAIL(msg: str):
print("### TEST FAILED ###")
raise AssertionError(msg)
class Process:
def __init__(self, cmd: str):
self._cmd = cmd
self._popen = subprocess.Popen(
args=shlex.split(self._cmd),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
bufsize=0
)
self._buf: bytes = b""
def write_stdin(self, data: str):
self._popen.stdin.write(data.encode())
def write_line(self, data: str):
self.write_stdin(data + "\n")
def check_output(self, data: str, clear=True, chunk_sz=4096, read_count=1):
# print(self._buf.decode())
if data.encode() not in self._buf:
for _ in range(read_count):
self._buf += self._popen.stdout.read(chunk_sz)
if data.encode() not in self._buf:
FAIL(f"not in output: '{data}'\nfull buffer:\n{self._buf.decode()}")
if clear:
self._buf = b""
def check_not_in_output(self, data: str, clear=True, chunk_sz=4096, read_count=1):
# print(self._buf.decode())
if data.encode() not in self._buf:
for _ in range(read_count):
self._buf += self._popen.stdout.read(chunk_sz)
if data.encode() in self._buf:
FAIL(f"in output: '{data}'\nfull buffer:\n{self._buf.decode()}")
else:
FAIL(f"in output: '{data}'\nfull buffer:\n{self._buf.decode()}")
if clear:
self._buf = b""
def __repr__(self) -> str:
return f"<Process {self._cmd}>"
def __del__(self):
self._popen.terminate()
def sigalrm_handler(*_):
raise AssertionError("### TEST TIMEOUT, output was probably messy and blocked ###")
def main():
if os.path.realpath(".").endswith("tests"):
FAIL("please run e2e.py from the implant.js repo root: ./tests/e2e.py")
if platform.system() != "Linux":
FAIL("unsupported operating system, please run the e2e suite on linux")
timeout = 15
print(f"### RUNNING E2E TEST SUITE, TIMEOUT IS {timeout} SECONDS ###")
signal.signal(signal.SIGALRM, sigalrm_handler)
signal.alarm(timeout)
port = str(random.randint(30000,50000))
server = Process(f"python -u ./server/server.py -p {port}")
server.check_output(f"server listening on port ")
client = Process(f"./client/build/client localhost {port}")
client.check_output("successfully connected to localhost:")
time.sleep(1)
server.check_output("new connection from 127.0.0.1:", clear=False)
server.check_output("client is running Linux")
server.write_line("lsmod")
server.check_output("available modules:", clear=False)
server.check_output("- tests/e2e", clear=False)
server.check_output("- tests/lib")
server.write_line("run tests/e2e")
server.check_output("running module tests/e2e", clear=False, read_count=2)
time.sleep(2)
client.check_output("executing js module", clear=False)
client.check_output("this is a successful output!")
server.check_output("output from the client", clear=False)
server.check_output("this is a successful output!")
server.write_line("run tests/lib")
server.check_output("running module tests/lib", clear=False, read_count=2)
time.sleep(2)
client.check_output("executing js module", clear=False)
client.check_output("tron >> tr3n", clear=False)
server.check_output("output from the client", clear=False)
server.check_output("tron >> tr3n")
client.check_not_in_output("module threw an exception", read_count=0)
# try to gracefully clean stuff up
server.write_line("dc")
server.write_line("exit")
time.sleep(1)
del client
del server
print("### E2E TEST SUCCESSFULLY PASSED ###")
if __name__ == "__main__":
main()