comparison rust/pyo3-sharedref/tests/test_sharedref.rs @ 52613:ac0cb3c334a1

rust-pyo3-sharedref: renamings in test Now that the renamings are done in main code, we give local variables and helper functions in the integration tests matching names.
author Georges Racinet <georges.racinet@cloudcrane.io>
date Sun, 15 Dec 2024 20:00:09 +0100
parents a945845137b1
children
comparison
equal deleted inserted replaced
52612:a945845137b1 52613:ac0cb3c334a1
24 }) 24 })
25 } 25 }
26 26
27 /// "leak" in the sense of `SharedByPyObject` the `string` data field, 27 /// "leak" in the sense of `SharedByPyObject` the `string` data field,
28 /// taking care of all the boilerplate 28 /// taking care of all the boilerplate
29 fn leak_string(owner: &Bound<'_, Owner>) -> SharedByPyObject<&'static String> { 29 fn share_string(
30 let cell = &owner.borrow().string; 30 owner: &Bound<'_, Owner>,
31 unsafe { cell.share(owner) } 31 ) -> SharedByPyObject<&'static String> {
32 } 32 let shareable = &owner.borrow().string;
33 33 unsafe { shareable.share(owner) }
34 fn try_leak_string( 34 }
35
36 fn try_share_string(
35 owner: &Bound<'_, Owner>, 37 owner: &Bound<'_, Owner>,
36 ) -> Result<SharedByPyObject<&'static String>, TryShareError> { 38 ) -> Result<SharedByPyObject<&'static String>, TryShareError> {
37 let cell = &owner.borrow().string; 39 let shareable = &owner.borrow().string;
38 unsafe { cell.try_share(owner) } 40 unsafe { shareable.try_share(owner) }
39 } 41 }
40 42
41 /// Mutate the `string` field of `owner` as would be done from Python code 43 /// Mutate the `string` field of `owner` as would be done from Python code
42 /// 44 ///
43 /// This is to simulate normal mutation of the owner object from 45 /// This is to simulate normal mutation of the owner object from
47 /// from rust-cpython 49 /// from rust-cpython
48 fn mutate_string<'py>( 50 fn mutate_string<'py>(
49 owner: &'py Bound<'py, Owner>, 51 owner: &'py Bound<'py, Owner>,
50 f: impl FnOnce(&mut String), 52 f: impl FnOnce(&mut String),
51 ) -> () { 53 ) -> () {
52 let cell = &owner.borrow_mut().string; 54 let shareable = &owner.borrow_mut().string;
53 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 55 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
54 f(&mut shared_ref.write()); 56 f(&mut shared_ref.write());
55 } 57 }
56 58
57 #[test] 59 #[test]
58 fn test_leaked_borrow() -> PyResult<()> { 60 fn test_shared_borrow() -> PyResult<()> {
59 with_setup(|py, owner| { 61 with_setup(|py, owner| {
60 let leaked = leak_string(owner); 62 let shared = share_string(owner);
61 let leaked_ref = unsafe { leaked.try_borrow(py) }.unwrap(); 63 let shared_ref = unsafe { shared.try_borrow(py) }.unwrap();
62 assert_eq!(*leaked_ref, "new"); 64 assert_eq!(*shared_ref, "new");
63 Ok(()) 65 Ok(())
64 }) 66 })
65 } 67 }
66 68
67 #[test] 69 #[test]
68 fn test_leaked_borrow_mut() -> PyResult<()> { 70 fn test_shared_borrow_mut() -> PyResult<()> {
69 with_setup(|py, owner| { 71 with_setup(|py, owner| {
70 let leaked = leak_string(owner); 72 let shared = share_string(owner);
71 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; 73 let mut shared_iter = unsafe { shared.map(py, |s| s.chars()) };
72 let mut leaked_ref = 74 let mut shared_ref =
73 unsafe { leaked_iter.try_borrow_mut(py) }.unwrap(); 75 unsafe { shared_iter.try_borrow_mut(py) }.unwrap();
74 assert_eq!(leaked_ref.next(), Some('n')); 76 assert_eq!(shared_ref.next(), Some('n'));
75 assert_eq!(leaked_ref.next(), Some('e')); 77 assert_eq!(shared_ref.next(), Some('e'));
76 assert_eq!(leaked_ref.next(), Some('w')); 78 assert_eq!(shared_ref.next(), Some('w'));
77 assert_eq!(leaked_ref.next(), None); 79 assert_eq!(shared_ref.next(), None);
78 Ok(()) 80 Ok(())
79 }) 81 })
80 } 82 }
81 83
82 #[test] 84 #[test]
83 fn test_leaked_borrow_after_mut() -> PyResult<()> { 85 fn test_shared_borrow_after_mut() -> PyResult<()> {
84 with_setup(|py, owner| { 86 with_setup(|py, owner| {
85 let leaked = leak_string(owner); 87 let shared = share_string(owner);
86 mutate_string(owner, String::clear); 88 mutate_string(owner, String::clear);
87 assert!(unsafe { leaked.try_borrow(py) }.is_err()); 89 assert!(unsafe { shared.try_borrow(py) }.is_err());
88 Ok(()) 90 Ok(())
89 }) 91 })
90 } 92 }
91 93
92 #[test] 94 #[test]
93 fn test_leaked_borrow_mut_after_mut() -> PyResult<()> { 95 fn test_shared_borrow_mut_after_mut() -> PyResult<()> {
94 with_setup(|py, owner| { 96 with_setup(|py, owner| {
95 let leaked = leak_string(owner); 97 let shared = share_string(owner);
96 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; 98 let mut shared_iter = unsafe { shared.map(py, |s| s.chars()) };
97 99
98 mutate_string(owner, String::clear); 100 mutate_string(owner, String::clear);
99 assert!(unsafe { leaked_iter.try_borrow_mut(py) }.is_err()); 101 assert!(unsafe { shared_iter.try_borrow_mut(py) }.is_err());
100 Ok(()) 102 Ok(())
101 }) 103 })
102 } 104 }
103 105
104 #[test] 106 #[test]
105 #[should_panic(expected = "map() over invalidated shared reference")] 107 #[should_panic(expected = "map() over invalidated shared reference")]
106 fn test_leaked_map_after_mut() { 108 fn test_shared_map_after_mut() {
107 with_setup(|py, owner| { 109 with_setup(|py, owner| {
108 let leaked = leak_string(owner); 110 let shared = share_string(owner);
109 mutate_string(owner, String::clear); 111 mutate_string(owner, String::clear);
110 let _leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; 112 let _shared_iter = unsafe { shared.map(py, |s| s.chars()) };
111 Ok(()) 113 Ok(())
112 }) 114 })
113 .expect("should already have panicked") 115 .expect("should already have panicked")
114 } 116 }
115 117
116 /// run `try_borrow_mut` on the `string` field and assert it is not an error 118 /// run `try_borrow_mut` on the `string` field and assert it is not an error
117 /// 119 ///
118 /// Simply returning the `Result` is not possible, because that is 120 /// Simply returning the `Result` is not possible, because that is
119 /// returning a reference to data owned by the function 121 /// returning a reference to data owned by the function
120 fn assert_try_write_string_ok(owner: &Bound<'_, Owner>) { 122 fn assert_try_write_string_ok(owner: &Bound<'_, Owner>) {
121 let cell = &owner.borrow().string; 123 let shareable = &owner.borrow().string;
122 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 124 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
123 assert!(shared_ref.try_write().is_ok()); 125 assert!(shared_ref.try_write().is_ok());
124 } 126 }
125 127
126 fn assert_try_write_string_err(owner: &Bound<'_, Owner>) { 128 fn assert_try_write_string_err(owner: &Bound<'_, Owner>) {
127 let cell = &owner.borrow().string; 129 let shareable = &owner.borrow().string;
128 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 130 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
129 assert!(shared_ref.try_write().is_err()); 131 assert!(shared_ref.try_write().is_err());
130 } 132 }
131 133
132 fn assert_try_read_string_err(owner: &Bound<'_, Owner>) { 134 fn assert_try_read_string_err(owner: &Bound<'_, Owner>) {
133 let cell = &owner.borrow().string; 135 let shareable = &owner.borrow().string;
134 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 136 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
135 assert!(shared_ref.try_read().is_err()); 137 assert!(shared_ref.try_read().is_err());
136 } 138 }
137 139
138 #[test] 140 #[test]
139 fn test_try_write_while_leaked_ref() -> PyResult<()> { 141 fn test_try_write_while_shared_ref() -> PyResult<()> {
140 with_setup(|py, owner| { 142 with_setup(|py, owner| {
141 assert_try_write_string_ok(owner); 143 assert_try_write_string_ok(owner);
142 let leaked = leak_string(owner); 144 let shared = share_string(owner);
143 { 145 {
144 let _leaked_ref = unsafe { leaked.try_borrow(py) }.unwrap(); 146 let _shared_ref = unsafe { shared.try_borrow(py) }.unwrap();
145 assert_try_write_string_err(owner); 147 assert_try_write_string_err(owner);
146 { 148 {
147 let _leaked_ref2 = unsafe { leaked.try_borrow(py) }.unwrap(); 149 let _shared_ref2 = unsafe { shared.try_borrow(py) }.unwrap();
148 assert_try_write_string_err(owner); 150 assert_try_write_string_err(owner);
149 } 151 }
150 assert_try_write_string_err(owner); 152 assert_try_write_string_err(owner);
151 } 153 }
152 assert_try_write_string_ok(owner); 154 assert_try_write_string_ok(owner);
153 Ok(()) 155 Ok(())
154 }) 156 })
155 } 157 }
156 158
157 #[test] 159 #[test]
158 fn test_try_write_while_leaked_ref_mut() -> PyResult<()> { 160 fn test_try_write_while_shared_ref_mut() -> PyResult<()> {
159 with_setup(|py, owner| { 161 with_setup(|py, owner| {
160 assert_try_write_string_ok(owner); 162 assert_try_write_string_ok(owner);
161 let leaked = leak_string(owner); 163 let shared = share_string(owner);
162 let mut leaked_iter = unsafe { leaked.map(py, |s| s.chars()) }; 164 let mut shared_iter = unsafe { shared.map(py, |s| s.chars()) };
163 { 165 {
164 let _leaked_ref = 166 let _shared_ref =
165 unsafe { leaked_iter.try_borrow_mut(py) }.unwrap(); 167 unsafe { shared_iter.try_borrow_mut(py) }.unwrap();
166 assert_try_write_string_err(owner); 168 assert_try_write_string_err(owner);
167 } 169 }
168 assert_try_write_string_ok(owner); 170 assert_try_write_string_ok(owner);
169 Ok(()) 171 Ok(())
170 }) 172 })
171 } 173 }
172 174
173 #[test] 175 #[test]
174 fn test_try_leak_while_write() -> PyResult<()> { 176 fn test_try_share_while_write() -> PyResult<()> {
175 with_setup(|_py, owner| { 177 with_setup(|_py, owner| {
176 let cell = &owner.borrow().string; 178 let shareable = &owner.borrow().string;
177 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 179 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
178 let _mut_ref = shared_ref.write(); 180 let _mut_ref = shared_ref.write();
179 181
180 assert!(try_leak_string(owner).is_err()); 182 assert!(try_share_string(owner).is_err());
181 Ok(()) 183 Ok(())
182 }) 184 })
183 } 185 }
184 186
185 #[test] 187 #[test]
186 #[should_panic(expected = "already mutably borrowed")] 188 #[should_panic(expected = "already mutably borrowed")]
187 fn test_leak_while_write() { 189 fn test_share_while_write() {
188 with_setup(|_py, owner| { 190 with_setup(|_py, owner| {
189 let cell = &owner.borrow().string; 191 let shareable = &owner.borrow().string;
190 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 192 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
191 let _mut_ref = shared_ref.write(); 193 let _mut_ref = shared_ref.write();
192 194
193 leak_string(owner); 195 share_string(owner);
194 Ok(()) 196 Ok(())
195 }) 197 })
196 .expect("should already have panicked") 198 .expect("should already have panicked")
197 } 199 }
198 200
199 #[test] 201 #[test]
200 fn test_try_write_while_borrow() -> PyResult<()> { 202 fn test_try_write_while_borrow() -> PyResult<()> {
201 with_setup(|_py, owner| { 203 with_setup(|_py, owner| {
202 let cell = &owner.borrow().string; 204 let shareable = &owner.borrow().string;
203 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 205 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
204 let _ref = shared_ref.read(); 206 let _ref = shared_ref.read();
205 207
206 assert_try_write_string_err(owner); 208 assert_try_write_string_err(owner);
207 Ok(()) 209 Ok(())
208 }) 210 })
210 212
211 #[test] 213 #[test]
212 #[should_panic(expected = "already borrowed")] 214 #[should_panic(expected = "already borrowed")]
213 fn test_write_while_borrow() { 215 fn test_write_while_borrow() {
214 with_setup(|_py, owner| { 216 with_setup(|_py, owner| {
215 let cell = &owner.borrow().string; 217 let shareable = &owner.borrow().string;
216 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 218 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
217 let _ref = shared_ref.read(); 219 let _ref = shared_ref.read();
218 220
219 let shared_ref2 = unsafe { cell.borrow_with_owner(owner) }; 221 let shared_ref2 = unsafe { shareable.borrow_with_owner(owner) };
220 let _mut_ref = shared_ref2.write(); 222 let _mut_ref = shared_ref2.write();
221 Ok(()) 223 Ok(())
222 }) 224 })
223 .expect("should already have panicked") 225 .expect("should already have panicked")
224 } 226 }
225 227
226 #[test] 228 #[test]
227 fn test_try_borrow_while_write() -> PyResult<()> { 229 fn test_try_borrow_while_write() -> PyResult<()> {
228 with_setup(|_py, owner| { 230 with_setup(|_py, owner| {
229 let cell = &owner.borrow().string; 231 let shareable = &owner.borrow().string;
230 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 232 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
231 let _mut_ref = shared_ref.write(); 233 let _mut_ref = shared_ref.write();
232 234
233 assert_try_read_string_err(owner); 235 assert_try_read_string_err(owner);
234 Ok(()) 236 Ok(())
235 }) 237 })
237 239
238 #[test] 240 #[test]
239 #[should_panic(expected = "already mutably borrowed")] 241 #[should_panic(expected = "already mutably borrowed")]
240 fn test_borrow_while_write() { 242 fn test_borrow_while_write() {
241 with_setup(|_py, owner| { 243 with_setup(|_py, owner| {
242 let cell = &owner.borrow().string; 244 let shareable = &owner.borrow().string;
243 let shared_ref = unsafe { cell.borrow_with_owner(owner) }; 245 let shared_ref = unsafe { shareable.borrow_with_owner(owner) };
244 let _mut_ref = shared_ref.write(); 246 let _mut_ref = shared_ref.write();
245 247
246 let shared_ref2 = unsafe { cell.borrow_with_owner(owner) }; 248 let shared_ref2 = unsafe { shareable.borrow_with_owner(owner) };
247 let _ref = shared_ref2.read(); 249 let _ref = shared_ref2.read();
248 Ok(()) 250 Ok(())
249 }) 251 })
250 .expect("should already have panicked") 252 .expect("should already have panicked")
251 } 253 }