Skip to content

Commit c1abab9

Browse files
bors[bot]rtzoeller
andauthored
Merge #1624
1624: Fix mq tests on NetBSD and DragonFly r=asomers a=rtzoeller NetBSD (and DragonFly, which borrows its implementation) include additional flags beyond O_NONBLOCK in MqAttr, such as the flags passed to mq_open(). Modify the mq tests to validate _at least_ the expected flags are set, but don't require strict equality on these platforms. Verified these tests pass on DragonFly and NetBSD locally. Co-authored-by: Ryan Zoeller <[email protected]>
2 parents 5359b8e + 58d7c04 commit c1abab9

File tree

1 file changed

+47
-17
lines changed

1 file changed

+47
-17
lines changed

test/test_mq.rs

+47-17
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use cfg_if::cfg_if;
12
use std::ffi::CString;
23
use std::str;
34

@@ -6,6 +7,25 @@ use nix::mqueue::{mq_open, mq_close, mq_send, mq_receive, mq_attr_member_t};
67
use nix::mqueue::{MqAttr, MQ_OFlag};
78
use nix::sys::stat::Mode;
89

10+
// Defined as a macro such that the error source is reported as the caller's location.
11+
macro_rules! assert_attr_eq {
12+
($read_attr:ident, $initial_attr:ident) => {
13+
cfg_if! {
14+
if #[cfg(any(target_os = "dragonfly", target_os = "netbsd"))] {
15+
// NetBSD (and others which inherit its implementation) include other flags
16+
// in read_attr, such as those specified by oflag. Just make sure at least
17+
// the correct bits are set.
18+
assert_eq!($read_attr.flags() & $initial_attr.flags(), $initial_attr.flags());
19+
assert_eq!($read_attr.maxmsg(), $initial_attr.maxmsg());
20+
assert_eq!($read_attr.msgsize(), $initial_attr.msgsize());
21+
assert_eq!($read_attr.curmsgs(), $initial_attr.curmsgs());
22+
} else {
23+
assert_eq!($read_attr, $initial_attr);
24+
}
25+
}
26+
}
27+
}
28+
929
#[test]
1030
fn test_mq_send_and_receive() {
1131
const MSG_SIZE: mq_attr_member_t = 32;
@@ -37,7 +57,6 @@ fn test_mq_send_and_receive() {
3757

3858

3959
#[test]
40-
#[cfg(not(any(target_os = "netbsd")))]
4160
fn test_mq_getattr() {
4261
use nix::mqueue::mq_getattr;
4362
const MSG_SIZE: mq_attr_member_t = 32;
@@ -53,13 +72,12 @@ fn test_mq_getattr() {
5372
let mqd = r.unwrap();
5473

5574
let read_attr = mq_getattr(mqd).unwrap();
56-
assert_eq!(read_attr, initial_attr);
75+
assert_attr_eq!(read_attr, initial_attr);
5776
mq_close(mqd).unwrap();
5877
}
5978

6079
// FIXME: Fix failures for mips in QEMU
6180
#[test]
62-
#[cfg(not(any(target_os = "netbsd")))]
6381
#[cfg_attr(all(
6482
qemu,
6583
any(target_arch = "mips", target_arch = "mips64")
@@ -79,28 +97,33 @@ fn test_mq_setattr() {
7997
};
8098
let mqd = r.unwrap();
8199

82-
let new_attr = MqAttr::new(0, 20, MSG_SIZE * 2, 100);
100+
let new_attr = MqAttr::new(0, 20, MSG_SIZE * 2, 100);
83101
let old_attr = mq_setattr(mqd, &new_attr).unwrap();
84-
assert_eq!(old_attr, initial_attr);
102+
assert_attr_eq!(old_attr, initial_attr);
85103

86-
let new_attr_get = mq_getattr(mqd).unwrap();
87-
// The following tests make sense. No changes here because according to the Linux man page only
104+
// No changes here because according to the Linux man page only
88105
// O_NONBLOCK can be set (see tests below)
89-
assert_ne!(new_attr_get, new_attr);
106+
#[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))]
107+
{
108+
let new_attr_get = mq_getattr(mqd).unwrap();
109+
assert_ne!(new_attr_get, new_attr);
110+
}
90111

91-
let new_attr_non_blocking = MqAttr::new(MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t, 10, MSG_SIZE, 0);
112+
let new_attr_non_blocking = MqAttr::new(MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t, 10, MSG_SIZE, 0);
92113
mq_setattr(mqd, &new_attr_non_blocking).unwrap();
93114
let new_attr_get = mq_getattr(mqd).unwrap();
94115

95116
// now the O_NONBLOCK flag has been set
96-
assert_ne!(new_attr_get, initial_attr);
97-
assert_eq!(new_attr_get, new_attr_non_blocking);
117+
#[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))]
118+
{
119+
assert_ne!(new_attr_get, initial_attr);
120+
}
121+
assert_attr_eq!(new_attr_get, new_attr_non_blocking);
98122
mq_close(mqd).unwrap();
99123
}
100124

101125
// FIXME: Fix failures for mips in QEMU
102126
#[test]
103-
#[cfg(not(any(target_os = "netbsd")))]
104127
#[cfg_attr(all(
105128
qemu,
106129
any(target_arch = "mips", target_arch = "mips64")
@@ -121,20 +144,21 @@ fn test_mq_set_nonblocking() {
121144
let mqd = r.unwrap();
122145
mq_set_nonblock(mqd).unwrap();
123146
let new_attr = mq_getattr(mqd);
124-
assert_eq!(new_attr.unwrap().flags(), MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t);
147+
let o_nonblock_bits = MQ_OFlag::O_NONBLOCK.bits() as mq_attr_member_t;
148+
assert_eq!(new_attr.unwrap().flags() & o_nonblock_bits, o_nonblock_bits);
125149
mq_remove_nonblock(mqd).unwrap();
126150
let new_attr = mq_getattr(mqd);
127-
assert_eq!(new_attr.unwrap().flags(), 0);
151+
assert_eq!(new_attr.unwrap().flags() & o_nonblock_bits, 0);
128152
mq_close(mqd).unwrap();
129153
}
130154

131155
#[test]
132-
#[cfg(not(any(target_os = "netbsd")))]
133156
fn test_mq_unlink() {
134157
use nix::mqueue::mq_unlink;
135158
const MSG_SIZE: mq_attr_member_t = 32;
136159
let initial_attr = MqAttr::new(0, 10, MSG_SIZE, 0);
137160
let mq_name_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
161+
#[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))]
138162
let mq_name_not_opened = &CString::new(b"/mq_unlink_test".as_ref()).unwrap();
139163
let oflag = MQ_OFlag::O_CREAT | MQ_OFlag::O_WRONLY;
140164
let mode = Mode::S_IWUSR | Mode::S_IRUSR | Mode::S_IRGRP | Mode::S_IROTH;
@@ -148,8 +172,14 @@ fn test_mq_unlink() {
148172
let res_unlink = mq_unlink(mq_name_opened);
149173
assert_eq!(res_unlink, Ok(()) );
150174

151-
let res_unlink_not_opened = mq_unlink(mq_name_not_opened);
152-
assert_eq!(res_unlink_not_opened, Err(Errno::ENOENT) );
175+
// NetBSD (and others which inherit its implementation) defer removing the message
176+
// queue name until all references are closed, whereas Linux and others remove the
177+
// message queue name immediately.
178+
#[cfg(not(any(target_os = "dragonfly", target_os = "netbsd")))]
179+
{
180+
let res_unlink_not_opened = mq_unlink(mq_name_not_opened);
181+
assert_eq!(res_unlink_not_opened, Err(Errno::ENOENT) );
182+
}
153183

154184
mq_close(mqd).unwrap();
155185
let res_unlink_after_close = mq_unlink(mq_name_opened);

0 commit comments

Comments
 (0)