-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathintegration_test.py
295 lines (212 loc) · 9.11 KB
/
integration_test.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
import subprocess
import threading
import time
import asyncio
NR_CLIENTS = 10
PORT = 4040
TEST_MESSAGE = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed varius metus ut nisl varius tempus. Nullam at cursus nisl. Etiam sit amet neque sem. Quisque ipsum arcu, mollis non leo eu, varius eleifend elit. Morbi quis pretium massa. Curabitur posuere ex enim, eget tincidunt mi commodo nec. Cras non ornare diam. Pellentesque lobortis est augue, ut tincidunt tortor aliquam id. Suspendisse libero ante, sollicitudin id aliquam quis, placerat vel nisl. Vivamus suscipit feugiat pellentesque. Cras rutrum orci non facilisis ultrices."
errors = 0
server = None
clients = [None] * NR_CLIENTS
class bcolors:
ERROR = '\033[91m' # Red
OKGREEN = '\033[92m' # Green
WARNING = '\033[93m' # Yellow
SERVER = '\033[94m' # Blue
NOTICE = '\033[95m' # Purple
CLIENT = '\033[96m' # Cyan
TIME = '\033[90m' # Grey
ENDC = '\033[0m'
class ElixirProcess:
def __init__(self, name, command):
self.name = name
self.process = subprocess.Popen(
command,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True,
bufsize=1, # Line-buffered
shell=True
)
# Start a background thread to stream output in real-time
self.output_thread = threading.Thread(target=self.stream_output)
self.output_thread.daemon = True
self.output_thread.start()
def stream_output(self):
"""Continuously read and print output from the Elixir process."""
if self.process.stdout:
for line in iter(self.process.stdout.readline, ""):
line = line.strip()
if line == "" or "iex" in line or "Elixir" in line or "Erlang" in line:
continue
line_split = line.split(" ")
if len(line_split) < 3:
print(f"{color}[{self.name}]{bcolors.ENDC} {line}")
continue
if "Error" in line or "error" in line:
global errors
errors += 1
color = bcolors.CLIENT
if "Server" in self.name:
color = bcolors.SERVER
time = line_split[0]
if time.count(":") != 2:
print(f"{color}[{self.name}]{bcolors.ENDC} {line}")
continue
level = line_split[3]
line = " ".join(line_split[4:])
metadata = " ".join(line_split[1:3])
level_color = bcolors.ERROR
if level == "[info]":
level_color = bcolors.OKGREEN
elif level == "[notice]":
level_color = bcolors.NOTICE
elif level == "[warning]":
level_color = bcolors.WARNING
print(f"{color}[{self.name}]{bcolors.ENDC} {bcolors.TIME}{time}{bcolors.ENDC} {metadata} {level_color}{level}{bcolors.ENDC} {line}")
self.process.stdout.close()
def send_input(self, input_data):
"""Send data to the Elixir process."""
if self.process.stdin:
self.process.stdin.write(input_data + '\n')
self.process.stdin.flush()
def stop(self):
"""Terminate the Elixir process."""
self.process.stdin.close()
self.process.terminate()
self.process.wait()
class Client:
def __init__(self, id):
self.id = id
self.name = f"Client {id}"
self.process = ElixirProcess(self.name, f"cd ./client && PORT={PORT} iex -S mix run --no-halt")
self.user_id = f"user{id}"
user_password = f"password{id}"
def login(self):
# token = Client.Account.login(user_id, user_password)
self.process.send_input(f"token = Client.Account.login(\"{self.user_id}\", \"password\")")
def signup(self):
# token = Client.Account.signup(user_id, user_password)
self.process.send_input(f"token = Client.Account.signup(\"{self.user_id}\", \"password\")")
def logout(self):
# token = Client.Account.logout()
self.process.send_input(f"Client.Account.logout()")
def add_contact(self, user_id):
if user_id == self.user_id:
return
# contact_uuid = Client.Contact.add_contact(user_uuid, user_id)
self.process.send_input(f"Client.Contact.add_contact(:crypto.hash(:md4, \"{user_id}\"))")
def send_message(self, user_id):
if user_id == self.user_id:
return
# Client.Message.send("Hello World! 1", contact_uuid)
self.process.send_input(f"Client.Message.send(\"{TEST_MESSAGE}\", :crypto.hash(:md4, \"{user_id}\"))")
def stop(self):
self.process.stop()
def create_server_and_clients():
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Starting server...")
global server
server = ElixirProcess(" Server ", f"cd ./server && PORT={PORT} iex -S mix run --no-halt")
time.sleep(1)
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Starting clients...")
for i in range(NR_CLIENTS):
clients[i] = Client(i)
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Logging in...")
for i in range(NR_CLIENTS):
# clients[i].login()
clients[i].signup()
input("")
def destroy_server_and_clients():
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Stopping...")
for i in range(NR_CLIENTS):
clients[i].stop()
server.stop()
time.sleep(1)
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Done!")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Errors: {errors}")
def run_elixir_test_1():
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Adding contacts...")
for i in range(NR_CLIENTS):
for j in range(NR_CLIENTS):
clients[i].add_contact(f"user{j}")
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Sending messages...")
for i in range(NR_CLIENTS):
for j in range(NR_CLIENTS):
clients[j].send_message(f"user{i}")
time.sleep(0.5)
def run_elixir_test_2():
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Adding contacts...")
i = 0
for j in range(NR_CLIENTS):
clients[j].add_contact(f"user{i}")
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Sending messages...")
for j in range(NR_CLIENTS):
clients[j].send_message(f"user{i}")
def run_elixir_test_3():
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Adding contacts...")
i = 0
for j in range(NR_CLIENTS):
clients[i].add_contact(f"user{j}")
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Stopping clients who are not sending messages...")
for j in range(1, NR_CLIENTS):
clients[j].stop()
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Sending messages...")
for j in range(NR_CLIENTS):
clients[i].send_message(f"user{j}")
def run_elixir_test_4():
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Logging out clients who are not sending messages...")
for j in range(1, NR_CLIENTS):
if j % 2 == 1:
clients[j].logout()
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Adding contacts...")
# Logged in clients are i % 2 == 0 and logged out clients are j % 2 == 1
for j in range(NR_CLIENTS):
for i in range(NR_CLIENTS):
if j % 2 == 1 and i % 2 == 0:
clients[i].add_contact(f"user{j}")
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Sending messages to clients logged out...")
# Logged in clients are i % 2 == 0 and logged out clients are j % 2 == 1
for j in range(NR_CLIENTS):
for i in range(1, NR_CLIENTS):
if j % 2 == 1 and i % 2 == 0:
clients[i].send_message(f"user{j}")
clients[i].send_message(f"user{j}")
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Logging clients back in...")
for j in range(1, NR_CLIENTS):
if j % 2 == 1:
clients[j].login()
input("")
print(f"{bcolors.OKGREEN}[Process ]{bcolors.ENDC} Sending messages to clients logged in...")
# Logged in clients are i % 2 == 0 and logged out clients are j % 2 == 1
for j in range(NR_CLIENTS):
for i in range(1, NR_CLIENTS):
if j % 2 == 1 and i % 2 == 0:
clients[j].send_message(f"user{i}")
clients[j].send_message(f"user{i}")
# cd server && mix ecto.drop && mix ecto.create && mix ecto.migrate && cd .. && python3 ./integration_test.py
if __name__ == "__main__":
# create_server_and_clients()
# run_elixir_test_1()
# destroy_server_and_clients()
# input("")
# create_server_and_clients()
# run_elixir_test_2()
# destroy_server_and_clients()
# input("")
# create_server_and_clients()
# run_elixir_test_3()
# destroy_server_and_clients()
# input("")
create_server_and_clients()
run_elixir_test_4()
destroy_server_and_clients()