authorgravatar for aleksey.kladov@gmail.comAlex Kladov <aleksey.kladov@gmail.com> 2024-06-20 20:38:54+01:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-06-20 12:38:54-07:00
loge03026507f6e3f0b60947d9859c1346f64f480b6
treed6ff64f85bf36e677029f3a677a91d302b870efb
parent5afd774db35e1e12cc49aab5b7f134b741545b80
signaturebadge-check Signed by PGP key B5690EEEBB952194

std: fuzz test sort stability (#20284)

Stability of std sort was undertested before this change. Add a fuzz test for more confidence. Specifically, we used to have a single example test that used an array of eight elements. That ends up exercising only a tiny fraction of sorting logic, as it hits a hard-coded sorting network due to small size.

1 files changed, 30 insertions(+), 2 deletions(-)

lib/std/sort.zig+30-2
...@@ -222,6 +222,35 @@ test "stable sort" {...@@ -222,6 +222,35 @@ test "stable sort" {
222 }222 }
223}223}
224224
225test "stable sort fuzz testing" {
226 var prng = std.Random.DefaultPrng.init(0x12345678);
227 const random = prng.random();
228 const test_case_count = 10;
229
230 for (0..test_case_count) |_| {
231 const array_size = random.intRangeLessThan(usize, 0, 1000);
232 const array = try testing.allocator.alloc(IdAndValue, array_size);
233 defer testing.allocator.free(array);
234 // Value is a small random numbers to create collisions.
235 // Id is a reverse index to make sure sorting function only uses provided `lessThan`.
236 for (array, 0..) |*item, index| {
237 item.* = .{
238 .value = random.intRangeLessThan(i32, 0, 100),
239 .id = array_size - index,
240 };
241 }
242 block(IdAndValue, array, {}, IdAndValue.lessThan);
243 if (array_size > 0) {
244 for (array[0 .. array_size - 1], array[1..]) |x, y| {
245 try testing.expect(x.value <= y.value);
246 if (x.value == y.value) {
247 try testing.expect(x.id > y.id);
248 }
249 }
250 }
251 }
252}
253
225test "sort" {254test "sort" {
226 const u8cases = [_][]const []const u8{255 const u8cases = [_][]const []const u8{
227 &[_][]const u8{256 &[_][]const u8{
...@@ -384,8 +413,7 @@ test "sort fuzz testing" {...@@ -384,8 +413,7 @@ test "sort fuzz testing" {
384 const test_case_count = 10;413 const test_case_count = 10;
385414
386 inline for (sort_funcs) |sortFn| {415 inline for (sort_funcs) |sortFn| {
387 var i: usize = 0;416 for (0..test_case_count) |_| {
388 while (i < test_case_count) : (i += 1) {
389 const array_size = random.intRangeLessThan(usize, 0, 1000);417 const array_size = random.intRangeLessThan(usize, 0, 1000);
390 const array = try testing.allocator.alloc(i32, array_size);418 const array = try testing.allocator.alloc(i32, array_size);
391 defer testing.allocator.free(array);419 defer testing.allocator.free(array);