Commit 258f06b1ef for openssl.org
commit 258f06b1ef57ce147ff2b1da5977d9e9adc55be7
Author: Mounir IDRASSI <mounir.idrassi@idrix.fr>
Date: Thu Jul 30 09:25:18 2026 +0900
test: cover duplicate fd event merging in RIO poll builder
Add a poll-backend unit test which registers the same fd first for
reading and then for writing. Verify that the builder retains one
pollfd with both POLLIN and POLLOUT set.
Without the preceding fix, the test observes POLLOUT only. Wire the
test into the QUIC-gated test build and skip it on non-poll backends.
Assisted-by: Codex:gpt-5.6-sol
Reviewed-by: Paul Yang <paulyang.inf@gmail.com>
Reviewed-by: Jakub Zelenka <jakub.zelenka@openssl.foundation>
MergeDate: Tue Aug 11 07:12:58 2026
(Merged from https://github.com/openssl/openssl/pull/32117)
diff --git a/test/build.info b/test/build.info
index 53c4a2380d..e533f737af 100644
--- a/test/build.info
+++ b/test/build.info
@@ -91,7 +91,8 @@ IF[{- !$disabled{tests} -}]
IF[{- !$disabled{quic} -}]
PROGRAMS{noinst}=priority_queue_test quicfaultstest quicapitest \
- quic_newcid_test quic_srt_gen_test rio_notifier_test
+ quic_newcid_test quic_srt_gen_test rio_notifier_test \
+ rio_poll_builder_test
ENDIF
IF[{- !$disabled{quic} && !$disabled{qlog} -}]
@@ -401,6 +402,10 @@ IF[{- !$disabled{tests} -}]
INCLUDE[rio_notifier_test]=.. ../include ../apps/include
DEPEND[rio_notifier_test]=../libcrypto.a ../libssl.a libtestutil.a
+ SOURCE[rio_poll_builder_test]=rio_poll_builder_test.c
+ INCLUDE[rio_poll_builder_test]=.. ../include ../apps/include
+ DEPEND[rio_poll_builder_test]=../libcrypto.a ../libssl.a libtestutil.a
+
SOURCE[quic_wire_test]=quic_wire_test.c
INCLUDE[quic_wire_test]=../include ../apps/include
DEPEND[quic_wire_test]=../libcrypto.a ../libssl.a libtestutil.a
diff --git a/test/recipes/70-test_rio_poll_builder.t b/test/recipes/70-test_rio_poll_builder.t
new file mode 100644
index 0000000000..e76c2f280a
--- /dev/null
+++ b/test/recipes/70-test_rio_poll_builder.t
@@ -0,0 +1,19 @@
+#! /usr/bin/env perl
+# Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use OpenSSL::Test;
+use OpenSSL::Test::Utils;
+
+setup("test_rio_poll_builder");
+
+plan skip_all => "RIO poll builder tests require QUIC"
+ if disabled("quic");
+
+plan tests => 1;
+
+ok(run(test(["rio_poll_builder_test"])));
diff --git a/test/rio_poll_builder_test.c b/test/rio_poll_builder_test.c
new file mode 100644
index 0000000000..f4acb7b9c2
--- /dev/null
+++ b/test/rio_poll_builder_test.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2026 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include "../ssl/rio/poll_builder.h"
+#include "testutil.h"
+
+static int test_duplicate_fd(void)
+{
+#if RIO_POLL_METHOD == RIO_POLL_METHOD_POLL
+ RIO_POLL_BUILDER rpb;
+ struct pollfd *pfds;
+ int ret = 0;
+
+ if (!TEST_true(ossl_rio_poll_builder_init(&rpb)))
+ return 0;
+
+ if (!TEST_true(ossl_rio_poll_builder_add_fd(&rpb, 0, 1, 0))
+ || !TEST_true(ossl_rio_poll_builder_add_fd(&rpb, 0, 0, 1)))
+ goto out;
+
+ pfds = rpb.pfd_heap != NULL ? rpb.pfd_heap : rpb.pfds;
+ if (!TEST_size_t_eq(rpb.pfd_num, 1)
+ || !TEST_int_eq(pfds[0].events, POLLIN | POLLOUT))
+ goto out;
+
+ ret = 1;
+out:
+ ossl_rio_poll_builder_cleanup(&rpb);
+ return ret;
+#else
+ return TEST_skip("poll() backend is not in use");
+#endif
+}
+
+int setup_tests(void)
+{
+ ADD_TEST(test_duplicate_fd);
+ return 1;
+}