Skip to content

Commit 65695ea

Browse files
committed
Fix tests
1 parent fbce4b1 commit 65695ea

File tree

6 files changed

+108
-34
lines changed

6 files changed

+108
-34
lines changed

.github/workflows/build.yml

-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ jobs:
2424
python-version: '3.13'
2525
cache: 'pip'
2626

27-
- run: sudo apt install -y valgrind
28-
2927
- run: zig build
3028
- run: zig build unit-tests --summary all
3129

src/Index.zig

-2
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,6 @@ pub fn update(self: *Self, changes: []const Change) !void {
405405
}
406406

407407
pub fn updateInternal(self: *Self, changes: []const Change, commit_id: ?u64) !void {
408-
// log.debug("update with {} changes", .{changes.len});
409-
410408
var target = try MemorySegmentList.createSegment(self.allocator, .{});
411409
defer MemorySegmentList.destroySegment(self.allocator, &target);
412410

src/main.zig

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const std = @import("std");
2+
const log = std.log.scoped(.main);
23
const zul = @import("zul");
34

45
const MultiIndex = @import("MultiIndex.zig");
@@ -51,8 +52,12 @@ pub fn main() !void {
5152
}
5253
}
5354

54-
const dir_path = args.get("dir") orelse ".";
55+
const dir_path_relative = args.get("dir") orelse "/tmp/fpindex";
56+
const dir_path = try std.fs.cwd().realpathAlloc(allocator, dir_path_relative);
57+
defer allocator.free(dir_path);
58+
5559
const dir = try std.fs.cwd().makeOpenPath(dir_path, .{ .iterate = true });
60+
log.info("using directory {s}", .{dir_path});
5661

5762
const address = args.get("address") orelse "127.0.0.1";
5863

@@ -66,6 +71,7 @@ pub fn main() !void {
6671
if (threads == 0) {
6772
threads = @intCast(try std.Thread.getCpuCount());
6873
}
74+
log.info("using {} threads", .{threads});
6975

7076
try metrics.initializeMetrics(.{ .prefix = "aindex_" });
7177

src/server.zig

+14-6
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ pub fn run(allocator: std.mem.Allocator, indexes: *MultiIndex, address: []const
7272
var router = server.router();
7373

7474
// Monitoring API
75-
router.get("/_ping", handlePing);
7675
router.get("/_metrics", handleMetrics);
76+
router.get("/_ping", handlePing);
77+
router.get("/:index/_ping", handlePingIndex);
7778

7879
// Search API
7980
router.post("/:index/_search", handleSearch);
@@ -277,11 +278,6 @@ fn handleUpdate(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !void
277278
return writeResponse(EmptyResponse{}, req, res);
278279
}
279280

280-
fn handleHeadIndex(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !void {
281-
const index_ref = try getIndex(ctx, req, res, false) orelse return;
282-
defer releaseIndex(ctx, index_ref);
283-
}
284-
285281
const Attributes = struct {
286282
attributes: std.AutoHashMapUnmanaged(u64, u64),
287283

@@ -348,6 +344,18 @@ fn handleDeleteIndex(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !
348344
return writeResponse(EmptyResponse{}, req, res);
349345
}
350346

347+
fn handleHeadIndex(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !void {
348+
const index_ref = try getIndex(ctx, req, res, false) orelse return;
349+
defer releaseIndex(ctx, index_ref);
350+
}
351+
352+
fn handlePingIndex(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !void {
353+
const index_ref = try getIndex(ctx, req, res, false) orelse return;
354+
defer releaseIndex(ctx, index_ref);
355+
356+
try handlePing(ctx, req, res);
357+
}
358+
351359
fn handlePing(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !void {
352360
_ = ctx;
353361
_ = req;

tests/conftest.py

+34-23
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import pytest
33
import subprocess
44
import time
5-
import socket
65
from urllib.parse import urljoin
76

87

@@ -16,7 +15,6 @@ def __init__(self, base_dir, port):
1615

1716
def start(self):
1817
command = [
19-
'valgrind',
2018
'zig-out/bin/fpindex',
2119
'--dir', str(self.data_dir),
2220
'--port', str(self.port),
@@ -26,19 +24,44 @@ def start(self):
2624
command,
2725
stdin=subprocess.DEVNULL,
2826
stdout=subprocess.DEVNULL,
29-
stderr=self.log_file.open('w'),
27+
stderr=self.log_file.open('a'),
3028
)
29+
self.wait_for_ready()
3130

32-
def stop(self):
31+
def stop(self, kill=False):
3332
if self.process is not None:
3433
if self.process.returncode is None:
35-
self.process.terminate()
34+
if kill:
35+
self.process.kill()
36+
else:
37+
self.process.terminate()
3638
try:
3739
self.process.wait(timeout=1.0)
3840
except subprocess.TimeoutExpired:
3941
self.process.kill()
4042
self.process.wait()
4143

44+
def restart(self, kill=True):
45+
self.stop(kill=kill)
46+
self.start()
47+
48+
def wait_for_ready(self, index_name=None, timeout=10.0):
49+
deadline = time.time() + timeout
50+
while True:
51+
if index_name:
52+
url = f'http://localhost:{self.port}/{index_name}/_ping'
53+
else:
54+
url = f'http://localhost:{self.port}/_ping'
55+
try:
56+
with requests.get(url) as res:
57+
res.raise_for_status()
58+
except Exception:
59+
if time.time() > deadline:
60+
raise TimeoutError()
61+
time.sleep(timeout / 100.0)
62+
else:
63+
break
64+
4265
def error_log(self):
4366
for line in self.log_file.read_text().splitlines():
4467
yield line
@@ -48,10 +71,12 @@ def error_log(self):
4871
def server(tmp_path_factory):
4972
srv = ServerManager(base_dir=tmp_path_factory.mktemp('srv'), port=14502)
5073
srv.start()
51-
yield srv
52-
srv.stop()
53-
for line in srv.error_log():
54-
print(line)
74+
try:
75+
yield srv
76+
finally:
77+
srv.stop()
78+
for line in srv.error_log():
79+
print(line)
5580

5681

5782
index_no = 1
@@ -96,22 +121,8 @@ def session():
96121
yield session
97122

98123

99-
def check_port(port_no):
100-
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock:
101-
return sock.connect_ex(('127.0.0.1', port_no)) == 0
102-
103-
104-
def wait_for_ready(port, timeout):
105-
deadline = time.time() + timeout
106-
while not check_port(port):
107-
if time.time() > deadline:
108-
raise TimeoutError()
109-
time.sleep(timeout / 100.0)
110-
111-
112124
@pytest.fixture
113125
def client(session, server):
114-
wait_for_ready(server.port, 1)
115126
return Client(session, f'http://localhost:{server.port}')
116127

117128

tests/test_fingerprint_api.py

+53
Original file line numberDiff line numberDiff line change
@@ -124,3 +124,56 @@ def test_delete(client, index_name, create_index):
124124
assert json.loads(req.content) == {
125125
'results': []
126126
}
127+
128+
129+
def test_persistence_after_soft_restart(server, client, index_name, create_index):
130+
# insert fingerprint
131+
for i in range(100):
132+
body = {
133+
'changes': [
134+
{'insert': {'id': 1, 'hashes': [100+i, 200+i, 300+i]}}
135+
],
136+
}
137+
with client.post(f'/{index_name}/_update', json=body) as req:
138+
assert req.status_code == 200, req.content
139+
assert json.loads(req.content) == {}
140+
141+
server.restart()
142+
server.wait_for_ready(index_name, timeout=10.0)
143+
144+
# verify we can find it
145+
req = client.post(f'/{index_name}/_search', json={
146+
'query': [199, 299, 399]
147+
})
148+
assert req.status_code == 200, req.content
149+
assert json.loads(req.content) == {
150+
'results': [{'id': 1, 'score': 3}]
151+
}
152+
153+
154+
def test_persistence_after_hard_restart(server, client, index_name, create_index):
155+
# insert fingerprint
156+
for i in range(100):
157+
body = {
158+
'changes': [
159+
{'insert': {'id': 1, 'hashes': [100+i, 200+i, 300+i]}}
160+
],
161+
}
162+
with client.post(f'/{index_name}/_update', json=body) as req:
163+
assert req.status_code == 200, req.content
164+
assert json.loads(req.content) == {}
165+
assert req.status_code == 200, req.content
166+
assert json.loads(req.content) == {}
167+
168+
server.restart(kill=True)
169+
server.wait_for_ready(index_name, timeout=10.0)
170+
171+
# verify we can find it
172+
req = client.post(f'/{index_name}/_search', json={
173+
'query': [199, 299, 399]
174+
})
175+
assert req.status_code == 200, req.content
176+
assert json.loads(req.content) == {
177+
'results': [{'id': 1, 'score': 3}]
178+
}
179+

0 commit comments

Comments
 (0)