Skip to content

Commit fb53cc5

Browse files
committed
tests: update tests to work with ph1024
1 parent c20eada commit fb53cc5

File tree

7 files changed

+198
-183
lines changed

7 files changed

+198
-183
lines changed

snapshot.c

Lines changed: 0 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -361,59 +361,3 @@ void write_32x32_to_uds(DATA_PRODUCT dp, PACKET_HEADER *header, uint8_t *data) {
361361
hashpipe_error(__FUNCTION__, "Failed to sprint Img snapshot JSON for UDS");
362362
}
363363
}
364-
365-
// =====================================================================
366-
// Filesystem snapshot functions (originally from net_thread.c)
367-
// =====================================================================
368-
369-
370-
// // Writes a single-packet pulse-height snapshot to a file.
371-
// void WritePHSnapshots(FILE *fp, PACKET_HEADER *header, uint8_t *data) {
372-
// char json_buffer[1024];
373-
374-
// // Create the JSON header in memory using the unified function
375-
// if (sprint_ph_snapshot_json(json_buffer, sizeof(json_buffer), header) <= 0) {
376-
// hashpipe_error(__FUNCTION__, "Failed to sprint PH snapshot JSON for filesystem");
377-
// return;
378-
// }
379-
380-
// // Write the PFF frame to the file
381-
// // move the pointer to the beginning,
382-
// // as we only need one pkt in the snapshot file.
383-
// fseek(fp, 0, SEEK_SET);
384-
// pff_start_json(fp);
385-
// fputs(json_buffer, fp); // Write the generated JSON string
386-
// pff_end_json(fp);
387-
// pff_write_image(fp, PIXELS_PER_IMAGE * 2, data);
388-
// fflush(fp);
389-
// if (ftruncate(fileno(fp), ftell(fp)) < 0) {
390-
// hashpipe_error(__FUNCTION__, "Failed to truncate PH snapshot file");
391-
// }
392-
// fsync(fileno(fp));
393-
// }
394-
395-
396-
// // write data into img snapshot file
397-
// void WriteImgSnapshots(FILE *fp, PACKET_HEADER *header, uint8_t *data) {
398-
// char json_buffer[4096];
399-
400-
// // Create the JSON header in memory using the unified function
401-
// if (sprint_img_snapshot_json(json_buffer, sizeof(json_buffer), header) <= 0) {
402-
// hashpipe_error(__FUNCTION__, "Failed to sprint Img snapshot JSON for filesystem");
403-
// return;
404-
// }
405-
406-
// // Write the PFF frame to the file
407-
// // move the pointer to the beginning,
408-
// // as we only need one pkt in the snapshot file.
409-
// fseek(fp, 0, SEEK_SET);
410-
// pff_start_json(fp);
411-
// fputs(json_buffer, fp); // Write the generated JSON string
412-
// pff_end_json(fp);
413-
// pff_write_image(fp, BYTES_PER_MODULE_FRAME, data);
414-
// fflush(fp);
415-
// if (ftruncate(fileno(fp), ftell(fp)) < 0) {
416-
// hashpipe_error(__FUNCTION__, "Failed to truncate Img snapshot file");
417-
// }
418-
// fsync(fileno(fp));
419-
// }

snapshot.h

Lines changed: 45 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -130,57 +130,56 @@ struct module_snapshot_buffer {
130130
}
131131

132132
void update_snapshot(PACKET_HEADER *header, uint8_t *data, struct timeval *nowTime, int snapshot_interval_ms, int group_ph_frames) {
133-
char acq_mode = header->acq_mode;
134-
int quabo_num = header->quabo_num;
135-
DATA_PRODUCT dp = acq_mode_to_dp(acq_mode, group_ph_frames);
136-
snapshot_t *s = this->get_snapshot(dp);
137-
138-
// If timestamp difference exceeds snapshot interval, write snapshot to the unix-domain socket for this data product
139-
bool write_snapshot = false;
140-
uint64_t tdiff = timeval_diff(&s->last_update_time, nowTime);
141-
if ((tdiff > snapshot_interval_ms * 1000))
142-
{
143-
write_snapshot = true;
133+
char acq_mode = header->acq_mode;
134+
int quabo_num = header->quabo_num;
135+
DATA_PRODUCT dp = acq_mode_to_dp(acq_mode, group_ph_frames);
136+
snapshot_t *s = this->get_snapshot(dp);
137+
if (!s) return; // Snapshot for this data product not found
138+
139+
bool write_snapshot = false;
140+
uint64_t tdiff = timeval_diff(&s->last_update_time, nowTime);
141+
if (tdiff > snapshot_interval_ms * 1000) {
142+
write_snapshot = true;
143+
}
144+
145+
bool is_single_quabo = (dp == DP_PH_256_IMG);
146+
bool is_complete = false;
147+
148+
if (is_single_quabo) {
149+
quabo16_to_quabo16_copy(data, quabo_num, s->data);
150+
memcpy(&s->headers[0], header, sizeof(PACKET_HEADER));
151+
is_complete = true;
152+
} else {
153+
s->quabo_bitmap |= 1 << quabo_num;
154+
memcpy(&s->headers[quabo_num], header, sizeof(PACKET_HEADER));
155+
156+
if (bytes_per_pixel(dp) == 1) {
157+
quabo8_to_module8_copy(data, quabo_num, s->data);
158+
} else if (bytes_per_pixel(dp) == 2) {
159+
quabo16_to_module16_copy(data, quabo_num, s->data);
144160
}
145161

146-
if (dp == DP_PH_256_IMG) {
147-
// For PH 256 images, use only the 0th index of the header and data buffers.
148-
s->quabo_bitmap = 0x01; // Only one quabo for PH 256
149-
// memcpy(&s->headers[0], header, sizeof(PACKET_HEADER));
150-
quabo16_to_quabo16_copy(data, quabo_num, s->data);
151-
152-
if (write_snapshot) {
153-
write_16x16_to_uds(dp, header, s->data);
154-
// memset(s->headers, 0, sizeof(s->headers));
155-
s->last_update_time.tv_sec = nowTime->tv_sec;
156-
s->last_update_time.tv_usec = nowTime->tv_usec;
157-
}
158-
memset(s->data, 0, sizeof(s->data));
162+
if (s->quabo_bitmap == 0xf) {
163+
is_complete = true;
164+
}
165+
}
166+
167+
if (is_complete && write_snapshot) {
168+
if (is_single_quabo) {
169+
write_16x16_to_uds(dp, &s->headers[0], s->data);
159170
} else {
160-
// Require 4 quabo images
161-
s->quabo_bitmap |= 1 << quabo_num;
162-
memcpy(&s->headers[quabo_num], header, sizeof(PACKET_HEADER));
163-
164-
if (bytes_per_pixel(dp) == 1) {
165-
quabo8_to_module8_copy(data, quabo_num, s->data);
166-
} else if (bytes_per_pixel(dp) == 2) {
167-
quabo16_to_module16_copy(data, quabo_num, s->data);
168-
} else {
169-
fprintf(stderr, "Unsupported data product for snapshot: %d\n", dp);
170-
return; // Unsupported data product
171-
}
172-
if (s->quabo_bitmap == 0xf) {
173-
if (write_snapshot) {
174-
write_16x16_to_uds(dp, s->headers, s->data);
175-
s->last_update_time.tv_sec = nowTime->tv_sec;
176-
s->last_update_time.tv_usec = nowTime->tv_usec;
177-
}
178-
memset(s->headers, 0, sizeof(s->headers));
179-
memset(s->data, 0, sizeof(s->data));
180-
s->quabo_bitmap = 0;
181-
}
171+
write_32x32_to_uds(dp, s->headers, s->data);
182172
}
173+
174+
// Reset for next snapshot
175+
s->last_update_time.tv_sec = nowTime->tv_sec;
176+
s->last_update_time.tv_usec = nowTime->tv_usec;
177+
memset(s->headers, 0, sizeof(s->headers));
178+
memset(s->data, 0, sizeof(s->data));
179+
s->quabo_bitmap = 0;
183180
}
181+
}
182+
184183

185184

186185
~module_snapshot_buffer() {

tests/ci_tests/conftest.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def is_utility_available(name):
2020
MODULE_IDS = [1, 254]
2121
PCAP_FILE = "/app/test_data.pcapng"
2222
UDS_TEMPLATE = "/tmp/hashpipe_grpc.dp_{dp_name}.sock"
23+
GROUP_PH_FRAMES = 1 # Default to not grouping frames
2324

2425
def _ensure_dirs_and_module_config():
2526
cfg_str = ""
@@ -169,6 +170,7 @@ def daq_env():
169170
"--run_dir", str(BASE_DIR),
170171
"--max_file_size_mb", "5",
171172
"--bindhost", "lo",
173+
"--group_ph_frames", str(GROUP_PH_FRAMES)
172174
]
173175
for mid in MODULE_IDS:
174176
start_daq.extend(["--module_id", str(mid)])
@@ -190,6 +192,8 @@ def daq_env():
190192
"base_dir": BASE_DIR,
191193
"run_name": RUN_NAME,
192194
"module_ids": MODULE_IDS,
195+
"group_ph_frames": GROUP_PH_FRAMES,
196+
"ph_dp": "ph256" if GROUP_PH_FRAMES == 0 else "ph1024",
193197
"uds_paths": uds_paths,
194198
"uds_manager": uds_mgr,
195199
"tcpreplay_proc": tcpreplay_proc,

tests/ci_tests/start_daq.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ def _parse_args(argv):
1212
module_ids = []
1313
bindhost = "0.0.0.0"
1414
obs = "TEST"
15+
group_ph_frames = 0
1516
i = 1
1617
while i < len(argv):
1718
a = argv[i]
@@ -25,12 +26,14 @@ def _parse_args(argv):
2526
i += 1; bindhost = argv[i]
2627
elif a == "--obs":
2728
i += 1; obs = argv[i]
29+
elif a == "--group_ph_frames":
30+
i += 1; group_ph_frames = int(argv[i])
2831
else:
2932
raise SystemExit(f"Unknown arg {a}\n{USAGE}")
3033
i += 1
3134
if not run_dir or not module_ids:
3235
raise SystemExit(f"Missing required args\n{USAGE}")
33-
return run_dir, max_file_size_mb, bindhost, obs, module_ids
36+
return run_dir, max_file_size_mb, bindhost, group_ph_frames, obs, module_ids
3437

3538
def _write_module_config(run_dir, run_name, module_ids):
3639
cfg_dir = os.path.join(run_dir, run_name)
@@ -40,7 +43,7 @@ def _write_module_config(run_dir, run_name, module_ids):
4043
f.write("".join(f"{m}\n" for m in module_ids))
4144
return cfg_path
4245

43-
def _write_run_script(run_dir, run_name, bindhost, max_file_size_mb, obs):
46+
def _write_run_script(run_dir, run_name, bindhost, max_file_size_mb, group_ph_frames, obs):
4447
# Hashpipe runs with cwd = run_dir (parent), RUNDIR is run_name
4548
script_path = os.path.join(run_dir, "run_hashpipe.sh")
4649
cfg_rel = f"{run_name}/module.config"
@@ -53,7 +56,7 @@ def _write_run_script(run_dir, run_name, bindhost, max_file_size_mb, obs):
5356
f'-o RUNDIR={run_name} '
5457
f'-o CONFIG={cfg_rel} '
5558
f'-o MAXFILESIZE={max_file_size_mb} '
56-
f'-o GROUPPHFRAMES=0 '
59+
f'-o GROUPPHFRAMES={group_ph_frames} '
5760
f'-o OBS={obs} '
5861
f'net_thread compute_thread output_thread'
5962
]
@@ -79,7 +82,7 @@ def _find_hashpipe_pid(expected_tokens, retries=30, delay=0.5):
7982
return None
8083

8184
def main():
82-
run_dir, max_file_size_mb, bindhost, obs, module_ids = _parse_args(sys.argv)
85+
run_dir, max_file_size_mb, bindhost, group_ph_frames, obs, module_ids = _parse_args(sys.argv)
8386
# The tests set cwd to run_dir’s parent (/tmp/ci_run_dir). We ensure directories exist.
8487
os.makedirs(run_dir, exist_ok=True)
8588

@@ -89,7 +92,7 @@ def main():
8992
os.makedirs(os.path.join(run_dir, f"module_{mid}", run_name), exist_ok=True)
9093

9194
cfg_path = _write_module_config(run_dir, run_name, module_ids)
92-
script_path = _write_run_script(run_dir, run_name, bindhost, max_file_size_mb, obs)
95+
script_path = _write_run_script(run_dir, run_name, bindhost, max_file_size_mb, group_ph_frames, obs)
9396

9497
# Launch the wrapper script detached from stdio
9598
proc = subprocess.Popen(

tests/ci_tests/test_can_hashpipe_init.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,13 +63,14 @@ def test_filesystem_outputs_progress(daq_env):
6363
assert progressed, "Expected at least one module to have updated PFF outputs."
6464

6565
@pytest.mark.usefixtures("daq_env")
66-
def test_uds_ph256_frames(daq_env):
66+
def test_uds_ph_frames(daq_env):
6767
"""
68-
The tests act as the UDS SERVER. Verify that the ph256 server accepted a connection
68+
The tests act as the UDS SERVER. Verify that the ph256 or ph1024 server accepted a connection
6969
and received at least one frame from hashpipe within a reasonable time.
7070
"""
7171
uds_mgr = daq_env["uds_manager"]
72-
srv = uds_mgr.servers["ph256"]
72+
ph_dp = daq_env["ph_dp"]
73+
srv = uds_mgr.servers[ph_dp]
7374

7475
# Wait up to 10s for a client connection (hashpipe)
7576
start = time.time()
@@ -79,13 +80,13 @@ def test_uds_ph256_frames(daq_env):
7980
connected = True
8081
break
8182
time.sleep(0.2)
82-
assert connected, "ph256 UDS server did not receive a connection from hashpipe within 10s"
83+
assert connected, f"{ph_dp} UDS server did not receive a connection from hashpipe within 10s"
8384

8485
# Wait a bit for at least one frame
8586
start = time.time()
8687
while time.time() - start < 10 and srv.frames_received == 0:
8788
time.sleep(0.2)
88-
assert srv.frames_received > 0, "ph256 UDS server did not receive any frames within 10s"
89+
assert srv.frames_received > 0, f"{ph_dp} UDS server did not receive any frames within 10s"
8990

9091
# @pytest.mark.usefixtures("daq_env")
9192
# def test_uds_img16_frames(daq_env):

0 commit comments

Comments
 (0)