Skip to content

Commit 6471808

Browse files
committed
Add roundtrip test for binsparse_read and binsparse_write.
1 parent 7493bd6 commit 6471808

1 file changed

Lines changed: 144 additions & 0 deletions

File tree

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
% SPDX-FileCopyrightText: 2024 Binsparse Developers
2+
%
3+
% SPDX-License-Identifier: BSD-3-Clause
4+
5+
function test_binsparse_roundtrip_dir(root_dir)
6+
% TEST_BINSPARSE_ROUNDTRIP_DIR - Round-trip binsparse files in a directory.
7+
%
8+
% This function scans a directory (recursively) for .h5 files, reads each
9+
% with binsparse_read, writes to a temporary file with binsparse_write, then
10+
% reads back and checks for equivalence.
11+
12+
if nargin < 1 || isempty(root_dir)
13+
error('Usage: test_binsparse_roundtrip_dir(root_dir)');
14+
end
15+
16+
if ~isfolder(root_dir)
17+
error('Directory not found: %s', root_dir);
18+
end
19+
20+
if ~exist('binsparse_read', 'file')
21+
error('binsparse_read MEX function not found. Build it first.');
22+
end
23+
24+
if ~exist('binsparse_write', 'file')
25+
error('binsparse_write MEX function not found. Build it first.');
26+
end
27+
28+
files = list_h5_files(root_dir);
29+
if isempty(files)
30+
fprintf('No .h5 files found under %s\n', root_dir);
31+
return;
32+
end
33+
34+
fprintf('Found %d .h5 files under %s\n', numel(files), root_dir);
35+
failures = 0;
36+
37+
for idx = 1:numel(files)
38+
file_path = files{idx};
39+
fprintf('\n[%d/%d] %s\n', idx, numel(files), file_path);
40+
41+
try
42+
matrix = binsparse_read(file_path);
43+
44+
temp_file = [tempname(), '.bsp.h5'];
45+
cleanup = onCleanup(@() cleanup_temp_file(temp_file));
46+
47+
binsparse_write(temp_file, matrix);
48+
roundtrip = binsparse_read(temp_file);
49+
50+
[ok, message] = compare_binsparse_structs(matrix, roundtrip);
51+
if ok
52+
fprintf(' OK\n');
53+
else
54+
failures = failures + 1;
55+
fprintf(' MISMATCH: %s\n', message);
56+
end
57+
58+
clear cleanup;
59+
catch ME
60+
failures = failures + 1;
61+
fprintf(' ERROR: %s\n', ME.message);
62+
end
63+
end
64+
65+
if failures == 0
66+
fprintf('\nAll %d files passed round-trip checks.\n', numel(files));
67+
else
68+
fprintf('\n%d of %d files failed round-trip checks.\n', failures, numel(files));
69+
end
70+
71+
end
72+
73+
function files = list_h5_files(root_dir)
74+
entries = dir(root_dir);
75+
files = {};
76+
77+
for i = 1:numel(entries)
78+
name = entries(i).name;
79+
if entries(i).isdir
80+
if strcmp(name, '.') || strcmp(name, '..')
81+
continue;
82+
end
83+
sub_files = list_h5_files(fullfile(root_dir, name));
84+
if ~isempty(sub_files)
85+
files = [files, sub_files]; %#ok<AGROW>
86+
end
87+
else
88+
[~, ~, ext] = fileparts(name);
89+
if strcmpi(ext, '.h5')
90+
files{end + 1} = fullfile(root_dir, name); %#ok<AGROW>
91+
end
92+
end
93+
end
94+
95+
end
96+
97+
function cleanup_temp_file(temp_file)
98+
if exist(temp_file, 'file')
99+
delete(temp_file);
100+
end
101+
end
102+
103+
function [ok, message] = compare_binsparse_structs(a, b)
104+
fields = {'values', 'indices_0', 'indices_1', 'pointers_to_1', ...
105+
'nrows', 'ncols', 'nnz', 'is_iso', 'format', 'structure'};
106+
107+
for i = 1:numel(fields)
108+
field = fields{i};
109+
if ~isfield(a, field)
110+
ok = false;
111+
message = ['missing field in first matrix: ', field];
112+
return;
113+
end
114+
if ~isfield(b, field)
115+
ok = false;
116+
message = ['missing field in second matrix: ', field];
117+
return;
118+
end
119+
if ~compare_field(a.(field), b.(field))
120+
ok = false;
121+
message = ['field mismatch: ', field];
122+
return;
123+
end
124+
end
125+
126+
extra_a = setdiff(fieldnames(a), fields);
127+
extra_b = setdiff(fieldnames(b), fields);
128+
if ~isempty(extra_a) || ~isempty(extra_b)
129+
ok = false;
130+
message = 'field set mismatch';
131+
return;
132+
end
133+
134+
ok = true;
135+
message = '';
136+
end
137+
138+
function ok = compare_field(a, b)
139+
if ischar(a) || isstring(a) || ischar(b) || isstring(b)
140+
ok = strcmp(char(a), char(b));
141+
else
142+
ok = isequaln(a, b);
143+
end
144+
end

0 commit comments

Comments
 (0)