1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//! # serial_test
//! `serial_test` allows for the creation of serialised Rust tests using the [serial](macro@serial) attribute
//! e.g.
//! ````no_run
//! #[test]
//! #[serial]
//! fn test_serial_one() {
//! // Do things
//! }
//!
//! #[test]
//! #[serial(some_key)]
//! fn test_serial_another() {
//! // Do things
//! }
//!
//! #[test]
//! #[parallel]
//! fn test_parallel_another() {
//! // Do parallel things
//! }
//! ````
//! Multiple tests with the [serial](macro@serial) attribute are guaranteed to be executed in serial. Ordering
//! of the tests is not guaranteed however. Other tests with the [parallel](macro@parallel) attribute may run
//! at the same time as each other, but not at the same time as a test with [serial](macro@serial). Tests with
//! neither attribute may run at any time and no guarantees are made about their timing!
//!
//! For cases like doctests and integration tests where the tests are run as separate processes, we also support
//! [file_serial](macro@file_serial)/[file_parallel](macro@file_parallel), with similar properties but based off file locking. Note that there are no
//! guarantees about one test with [serial](macro@serial)/[parallel](macro@parallel) and another with [file_serial](macro@file_serial)/[file_parallel](macro@file_parallel)
//! as they lock using different methods.
//! ````no_run
//! #[test]
//! #[file_serial]
//! fn test_serial_three() {
//! // Do things
//! }
//! ````
//!
//! All of the attributes can also be applied at a `mod` level and will be automagically applied to all test functions in that block
//! ````no_run
//! #[cfg(test)]
//! #[serial]
//! mod serial_attr_tests {
//! fn foo() {
//! // Won't have `serial` applied, because not a test function
//! println!("Nothing");
//! }
//!
//! #[test]
//! fn test_bar() {
//! // Will be run serially
//! }
//!}
//! ````
//!
//! All of the attributes support an optional `crate` argument for other macros generating
//! the attributes, which lets them re-export the serial_test crate and supply an import path.
//! This defaults to assuming it can just import `serial_test` for the use of internal functions.
//! Note this is `crate = <import-path>` not `crate => <import-path>` unlike the `path` in [file_serial](macro@file_serial)
//! for historical reasons
//! ````no_run
//! // Assuming wrapper::refs:serial is a re-export of serial_test
//! #[test]
//! #[serial(crate = wrapper::refs:serial)]
//! fn test_generated() {
//! // Do things
//! }
//! ````
//!
//! ## Inner Attributes
//!
//! You can apply attributes to an inner test function using `inner_attrs`. This is useful for
//! applying attributes like `ntest::timeout` that should only affect the test body, not the
//! mutex/lock acquisition. Without this, a timeout would start counting from when the test is
//! waiting for the lock, not when the actual test logic starts.
//!
//! ````no_run
//! #[test]
//! #[serial(inner_attrs = [ntest::timeout(1000)])]
//! fn test_with_timeout() {
//! // The timeout only applies to this body, not the serial lock acquisition
//! }
//! ````
//!
//! You can combine `inner_attrs` with keys and other options:
//! ````no_run
//! #[test]
//! #[serial(my_key, inner_attrs = [ntest::timeout(1000)])]
//! fn test_with_key_and_timeout() {
//! // Serialized with 'my_key' group, with timeout on the body
//! }
//! ````
//!
//! ## Feature flags
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;
pub use is_locked_file_serially;
pub use ;
pub use ;
// Re-export #[serial/parallel].
pub use ;
pub use ;
pub use is_locked_serially;