Skip to content

Commit de252c7

Browse files
committed
test: add benches for various syscalls
1 parent 46fb608 commit de252c7

File tree

1 file changed

+151
-0
lines changed

1 file changed

+151
-0
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import concurrent.futures
2+
import mmap
3+
import multiprocessing
4+
import os
5+
import socket
6+
from socket import gethostbyname
7+
from tempfile import NamedTemporaryFile
8+
from time import sleep
9+
10+
import pytest
11+
12+
13+
@pytest.mark.parametrize("sleep_time", [0.001, 0.01, 0.05, 0.1])
14+
def test_sleep(benchmark, sleep_time):
15+
benchmark(sleep, sleep_time)
16+
17+
18+
@pytest.mark.parametrize("array_size", [100, 1_000, 10_000, 100_000])
19+
def test_array_alloc(benchmark, array_size):
20+
benchmark(lambda: [0] * array_size)
21+
22+
23+
@pytest.mark.parametrize("num_fds", [10, 100, 1000])
24+
def test_open_close_fd(benchmark, num_fds):
25+
def open_close_fds():
26+
fds = [os.open("/dev/null", os.O_RDONLY) for _ in range(num_fds)]
27+
for fd in fds:
28+
os.close(fd)
29+
30+
benchmark(open_close_fds)
31+
32+
33+
def test_dup_fd(benchmark):
34+
def dup_fd():
35+
fd = os.open("/dev/null", os.O_RDONLY)
36+
new_fd = os.dup(fd)
37+
os.close(new_fd)
38+
os.close(fd)
39+
40+
benchmark(dup_fd)
41+
42+
43+
@pytest.mark.parametrize("content_length", [100, 1000, 10_000, 100_000, 1_000_000])
44+
def test_fs_write(benchmark, content_length):
45+
content = "a" * content_length
46+
f = NamedTemporaryFile(mode="w")
47+
48+
@benchmark
49+
def write_to_file():
50+
f.write(content)
51+
f.flush()
52+
53+
f.close()
54+
55+
56+
@pytest.mark.parametrize("content_length", [100, 1000, 10_000, 100_000, 1_000_000])
57+
def test_fs_read(benchmark, content_length):
58+
with open("/dev/urandom", "rb") as f:
59+
benchmark(f.read, content_length)
60+
61+
62+
@pytest.mark.parametrize(
63+
"host",
64+
["localhost", "127.0.0.1", "1.1.1.1", "8.8.8.8", "google.com", "amazon.com"],
65+
)
66+
def test_hostname_resolution(benchmark, host):
67+
benchmark(gethostbyname, host)
68+
69+
70+
@pytest.mark.parametrize(
71+
"host, port",
72+
[("8.8.8.8", 53), ("1.1.1.1", 53), ("google.com", 443), ("wikipedia.org", 443)],
73+
)
74+
def test_tcp_connection(benchmark, host, port):
75+
def connect():
76+
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
77+
try:
78+
sock.connect((host, port))
79+
finally:
80+
sock.close()
81+
82+
benchmark(connect)
83+
84+
85+
@pytest.mark.parametrize("command", ["echo hello", "ls -l", "cat /dev/null"])
86+
def test_process_creation(benchmark, command):
87+
def create_process():
88+
process = os.popen(command)
89+
process.read()
90+
process.close()
91+
92+
benchmark(create_process)
93+
94+
95+
@pytest.mark.parametrize("message_size", [10, 100, 1000, 10000])
96+
def test_pipe_communication(benchmark, message_size):
97+
def pipe_comm():
98+
r, w = os.pipe()
99+
pid = os.fork()
100+
if pid == 0: # child process
101+
os.close(r)
102+
os.write(w, b"x" * message_size)
103+
os._exit(0)
104+
else: # parent process
105+
os.close(w)
106+
os.read(r, message_size)
107+
os.waitpid(pid, 0)
108+
os.close(r)
109+
110+
benchmark(pipe_comm)
111+
112+
113+
@pytest.mark.parametrize("map_size", [4096, 40960, 409600])
114+
def test_mmap_operation(benchmark, map_size):
115+
# Create a temporary file outside the benchmarked function
116+
temp_file = NamedTemporaryFile(mode="w+b", delete=False)
117+
temp_file.write(b"\0" * map_size)
118+
temp_file.flush()
119+
temp_file.close()
120+
121+
mfd = os.open(temp_file.name, os.O_RDONLY)
122+
123+
def mmap_op():
124+
mm = mmap.mmap(mfd, map_size, access=mmap.ACCESS_READ)
125+
mm.read(map_size)
126+
127+
benchmark(mmap_op)
128+
os.close(mfd)
129+
130+
131+
def multi_task(x):
132+
"""Multiprocessing need this function to be defined at the top level."""
133+
return x * x
134+
135+
136+
@pytest.mark.parametrize("num_tasks", [10, 100, 1000, 10000, 100000])
137+
def test_threadpool_map(benchmark, num_tasks):
138+
def threadpool_map():
139+
with concurrent.futures.ThreadPoolExecutor(max_workers=8) as executor:
140+
list(executor.map(multi_task, range(num_tasks)))
141+
142+
benchmark(threadpool_map)
143+
144+
145+
@pytest.mark.parametrize("num_tasks", [10, 100, 1000, 10000, 100000])
146+
def test_multiprocessing_map(benchmark, num_tasks):
147+
def multiprocessing_map():
148+
with multiprocessing.Pool(processes=8) as pool:
149+
list(pool.map(multi_task, range(num_tasks)))
150+
151+
benchmark(multiprocessing_map)

0 commit comments

Comments
 (0)