#include <unistd.h>
#include <errno.h>
#include <string.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <poll.h>
+#include <fcntl.h>
#include <thread>
#include <memory>
+#include <stdexcept>
#include <boost_macros_wrapper.h>
#include <boost/test/results_reporter.hpp>
}
/*
- * Add pipe[0] descriptor and wait. Callback should not be called. Instead the 8s timeout should
+ * Add pipe[0] descriptor and wait. Callback should not be called. Instead the 1s timeout should
* occur and a proper exception should be thrown.
*/
NEGATIVE_TEST_CASE(T060_Timeout)
BOOST_REQUIRE_MESSAGE(callback2, "Second callback not called");
}
+/*
+ * Add negative descriptor and wait. Callback should not be called. Instead the 1s timeout
+ * should occur and a proper exception should be thrown.
+ */
+NEGATIVE_TEST_CASE(T100_AddNegativeFd)
+{
+ DescriptorSet descriptors;
+ descriptors.add(-1, POLLALL, unexpectedCallback);
+
+ BOOST_REQUIRE_THROW(descriptors.wait(POLL_TIMEOUT_SHORT), DescriptorSet::Timeout);
+}
+
+/*
+ * Cross the descriptor limit which should lead to EINVAL. Utilize unused descriptors only. Callback
+ * should not be called.
+ */
+NEGATIVE_TEST_CASE(T110_DescriptorLimit)
+{
+ DescriptorSet descriptors;
+
+ struct rlimit limit;
+ BOOST_REQUIRE(getrlimit(RLIMIT_NOFILE, &limit) == 0);
+
+ int fd = 3;
+ for(rlim_t i = 0; i <= limit.rlim_cur; ++fd) {
+ int ret = fcntl(fd, F_GETFD);
+ int err = errno;
+ BOOST_REQUIRE(ret != -1 || err == EBADF);
+ if (ret == -1) {
+ descriptors.add(fd, POLLALL, unexpectedCallback);
+ ++i;
+ }
+ }
+
+ BOOST_REQUIRE_THROW(descriptors.wait(POLL_TIMEOUT_SHORT), DescriptorSet::InternalError);
+}
+
+/*
+ * Not opened descriptor should trigger a callback with error.
+ */
+NEGATIVE_TEST_CASE(T120_NotOpenedDescriptor)
+{
+ DescriptorSet descriptors;
+
+ bool callbackCalled = false;
+ auto callback = [&](int, short revents) {
+ callbackCalled = true;
+ BOOST_REQUIRE(revents == POLLNVAL);
+ };
+ descriptors.add(42, POLLALL, callback);
+
+ BOOST_REQUIRE_NO_THROW(descriptors.wait(POLL_TIMEOUT));
+ BOOST_REQUIRE(callbackCalled);
+}
+
+/*
+ * Throwing callback. The exception should be propagated outside of DescriptorSet::wait().
+ */
+NEGATIVE_TEST_CASE(T130_ThrowingCallback)
+{
+ DescriptorSet descriptors;
+
+ auto throwingCallback = [&](int, short) {
+ throw std::runtime_error("");
+ };
+ descriptors.add(42, POLLALL, throwingCallback);
+
+ BOOST_REQUIRE_THROW(descriptors.wait(POLL_TIMEOUT), std::runtime_error);
+}
+
+
BOOST_AUTO_TEST_SUITE_END()