forked from parallaxsecond/parsec-mock
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparsec-mock.py
94 lines (72 loc) · 2.94 KB
/
parsec-mock.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
# Copyright 2021 Contributors to the Parsec project.
# SPDX-License-Identifier: Apache-2.0
import click
import socket
import os
from os import listdir
from os.path import isfile, join
import base64
from yaml import safe_load
@click.command()
@click.option('--test-folder', default='./testdata', help='Load all tests from folder')
@click.option('--parsec-socket', default='./parsec.sock', help='Path to parsec unix socket')
def run_test(test_folder, parsec_socket):
print('Mock parsec service listening on unix://{}.'.format(parsec_socket))
test_cases = load_tests_from_folder(test_folder)
print('Serving all {} tests in folder {}'.format(len(test_cases),test_folder))
# Make sure socket doesn't already exist
try:
os.unlink(parsec_socket)
except OSError:
if os.path.exists(parsec_socket):
print('Error removing old parsec socket, exiting')
return
# Create a unix socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(parsec_socket)
sock.listen(1)
while True:
connection, client_addr = sock.accept()
try:
print('Connection received from {}'.format(client_addr))
received_data = connection.recv(4096)
b64_received_data = base64.b64encode(received_data).decode('ascii')
if b64_received_data in test_cases:
test_case = test_cases[b64_received_data]
print('Received expected request for test case {}'.format(test_case.spec.name))
bin_response = base64.b64decode(test_case.test_data.response)
connection.sendall(bin_response)
else:
print('Received unexpected request {}'.format(b64_received_data))
finally:
connection.close()
class TestSpec(object):
"""Class to represent a test specification. Used to convert
dictionary created by pyaml to object format, making code easier to read."""
def __init__(self, dictionary):
def _traverse(key, element):
if isinstance(element, dict):
return key, TestSpec(element)
else:
return key, element
objd = dict(_traverse(k, v) for k, v in dictionary.items())
self.__dict__.update(objd)
self.basedict = dictionary
def is_valid(self):
return True
def load_tests_from_folder(test_folder):
tests = {}
"""Read test specs from a folder"""
specfiles = [f for f in listdir(test_folder) if isfile(join(test_folder, f))]
for file in specfiles:
print(f"Parsing spec file: {file}")
with open(os.path.join(test_folder, file), 'r') as f:
spec = safe_load(f)
testspec = TestSpec(spec)
if testspec.is_valid():
tests[testspec.test_data.request] = testspec
else:
print(f"Error loading test spec from {file}")
return tests
if __name__ == "__main__":
run_test()