1use super::{AsyncGroup, DataConn, DataConnContainer, DataConnManager, ErrEntry, SendSyncNonNull};
6use crate::{TxnFailureCause, TxnFailureReport, TxnFailureRollback};
7
8use std::collections::HashMap;
9use std::future::Future;
10use std::pin::Pin;
11use std::sync::Arc;
12use std::{any, mem};
13
14#[allow(clippy::enum_variant_names)]
16#[derive(Debug)]
17pub enum DataConnError {
18 FailToPreCommitDataConn {
20 errors: Vec<ErrEntry>,
22 },
23
24 FailToCommitDataConn {
26 errors: Vec<ErrEntry>,
28 },
29
30 FailToPostCommitDataConn {
32 errors: Vec<ErrEntry>,
34 },
35
36 FailToCastDataConn {
38 name: Arc<str>,
40
41 target_type: &'static str,
43 },
44}
45
46impl<C> DataConnContainer<C>
47where
48 C: DataConn + 'static,
49{
50 pub(crate) fn new(name: impl Into<Arc<str>>, data_conn: Box<C>) -> Self {
51 Self {
52 drop_fn: drop_data_conn::<C>,
53 is_fn: is_data_conn::<C>,
54 type_fn: type_of_data_conn::<C>,
55 commit_fn: commit_data_conn_async::<C>,
56 pre_commit_fn: pre_commit_data_conn_async::<C>,
57 post_commit_fn: post_commit_data_conn_async::<C>,
58 is_committed_fn: is_committed_data_conn::<C>,
59 rollback_fn: rollback_data_conn_async::<C>,
60 on_txn_failure_fn: on_txn_failure_data_conn_async::<C>,
61 close_fn: close_data_conn::<C>,
62
63 name: name.into(),
64 data_conn,
65 }
66 }
67}
68
69fn drop_data_conn<C>(ptr: *const DataConnContainer)
70where
71 C: DataConn + 'static,
72{
73 unsafe {
74 drop(Box::from_raw(ptr as *mut DataConnContainer<C>));
75 }
76}
77
78fn is_data_conn<C>(type_id: any::TypeId) -> bool
79where
80 C: DataConn + 'static,
81{
82 any::TypeId::of::<C>() == type_id
83}
84
85fn type_of_data_conn<C>() -> &'static str
86where
87 C: DataConn + 'static,
88{
89 any::type_name::<C>()
90}
91
92fn commit_data_conn_async<C>(
93 ptr: *const DataConnContainer,
94 ag: &mut AsyncGroup,
95) -> Pin<Box<dyn Future<Output = errs::Result<()>> + Send + '_>>
96where
97 C: DataConn + 'static,
98{
99 let container = unsafe { &mut *(ptr as *mut DataConnContainer<C>) };
100 Box::pin(container.data_conn.commit_async(ag))
101}
102
103fn pre_commit_data_conn_async<C>(
104 ptr: *const DataConnContainer,
105 ag: &mut AsyncGroup,
106) -> Pin<Box<dyn Future<Output = errs::Result<()>> + Send + '_>>
107where
108 C: DataConn + 'static,
109{
110 let container = unsafe { &mut *(ptr as *mut DataConnContainer<C>) };
111 Box::pin(container.data_conn.pre_commit_async(ag))
112}
113
114fn post_commit_data_conn_async<C>(
115 ptr: *const DataConnContainer,
116 ag: &mut AsyncGroup,
117) -> Pin<Box<dyn Future<Output = errs::Result<()>> + Send + '_>>
118where
119 C: DataConn + 'static,
120{
121 let container = unsafe { &mut *(ptr as *mut DataConnContainer<C>) };
122 Box::pin(container.data_conn.post_commit_async(ag))
123}
124
125fn is_committed_data_conn<C>(ptr: *const DataConnContainer) -> bool
126where
127 C: DataConn + 'static,
128{
129 let container = unsafe { &*(ptr as *const DataConnContainer<C>) };
130 container.data_conn.is_committed()
131}
132
133fn rollback_data_conn_async<C>(
134 ptr: *const DataConnContainer,
135 ag: &mut AsyncGroup,
136) -> Pin<Box<dyn Future<Output = errs::Result<()>> + Send + '_>>
137where
138 C: DataConn + 'static,
139{
140 let container = unsafe { &mut *(ptr as *mut DataConnContainer<C>) };
141 Box::pin(container.data_conn.rollback_async(ag))
142}
143
144fn on_txn_failure_data_conn_async<C>(
145 ptr: *const DataConnContainer,
146 ag: &mut AsyncGroup,
147 reports: Arc<[TxnFailureReport]>,
148) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>
149where
150 C: DataConn + 'static,
151{
152 let container = unsafe { &mut *(ptr as *mut DataConnContainer<C>) };
153 Box::pin(container.data_conn.on_txn_failure_async(ag, reports))
154}
155
156fn close_data_conn<C>(ptr: *const DataConnContainer)
157where
158 C: DataConn + 'static,
159{
160 let container = unsafe { &mut *(ptr as *mut DataConnContainer<C>) };
161 container.data_conn.close();
162}
163
164impl DataConnManager {
165 pub(crate) fn new() -> Self {
166 Self {
167 vec: Vec::new(),
168 index_map: HashMap::new(),
169 committed: false,
170 }
171 }
172
173 pub(crate) fn with_commit_order(names: &[&str]) -> Self {
174 let mut index_map = HashMap::with_capacity(names.len());
175 for (i, nm) in names.iter().rev().enumerate() {
177 index_map.insert((*nm).into(), names.len() - 1 - i);
178 }
179
180 Self {
181 vec: vec![None; names.len()],
182 index_map,
183 committed: false,
184 }
185 }
186
187 pub(crate) fn add(&mut self, ssnnptr: SendSyncNonNull<DataConnContainer>) {
188 let name = unsafe { (*ssnnptr.non_null_ptr.as_ptr()).name.clone() };
189 if let Some(index) = self.index_map.get(&name) {
190 if self.vec[*index].is_none() {
192 self.vec[*index] = Some(ssnnptr);
193 }
194 } else {
195 let index = self.vec.len();
196 self.vec.push(Some(ssnnptr));
197 self.index_map.insert(name.clone(), index);
198 }
199 }
200
201 pub(crate) fn find_by_name(
202 &self,
203 name: impl AsRef<str>,
204 ) -> Option<SendSyncNonNull<DataConnContainer>> {
205 if let Some(index) = self.index_map.get(name.as_ref()) {
206 if *index < self.vec.len() {
207 if let Some(ssnnptr) = &self.vec[*index] {
208 let ptr = ssnnptr.non_null_ptr.as_ptr();
209 let cont_name = unsafe { &(*ptr).name };
210 if cont_name.as_ref() == name.as_ref() {
211 return Some(*ssnnptr);
212 }
213 }
214 }
215 }
216
217 None
218 }
219
220 pub(crate) fn to_typed_ptr<C>(
221 ssnnptr: &SendSyncNonNull<DataConnContainer>,
222 ) -> errs::Result<*mut DataConnContainer<C>>
223 where
224 C: DataConn + 'static,
225 {
226 let ptr = ssnnptr.non_null_ptr.as_ptr();
227 let name = unsafe { &(*ptr).name };
228 let type_id = any::TypeId::of::<C>();
229 let is_fn = unsafe { (*ptr).is_fn };
230
231 if !is_fn(type_id) {
232 return Err(errs::Err::new(DataConnError::FailToCastDataConn {
233 name: name.clone(),
234 target_type: any::type_name::<C>(),
235 }));
236 }
237
238 let typed_ptr = ptr as *mut DataConnContainer<C>;
239 Ok(typed_ptr)
240 }
241
242 pub(crate) fn new_failure_reports(&self) -> Vec<TxnFailureReport> {
243 let mut reports = Vec::new();
244 for ssnnptr in self.vec.iter().flatten() {
245 let ptr = ssnnptr.non_null_ptr.as_ptr();
246 let name = unsafe { (*ptr).name.clone() };
247 let type_fn = unsafe { (*ptr).type_fn };
248 let report = TxnFailureReport::new(name, type_fn());
249 reports.push(report);
250 }
251 reports
252 }
253
254 pub(crate) async fn commit_async(
255 &mut self,
256 reports: &mut [TxnFailureReport],
257 ) -> errs::Result<()> {
258 let mut errors = Vec::new();
259
260 let mut ag = AsyncGroup::new();
261 for (i, ssnnptr) in self.vec.iter().flatten().enumerate() {
262 let ptr = ssnnptr.non_null_ptr.as_ptr();
263 let pre_commit_fn = unsafe { (*ptr).pre_commit_fn };
264 let name = unsafe { &(*ptr).name };
265 ag._index = i;
266 ag._name = name.clone();
267 if let Err(err) = pre_commit_fn(ptr, &mut ag).await {
268 errors.push(ErrEntry {
269 index: i,
270 name: name.clone(),
271 err,
272 });
273 break;
274 }
275 }
276 ag.join_and_collect_errors_async(&mut errors).await;
277
278 if !errors.is_empty() {
279 for ee in errors.iter() {
280 let report = &mut reports[ee.index];
281 report.cause = TxnFailureCause::LogicFailure(ee.err.clone());
282 }
283 return Err(errs::Err::new(DataConnError::FailToPreCommitDataConn {
284 errors,
285 }));
286 }
287
288 let mut ag = AsyncGroup::new();
289 for (i, ssnnptr) in self.vec.iter().flatten().enumerate() {
290 let ptr = ssnnptr.non_null_ptr.as_ptr();
291 let is_committed_fn = unsafe { (*ptr).is_committed_fn };
292 if is_committed_fn(ptr) {
293 continue;
296 }
297 let commit_fn = unsafe { (*ptr).commit_fn };
298 let name = unsafe { &(*ptr).name };
299 ag._index = i;
300 ag._name = name.clone();
301 if let Err(err) = commit_fn(ptr, &mut ag).await {
302 errors.push(ErrEntry {
303 index: i,
304 name: name.clone(),
305 err,
306 });
307 break;
308 }
309 }
310 ag.join_and_collect_errors_async(&mut errors).await;
311
312 if !errors.is_empty() {
313 for ee in errors.iter() {
314 let report = &mut reports[ee.index];
315 report.cause = TxnFailureCause::CommitFailure(ee.err.clone());
316 }
317 return Err(errs::Err::new(DataConnError::FailToCommitDataConn {
318 errors,
319 }));
320 }
321
322 self.committed = true;
323
324 let mut ag = AsyncGroup::new();
325 for (i, ssnnptr) in self.vec.iter().flatten().enumerate() {
326 let ptr = ssnnptr.non_null_ptr.as_ptr();
327 let post_commit_fn = unsafe { (*ptr).post_commit_fn };
328 let name = unsafe { &(*ptr).name };
329 ag._index = i;
330 ag._name = name.clone();
331 if let Err(err) = post_commit_fn(ptr, &mut ag).await {
332 errors.push(ErrEntry {
333 index: i,
334 name: name.clone(),
335 err,
336 });
337 }
339 }
340 ag.join_and_collect_errors_async(&mut errors).await;
341
342 if !errors.is_empty() {
343 for ee in errors.iter() {
344 let report = &mut reports[ee.index];
345 report.cause = TxnFailureCause::PostCommitFailure(ee.err.clone());
346 }
347 return Err(errs::Err::new(DataConnError::FailToPostCommitDataConn {
348 errors,
349 }));
350 }
351
352 Ok(())
353 }
354
355 pub(crate) async fn rollback_async(&mut self, mut reports: Vec<TxnFailureReport>) {
356 let mut errors = Vec::new();
357
358 let mut ag = AsyncGroup::new();
359 for (i, ssnnptr) in self.vec.iter().flatten().enumerate() {
360 let ptr = ssnnptr.non_null_ptr.as_ptr();
361 let report = &mut reports[i];
362 let is_committed_fn = unsafe { (*ptr).is_committed_fn };
363 if is_committed_fn(ptr) {
364 if let TxnFailureCause::NoneByUncommitted = report.cause {
365 report.cause = TxnFailureCause::NoneByCommitted;
366 }
367 continue;
368 }
369 if self.committed {
370 continue;
371 }
372 let rollback_fn = unsafe { (*ptr).rollback_fn };
373 let name = unsafe { &(*ptr).name };
374 ag._index = i;
375 ag._name = name.clone();
376 if let Err(err) = rollback_fn(ptr, &mut ag).await {
377 errors.push(ErrEntry {
378 index: i,
379 name: name.clone(),
380 err,
381 });
382 } else {
383 report.rollback = TxnFailureRollback::NoneByRolledBack;
384 }
385 }
386 ag.join_and_collect_errors_async(&mut errors).await;
387
388 if !errors.is_empty() {
389 for ee in errors.into_iter() {
390 let report = &mut reports[ee.index];
391 report.rollback = TxnFailureRollback::RollbackFailure(ee.err);
392 }
393 }
394
395 let reports: Arc<[TxnFailureReport]> = Arc::from(reports);
396
397 let mut ag = AsyncGroup::new();
398 for ssnnptr in self.vec.iter().flatten() {
399 let ptr = ssnnptr.non_null_ptr.as_ptr();
400 let on_txn_failure_fn = unsafe { (*ptr).on_txn_failure_fn };
401 on_txn_failure_fn(ptr, &mut ag, reports.clone()).await;
402 }
403 ag.join_and_ignore_errors_async().await;
404 }
405
406 pub(crate) fn close(&mut self) {
407 self.index_map.clear();
408
409 let vec: Vec<Option<SendSyncNonNull<DataConnContainer>>> = mem::take(&mut self.vec);
410 for ssnnptr in vec.iter().flatten().rev() {
411 let ptr = ssnnptr.non_null_ptr.as_ptr();
412 let close_fn = unsafe { (*ptr).close_fn };
413 let drop_fn = unsafe { (*ptr).drop_fn };
414 close_fn(ptr);
415 drop_fn(ptr);
416 }
417 }
418}
419
420impl Drop for DataConnManager {
421 fn drop(&mut self) {
422 self.close();
423 }
424}
425
426#[cfg_attr(coverage_nightly, coverage(off))]
427#[cfg(test)]
428mod tests_of_data_conn {
429 use super::*;
430 use std::ptr;
431 use std::sync::{
432 atomic::{AtomicBool, Ordering},
433 Arc, Mutex,
434 };
435 use tokio::time;
436
437 const BASE_LINE: u32 = line!();
438
439 #[derive(PartialEq, Copy, Clone)]
440 enum Fail {
441 Not,
442 Commit,
443 PreCommit,
444 PostCommit,
445 Rollback,
446 PreCommitBecomeCommitted,
447 }
448
449 struct SyncDataConn {
450 id: i8,
451 committed: AtomicBool,
452 fail: Fail,
453 logger: Arc<Mutex<Vec<String>>>,
454 }
455 impl SyncDataConn {
456 fn new(id: i8, logger: Arc<Mutex<Vec<String>>>, fail: Fail) -> Self {
457 logger
458 .lock()
459 .unwrap()
460 .push(format!("SyncDataConn::new {}", id));
461 Self {
462 id,
463 committed: AtomicBool::new(false),
464 fail,
465 logger,
466 }
467 }
468 }
469 impl Drop for SyncDataConn {
470 fn drop(&mut self) {
471 self.logger
472 .lock()
473 .unwrap()
474 .push(format!("SyncDataConn::drop {}", self.id));
475 }
476 }
477 impl DataConn for SyncDataConn {
478 async fn commit_async(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
479 let fail = self.fail;
480 let id = self.id;
481 let logger = self.logger.clone();
482 let committed = &self.committed;
483
484 if fail == Fail::Commit {
485 logger
486 .lock()
487 .unwrap()
488 .push(format!("SyncDataConn::commit {} failed", id));
489 return Err(errs::Err::new("ZZZ".to_string()));
490 }
491 committed.store(true, Ordering::Release);
492 logger
493 .lock()
494 .unwrap()
495 .push(format!("SyncDataConn::commit {}", id));
496 Ok(())
497 }
498 async fn pre_commit_async(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
499 let fail = self.fail;
500 let id = self.id;
501 let logger = self.logger.clone();
502
503 if fail == Fail::PreCommit {
504 logger
505 .lock()
506 .unwrap()
507 .push(format!("SyncDataConn::pre_commit {} failed", id));
508 return Err(errs::Err::new("zzz".to_string()));
509 }
510 logger
511 .lock()
512 .unwrap()
513 .push(format!("SyncDataConn::pre_commit {}", id));
514 Ok(())
515 }
516 async fn post_commit_async(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
517 let fail = self.fail;
518 let id = self.id;
519 let logger = self.logger.clone();
520
521 if fail == Fail::PostCommit {
522 logger
523 .lock()
524 .unwrap()
525 .push(format!("SyncDataConn::post_commit {} failed", id));
526 return Err(errs::Err::new("!!!".to_string()));
527 }
528 logger
529 .lock()
530 .unwrap()
531 .push(format!("SyncDataConn::post_commit {}", id));
532 Ok(())
533 }
534 fn is_committed(&self) -> bool {
535 self.committed.load(Ordering::Acquire)
536 }
537 async fn rollback_async(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
538 let fail = self.fail;
539 let id = self.id;
540 let logger = self.logger.clone();
541
542 if fail == Fail::Rollback {
543 logger
544 .lock()
545 .unwrap()
546 .push(format!("SyncDataConn::rollback {} failed", id));
547 return Err(errs::Err::new("!!!".to_string()));
548 }
549 logger
550 .lock()
551 .unwrap()
552 .push(format!("SyncDataConn::rollback {}", id));
553 Ok(())
554 }
555 async fn on_txn_failure_async(
556 &mut self,
557 _ag: &mut AsyncGroup,
558 reports: Arc<[TxnFailureReport]>,
559 ) {
560 let logger = self.logger.clone();
561 let mut logger = logger.lock().unwrap();
562 logger.push(format!("SyncDataConn::on_txn_failure {}", self.id));
563 logger.push(format!("TxnFailureReports={:?}", reports));
564 }
565 fn close(&mut self) {
566 self.logger
567 .lock()
568 .unwrap()
569 .push(format!("SyncDataConn::close {}", self.id));
570 }
571 }
572
573 struct AsyncDataConn {
574 id: i8,
575 committed: Arc<AtomicBool>,
576 fail: Fail,
577 logger: Arc<Mutex<Vec<String>>>,
578 }
579 impl AsyncDataConn {
580 fn new(id: i8, logger: Arc<Mutex<Vec<String>>>, fail: Fail) -> Self {
581 logger
582 .lock()
583 .unwrap()
584 .push(format!("AsyncDataConn::new {}", id));
585 Self {
586 id,
587 committed: Arc::new(AtomicBool::new(false)),
588 fail,
589 logger,
590 }
591 }
592 }
593 impl Drop for AsyncDataConn {
594 fn drop(&mut self) {
595 self.logger
596 .lock()
597 .unwrap()
598 .push(format!("AsyncDataConn::drop {}", self.id));
599 }
600 }
601 impl DataConn for AsyncDataConn {
602 async fn commit_async(&mut self, ag: &mut AsyncGroup) -> errs::Result<()> {
603 let fail = self.fail;
604 let id = self.id;
605 let logger = self.logger.clone();
606 let committed = self.committed.clone();
607 ag.add(async move {
608 time::sleep(time::Duration::from_millis(100)).await;
609 if fail == Fail::Commit {
610 logger
611 .lock()
612 .unwrap()
613 .push(format!("AsyncDataConn::commit {} failed", id));
614 return Err(errs::Err::new("YYY".to_string()));
615 }
616 committed.store(true, Ordering::Release);
617 logger
618 .lock()
619 .unwrap()
620 .push(format!("AsyncDataConn::commit {}", id));
621 Ok(())
622 });
623 Ok(())
624 }
625 async fn pre_commit_async(&mut self, ag: &mut AsyncGroup) -> errs::Result<()> {
626 let fail = self.fail;
627 let id = self.id;
628 let logger = self.logger.clone();
629 ag.add(async move {
630 time::sleep(time::Duration::from_millis(100)).await;
631 if fail == Fail::PreCommit {
632 logger
633 .lock()
634 .unwrap()
635 .push(format!("AsyncDataConn::pre_commit {} failed", id));
636 return Err(errs::Err::new("yyy".to_string()));
637 }
638 logger
639 .lock()
640 .unwrap()
641 .push(format!("AsyncDataConn::pre_commit {}", id));
642 Ok(())
643 });
644 Ok(())
645 }
646 async fn post_commit_async(&mut self, ag: &mut AsyncGroup) -> errs::Result<()> {
647 let logger = self.logger.clone();
648 let id = self.id;
649 let fail = self.fail;
650 ag.add(async move {
651 time::sleep(time::Duration::from_millis(100)).await;
652 if fail == Fail::PostCommit {
653 logger
654 .lock()
655 .unwrap()
656 .push(format!("AsyncDataConn::post_commit {} failed", id));
657 return Err(errs::Err::new("!!!".to_string()));
658 }
659 logger
660 .lock()
661 .unwrap()
662 .push(format!("AsyncDataConn::post_commit {}", id));
663 Ok(())
664 });
665 Ok(())
666 }
667 fn is_committed(&self) -> bool {
668 self.committed.load(Ordering::Acquire)
669 }
670 async fn rollback_async(&mut self, ag: &mut AsyncGroup) -> errs::Result<()> {
671 let logger = self.logger.clone();
672 let id = self.id;
673 let fail = self.fail;
674 ag.add(async move {
675 time::sleep(time::Duration::from_millis(100)).await;
676 if fail == Fail::Rollback {
677 logger
678 .lock()
679 .unwrap()
680 .push(format!("AsyncDataConn::rollback {} failed", id));
681 return Err(errs::Err::new("???".to_string()));
682 }
683 logger
684 .lock()
685 .unwrap()
686 .push(format!("AsyncDataConn::rollback {}", id));
687 Ok(())
688 });
689 Ok(())
690 }
691 async fn on_txn_failure_async(
692 &mut self,
693 ag: &mut AsyncGroup,
694 reports: Arc<[TxnFailureReport]>,
695 ) {
696 let reports_log = format!("TxnFailureReports={:?}", reports);
697 let logger = self.logger.clone();
698 let id = self.id;
699 ag.add(async move {
700 time::sleep(time::Duration::from_millis(100)).await;
701 let mut logger = logger.lock().unwrap();
702 logger.push(format!("AsyncDataConn::on_txn_failure {}", id));
703 logger.push(reports_log);
704 Ok(())
705 });
706 }
707 fn close(&mut self) {
708 self.logger
709 .lock()
710 .unwrap()
711 .push(format!("AsyncDataConn::close {}", self.id));
712 }
713 }
714
715 struct NoCommitDataConn {
716 id: i8,
717 logger: Arc<Mutex<Vec<String>>>,
718 }
719 impl NoCommitDataConn {
720 fn new(id: i8, logger: Arc<Mutex<Vec<String>>>) -> Self {
721 logger
722 .lock()
723 .unwrap()
724 .push(format!("NoCommitDataConn::new {}", id));
725 Self { id, logger }
726 }
727 }
728 impl Drop for NoCommitDataConn {
729 fn drop(&mut self) {
730 self.logger
731 .lock()
732 .unwrap()
733 .push(format!("NoCommitDataConn::drop {}", self.id));
734 }
735 }
736 impl DataConn for NoCommitDataConn {
737 async fn commit_async(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
738 self.logger
739 .lock()
740 .unwrap()
741 .push(format!("NoCommitDataConn::commit {}", self.id));
742 Ok(())
743 }
744 async fn pre_commit_async(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
745 self.logger
746 .lock()
747 .unwrap()
748 .push(format!("NoCommitDataConn::pre_commit {}", self.id));
749 Ok(())
750 }
751 async fn post_commit_async(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
752 self.logger
753 .lock()
754 .unwrap()
755 .push(format!("NoCommitDataConn::post_commit {}", self.id));
756 Ok(())
757 }
758 fn is_committed(&self) -> bool {
759 false
760 }
761 async fn rollback_async(&mut self, _ag: &mut AsyncGroup) -> errs::Result<()> {
762 self.logger
763 .lock()
764 .unwrap()
765 .push(format!("NoCommitDataConn::rollback {}", self.id));
766 Ok(())
767 }
768 async fn on_txn_failure_async(
769 &mut self,
770 _ag: &mut AsyncGroup,
771 reports: Arc<[TxnFailureReport]>,
772 ) {
773 let logger = self.logger.clone();
774 let mut logger = logger.lock().unwrap();
775 logger.push(format!("NoCommitDataConn::on_txn_failure {}", self.id));
776 logger.push(format!("TxnFailureReports={:?}", reports));
777 }
778 fn close(&mut self) {
779 self.logger
780 .lock()
781 .unwrap()
782 .push(format!("NoCommitDataConn::close {}", self.id));
783 }
784 }
785
786 mod tests_of_data_conn_manager {
787 use super::*;
788 use std::panic::panic_any;
789
790 #[tokio::test]
791 async fn test_new() {
792 let manager = DataConnManager::new();
793 assert!(manager.vec.is_empty());
794 assert!(manager.index_map.is_empty());
795 }
796
797 #[tokio::test]
798 async fn test_with_commit_order() {
799 let manager = DataConnManager::with_commit_order(&["bar", "baz", "foo"]);
800 assert_eq!(manager.vec.len(), 3);
801 assert!(manager.vec[0].is_none());
802 assert!(manager.vec[1].is_none());
803 assert!(manager.vec[2].is_none());
804 assert_eq!(manager.index_map.len(), 3);
805 assert_eq!(*manager.index_map.get("foo").unwrap(), 2);
806 assert_eq!(*manager.index_map.get("bar").unwrap(), 0);
807 assert_eq!(*manager.index_map.get("baz").unwrap(), 1);
808 }
809
810 #[test]
811 fn test_new_and_add() {
812 let logger = Arc::new(Mutex::new(Vec::new()));
813
814 let mut manager = DataConnManager::new();
815 assert!(manager.vec.is_empty());
816 assert!(manager.index_map.is_empty());
817
818 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
819 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
820 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
821 let ssnnptr = SendSyncNonNull::new(nnptr);
822 manager.add(ssnnptr);
823 assert_eq!(manager.vec.len(), 1);
824 assert_eq!(manager.index_map.len(), 1);
825 assert_eq!(*manager.index_map.get("foo").unwrap(), 0);
826
827 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
828 let boxed = Box::new(DataConnContainer::new("bar".to_string(), Box::new(conn)));
829 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
830 let ssnnptr = SendSyncNonNull::new(nnptr);
831 manager.add(ssnnptr);
832 assert_eq!(manager.vec.len(), 2);
833 assert_eq!(manager.index_map.len(), 2);
834 assert_eq!(*manager.index_map.get("foo").unwrap(), 0);
835 assert_eq!(*manager.index_map.get("bar").unwrap(), 1);
836 }
837
838 #[test]
839 fn test_new_and_add_when_overlapping_name() {
840 let logger = Arc::new(Mutex::new(Vec::new()));
841
842 let mut manager = DataConnManager::new();
843 assert!(manager.vec.is_empty());
844 assert!(manager.index_map.is_empty());
845
846 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
847 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
848 let nnptr0 = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
849 let ssnnptr = SendSyncNonNull::new(nnptr0);
850 manager.add(ssnnptr);
851 assert_eq!(manager.vec.len(), 1);
852 assert_eq!(manager.index_map.len(), 1);
853 assert_eq!(*manager.index_map.get("foo").unwrap(), 0);
854 assert_eq!(manager.vec[0].clone().unwrap().non_null_ptr, nnptr0);
855
856 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
857 let boxed = Box::new(DataConnContainer::new("foo".to_string(), Box::new(conn)));
858 let nnptr1 = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
859 let ssnnptr = SendSyncNonNull::new(nnptr1);
860 manager.add(ssnnptr);
861 assert_eq!(manager.vec.len(), 1);
862 assert_eq!(manager.index_map.len(), 1);
863 assert_eq!(*manager.index_map.get("foo").unwrap(), 0);
864 assert_eq!(manager.vec[0].clone().unwrap().non_null_ptr, nnptr0);
865 }
866
867 #[test]
868 fn test_with_commit_order_and_add() {
869 let logger = Arc::new(Mutex::new(Vec::new()));
870
871 let mut manager = DataConnManager::with_commit_order(&["bar", "baz", "foo"]);
872 assert_eq!(manager.vec.len(), 3);
873 assert!(manager.vec[0].is_none());
874 assert!(manager.vec[1].is_none());
875 assert!(manager.vec[2].is_none());
876 assert_eq!(manager.index_map.len(), 3);
877 assert_eq!(*manager.index_map.get("foo").unwrap(), 2);
878 assert_eq!(*manager.index_map.get("bar").unwrap(), 0);
879 assert_eq!(*manager.index_map.get("baz").unwrap(), 1);
880
881 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
882 let boxed = Box::new(DataConnContainer::new("foo".to_string(), Box::new(conn)));
883 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
884 let ssnnptr = SendSyncNonNull::new(nnptr);
885 manager.add(ssnnptr);
886 assert_eq!(manager.vec.len(), 3);
887 assert_eq!(manager.index_map.len(), 3);
888 assert_eq!(*manager.index_map.get("foo").unwrap(), 2);
889
890 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
891 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
892 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
893 let ssnnptr = SendSyncNonNull::new(nnptr);
894 manager.add(ssnnptr);
895 assert_eq!(manager.vec.len(), 3);
896 assert_eq!(manager.index_map.len(), 3);
897 assert_eq!(*manager.index_map.get("foo").unwrap(), 2);
898 assert_eq!(*manager.index_map.get("bar").unwrap(), 0);
899
900 let conn = SyncDataConn::new(3, logger.clone(), Fail::Not);
901 let boxed = Box::new(DataConnContainer::new("qux", Box::new(conn)));
902 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
903 let ssnnptr = SendSyncNonNull::new(nnptr);
904 manager.add(ssnnptr);
905 assert_eq!(manager.vec.len(), 4);
906 assert_eq!(manager.index_map.len(), 4);
907 assert_eq!(*manager.index_map.get("foo").unwrap(), 2);
908 assert_eq!(*manager.index_map.get("bar").unwrap(), 0);
909 assert_eq!(*manager.index_map.get("qux").unwrap(), 3);
910 }
911
912 #[test]
913 fn test_with_order_and_add_when_overlapping_name() {
914 let logger = Arc::new(Mutex::new(Vec::new()));
915
916 let mut manager = DataConnManager::with_commit_order(&["bar", "baz", "foo"]);
917 assert_eq!(manager.vec.len(), 3);
918 assert!(manager.vec[0].is_none());
919 assert!(manager.vec[1].is_none());
920 assert!(manager.vec[2].is_none());
921 assert_eq!(manager.index_map.len(), 3);
922
923 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
924 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
925 let nnptr0 = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
926 let ssnnptr = SendSyncNonNull::new(nnptr0);
927 manager.add(ssnnptr);
928 assert_eq!(manager.vec.len(), 3);
929 assert_eq!(manager.index_map.len(), 3);
930 assert_eq!(*manager.index_map.get("foo").unwrap(), 2);
931 assert_eq!(manager.vec[2].clone().unwrap().non_null_ptr, nnptr0);
932
933 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
934 let boxed = Box::new(DataConnContainer::new("foo".to_string(), Box::new(conn)));
935 let nnptr1 = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
936 let ssnnptr = SendSyncNonNull::new(nnptr1);
937 manager.add(ssnnptr);
938 assert_eq!(manager.vec.len(), 3);
939 assert_eq!(manager.index_map.len(), 3);
940 assert_eq!(*manager.index_map.get("foo").unwrap(), 2);
941 assert_eq!(manager.vec[2].clone().unwrap().non_null_ptr, nnptr0);
942 }
943
944 #[test]
945 fn test_find_by_name_but_none() {
946 let manager = DataConnManager::new();
947 assert!(manager.find_by_name("foo").is_none());
948 assert!(manager.find_by_name("bar").is_none());
949 }
950
951 #[test]
952 fn test_find_by_name_and_found() {
953 let logger = Arc::new(Mutex::new(Vec::new()));
954
955 let mut manager = DataConnManager::new();
956
957 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
958 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
959 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
960 let ssnnptr = SendSyncNonNull::new(nnptr);
961 manager.add(ssnnptr);
962
963 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
964 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
965 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
966 let ssnnptr = SendSyncNonNull::new(nnptr);
967 manager.add(ssnnptr);
968
969 if let Some(ssnnptr) = manager.find_by_name("foo") {
970 let name = unsafe { (*ssnnptr.non_null_ptr.as_ptr()).name.clone() };
971 assert_eq!(name.as_ref(), "foo");
972 } else {
973 panic!();
974 }
975
976 if let Some(ssnnptr) = manager.find_by_name("bar") {
977 let name = unsafe { (*ssnnptr.non_null_ptr.as_ptr()).name.clone() };
978 assert_eq!(name.as_ref(), "bar");
979 } else {
980 panic!();
981 }
982 }
983
984 #[test]
985 fn test_find_by_name_of_ordered_dataconn() {
986 let logger = Arc::new(Mutex::new(Vec::new()));
987
988 let mut manager = DataConnManager::with_commit_order(&["baz", "qux", "foo"]);
989
990 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
991 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
992 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
993 let ssnnptr = SendSyncNonNull::new(nnptr);
994 manager.add(ssnnptr);
995
996 let conn = SyncDataConn::new(2, logger.clone(), Fail::Not);
997 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
998 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
999 let ssnnptr = SendSyncNonNull::new(nnptr);
1000 manager.add(ssnnptr);
1001
1002 let conn = SyncDataConn::new(3, logger.clone(), Fail::Not);
1003 let boxed = Box::new(DataConnContainer::new("baz", Box::new(conn)));
1004 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1005 let ssnnptr = SendSyncNonNull::new(nnptr);
1006 manager.add(ssnnptr);
1007
1008 if let Some(ssnnptr) = manager.find_by_name("foo") {
1009 let name = unsafe { (*ssnnptr.non_null_ptr.as_ptr()).name.clone() };
1010 assert_eq!(name.as_ref(), "foo");
1011 } else {
1012 panic!();
1013 }
1014
1015 if let Some(ssnnptr) = manager.find_by_name("bar") {
1016 let name = unsafe { (*ssnnptr.non_null_ptr.as_ptr()).name.clone() };
1017 assert_eq!(name.as_ref(), "bar");
1018 } else {
1019 panic!();
1020 }
1021
1022 if let Some(ssnnptr) = manager.find_by_name("baz") {
1023 let name = unsafe { (*ssnnptr.non_null_ptr.as_ptr()).name.clone() };
1024 assert_eq!(name.as_ref(), "baz");
1025 } else {
1026 panic!();
1027 }
1028
1029 assert!(manager.find_by_name("qux").is_none());
1030 }
1031
1032 #[test]
1033 fn test_to_typed_ptr() {
1034 let logger = Arc::new(Mutex::new(Vec::new()));
1035
1036 let mut manager = DataConnManager::new();
1037
1038 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
1039 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1040 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1041 let ssnnptr = SendSyncNonNull::new(nnptr);
1042 manager.add(ssnnptr);
1043
1044 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
1045 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1046 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1047 let ssnnptr = SendSyncNonNull::new(nnptr);
1048 manager.add(ssnnptr);
1049
1050 let nnptr = manager.find_by_name("foo").unwrap();
1051 if let Ok(typed_nnptr) = DataConnManager::to_typed_ptr::<SyncDataConn>(&nnptr) {
1052 assert_eq!(any::type_name_of_val(&typed_nnptr), "*mut sabi::tokio::DataConnContainer<sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn>");
1053 assert_eq!(unsafe { (*typed_nnptr).name.clone() }, "foo".into());
1054 } else {
1055 panic!();
1056 }
1057
1058 let nnptr = manager.find_by_name("bar").unwrap();
1059 if let Ok(typed_nnptr) = DataConnManager::to_typed_ptr::<AsyncDataConn>(&nnptr) {
1060 assert_eq!(any::type_name_of_val(&typed_nnptr), "*mut sabi::tokio::DataConnContainer<sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn>");
1061 assert_eq!(unsafe { (*typed_nnptr).name.clone() }, "bar".into());
1062 } else {
1063 panic!();
1064 }
1065 }
1066
1067 #[test]
1068 fn test_to_typed_ptr_but_fail() {
1069 let logger = Arc::new(Mutex::new(Vec::new()));
1070
1071 let mut manager = DataConnManager::new();
1072
1073 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
1074 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1075 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1076 let ssnnptr = SendSyncNonNull::new(nnptr);
1077 manager.add(ssnnptr);
1078
1079 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
1080 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1081 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1082 let ssnnptr = SendSyncNonNull::new(nnptr);
1083 manager.add(ssnnptr);
1084
1085 let ssnnptr = manager.find_by_name("foo").unwrap();
1086 if let Err(err) = DataConnManager::to_typed_ptr::<AsyncDataConn>(&ssnnptr) {
1087 match err.reason::<DataConnError>() {
1088 Ok(DataConnError::FailToCastDataConn { name, target_type }) => {
1089 assert_eq!(name.as_ref(), "foo");
1090 assert_eq!(
1091 *target_type,
1092 "sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn"
1093 );
1094 }
1095 _ => panic!(),
1096 }
1097 } else {
1098 panic!();
1099 }
1100
1101 let ssnnptr = manager.find_by_name("bar").unwrap();
1102 if let Err(err) = DataConnManager::to_typed_ptr::<SyncDataConn>(&ssnnptr) {
1103 match err.reason::<DataConnError>() {
1104 Ok(DataConnError::FailToCastDataConn { name, target_type }) => {
1105 assert_eq!(name.as_ref(), "bar");
1106 assert_eq!(
1107 *target_type,
1108 "sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn"
1109 );
1110 }
1111 _ => panic!(),
1112 }
1113 } else {
1114 panic!();
1115 }
1116 }
1117
1118 #[test]
1119 fn test_new_failure_reports() {
1120 let logger = Arc::new(Mutex::new(Vec::new()));
1121
1122 let mut manager = DataConnManager::new();
1123
1124 let vec = manager.new_failure_reports();
1125 assert_eq!(vec.len(), 0);
1126
1127 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
1128 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1129 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1130 let ssnnptr = SendSyncNonNull::new(nnptr);
1131 manager.add(ssnnptr);
1132
1133 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
1134 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1135 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1136 let ssnnptr = SendSyncNonNull::new(nnptr);
1137 manager.add(ssnnptr);
1138
1139 let vec = manager.new_failure_reports();
1140 assert_eq!(vec.len(), 2);
1141
1142 let report = &vec[0];
1143 assert_eq!(report.data_conn_name, "foo".into());
1144 assert_eq!(
1145 report.data_conn_type,
1146 "sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn"
1147 );
1148
1149 let report = &vec[1];
1150 assert_eq!(report.data_conn_name, "bar".into());
1151 assert_eq!(
1152 report.data_conn_type,
1153 "sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn"
1154 );
1155 }
1156
1157 #[tokio::test]
1158 async fn test_commit_and_rollback_ok() {
1159 let logger = Arc::new(Mutex::new(Vec::new()));
1160
1161 {
1162 let mut manager = DataConnManager::new();
1163
1164 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
1165 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1166 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1167 let ssnnptr = SendSyncNonNull::new(nnptr);
1168 manager.add(ssnnptr);
1169
1170 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
1171 let boxed = Box::new(DataConnContainer::new("bar".to_string(), Box::new(conn)));
1172 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1173 let ssnnptr = SendSyncNonNull::new(nnptr);
1174 manager.add(ssnnptr);
1175
1176 let mut reports = manager.new_failure_reports();
1177 assert!(manager.commit_async(&mut reports).await.is_ok());
1178 manager.rollback_async(reports).await;
1179 }
1180
1181 assert_eq!(
1182 *logger.lock().unwrap(),
1183 &[
1184 "SyncDataConn::new 1",
1185 "AsyncDataConn::new 2",
1186 "SyncDataConn::pre_commit 1",
1187 "AsyncDataConn::pre_commit 2",
1188 "SyncDataConn::commit 1",
1189 "AsyncDataConn::commit 2",
1190 "SyncDataConn::post_commit 1",
1191 "AsyncDataConn::post_commit 2",
1192 "SyncDataConn::on_txn_failure 1",
1193 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]"),
1194 "AsyncDataConn::on_txn_failure 2",
1195 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]"),
1196 "AsyncDataConn::close 2",
1197 "AsyncDataConn::drop 2",
1198 "SyncDataConn::close 1",
1199 "SyncDataConn::drop 1",
1200 ]
1201 );
1202 }
1203
1204 #[tokio::test]
1205 async fn test_commit_with_order_and_rollback_ok() {
1206 let logger = Arc::new(Mutex::new(Vec::new()));
1207
1208 {
1209 let mut manager = DataConnManager::with_commit_order(&["bar", "baz", "foo"]);
1210
1211 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
1212 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1213 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1214 let ssnnptr = SendSyncNonNull::new(nnptr);
1215 manager.add(ssnnptr);
1216
1217 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
1218 let boxed = Box::new(DataConnContainer::new("bar".to_string(), Box::new(conn)));
1219 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1220 let ssnnptr = SendSyncNonNull::new(nnptr);
1221 manager.add(ssnnptr);
1222
1223 let conn = SyncDataConn::new(3, logger.clone(), Fail::Not);
1224 let boxed = Box::new(DataConnContainer::new("qux", Box::new(conn)));
1225 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1226 let ssnnptr = SendSyncNonNull::new(nnptr);
1227 manager.add(ssnnptr);
1228
1229 let mut reports = manager.new_failure_reports();
1230 assert!(manager.commit_async(&mut reports).await.is_ok());
1231 manager.rollback_async(reports).await;
1232 }
1233
1234 assert_eq!(
1235 *logger.lock().unwrap(),
1236 &[
1237 "SyncDataConn::new 1",
1238 "AsyncDataConn::new 2",
1239 "SyncDataConn::new 3",
1240 "SyncDataConn::pre_commit 1",
1241 "SyncDataConn::pre_commit 3",
1242 "AsyncDataConn::pre_commit 2",
1243 "SyncDataConn::commit 1",
1244 "SyncDataConn::commit 3",
1245 "AsyncDataConn::commit 2",
1246 "SyncDataConn::post_commit 1",
1247 "SyncDataConn::post_commit 3",
1248 "AsyncDataConn::post_commit 2",
1249 "SyncDataConn::on_txn_failure 1",
1250 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"qux\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]"),
1251 "SyncDataConn::on_txn_failure 3",
1252 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"qux\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]"),
1253 "AsyncDataConn::on_txn_failure 2",
1254 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"qux\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]"),
1255 "SyncDataConn::close 3",
1256 "SyncDataConn::drop 3",
1257 "SyncDataConn::close 1",
1258 "SyncDataConn::drop 1",
1259 "AsyncDataConn::close 2",
1260 "AsyncDataConn::drop 2",
1261 ]
1262 );
1263 }
1264
1265 #[tokio::test]
1266 async fn test_commit_and_rollback_but_fail_first_sync_pre_commit() {
1267 let logger = Arc::new(Mutex::new(Vec::new()));
1268
1269 {
1270 let mut manager = DataConnManager::new();
1271
1272 let conn = SyncDataConn::new(1, logger.clone(), Fail::PreCommit);
1273 let boxed = Box::new(DataConnContainer::new("foo".to_string(), Box::new(conn)));
1274 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1275 let ssnnptr = SendSyncNonNull::new(nnptr);
1276 manager.add(ssnnptr);
1277
1278 let conn = AsyncDataConn::new(2, logger.clone(), Fail::PreCommit);
1279 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1280 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1281 let ssnnptr = SendSyncNonNull::new(nnptr);
1282 manager.add(ssnnptr);
1283
1284 let mut reports = manager.new_failure_reports();
1285 if let Err(e) = manager.commit_async(&mut reports).await {
1286 match e.reason::<DataConnError>() {
1287 Ok(DataConnError::FailToPreCommitDataConn { errors }) => {
1288 assert_eq!(errors.len(), 1);
1289 assert_eq!(errors[0].index, 0);
1290 assert_eq!(errors[0].name, "foo".into());
1291 assert_eq!(errors[0].err.reason::<String>().unwrap(), "zzz");
1292 }
1293 _ => panic!(),
1294 }
1295 } else {
1296 panic!();
1297 }
1298 manager.rollback_async(reports).await;
1299 }
1300
1301 #[cfg(unix)]
1302 assert_eq!(
1303 *logger.lock().unwrap(),
1304 &[
1305 "SyncDataConn::new 1",
1306 "AsyncDataConn::new 2",
1307 "SyncDataConn::pre_commit 1 failed",
1308 "SyncDataConn::rollback 1",
1309 "AsyncDataConn::rollback 2",
1310 "SyncDataConn::on_txn_failure 1",
1311 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"zzz\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 71),
1312 "AsyncDataConn::on_txn_failure 2",
1313 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"zzz\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 71),
1314 "AsyncDataConn::close 2",
1315 "AsyncDataConn::drop 2",
1316 "SyncDataConn::close 1",
1317 "SyncDataConn::drop 1",
1318 ]
1319 );
1320 #[cfg(windows)]
1321 assert_eq!(
1322 *logger.lock().unwrap(),
1323 &[
1324 "SyncDataConn::new 1",
1325 "AsyncDataConn::new 2",
1326 "SyncDataConn::pre_commit 1 failed",
1327 "SyncDataConn::rollback 1",
1328 "AsyncDataConn::rollback 2",
1329 "SyncDataConn::on_txn_failure 1",
1330 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"zzz\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 71),
1331 "AsyncDataConn::on_txn_failure 2",
1332 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"zzz\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 71),
1333 "AsyncDataConn::close 2",
1334 "AsyncDataConn::drop 2",
1335 "SyncDataConn::close 1",
1336 "SyncDataConn::drop 1",
1337 ]
1338 );
1339 }
1340
1341 #[tokio::test]
1342 async fn test_commit_and_rollback_but_fail_first_async_pre_commit() {
1343 let logger = Arc::new(Mutex::new(Vec::new()));
1344
1345 {
1346 let mut manager = DataConnManager::new();
1347
1348 let conn = SyncDataConn::new(1, logger.clone(), Fail::PreCommit);
1349 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1350 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1351 let ssnnptr = SendSyncNonNull::new(nnptr);
1352 manager.add(ssnnptr);
1353
1354 let conn = AsyncDataConn::new(2, logger.clone(), Fail::PreCommit);
1355 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1356 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1357 let ssnnptr = SendSyncNonNull::new(nnptr);
1358 manager.add(ssnnptr);
1359
1360 let mut reports = manager.new_failure_reports();
1361 if let Err(e) = manager.commit_async(&mut reports).await {
1362 match e.reason::<DataConnError>() {
1363 Ok(DataConnError::FailToPreCommitDataConn { errors }) => {
1364 assert_eq!(errors.len(), 1);
1365 assert_eq!(errors[0].index, 0);
1366 assert_eq!(errors[0].name, "foo".into());
1367 assert_eq!(errors[0].err.reason::<String>().unwrap(), "zzz");
1368 }
1369 _ => panic!(),
1370 }
1371 } else {
1372 panic!();
1373 }
1374 manager.rollback_async(reports).await;
1375 }
1376
1377 #[cfg(unix)]
1378 assert_eq!(*logger.lock().unwrap(), &[
1379 "SyncDataConn::new 1",
1380 "AsyncDataConn::new 2",
1381 "SyncDataConn::pre_commit 1 failed",
1382 "SyncDataConn::rollback 1",
1383 "AsyncDataConn::rollback 2",
1384 "SyncDataConn::on_txn_failure 1",
1385 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"zzz\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 71),
1386 "AsyncDataConn::on_txn_failure 2",
1387 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"zzz\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 71),
1388 "AsyncDataConn::close 2",
1389 "AsyncDataConn::drop 2",
1390 "SyncDataConn::close 1",
1391 "SyncDataConn::drop 1",
1392 ]);
1393 #[cfg(windows)]
1394 assert_eq!(*logger.lock().unwrap(), &[
1395 "SyncDataConn::new 1",
1396 "AsyncDataConn::new 2",
1397 "SyncDataConn::pre_commit 1 failed",
1398 "SyncDataConn::rollback 1",
1399 "AsyncDataConn::rollback 2",
1400 "SyncDataConn::on_txn_failure 1",
1401 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"zzz\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 71),
1402 "AsyncDataConn::on_txn_failure 2",
1403 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"zzz\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 71),
1404 "AsyncDataConn::close 2",
1405 "AsyncDataConn::drop 2",
1406 "SyncDataConn::close 1",
1407 "SyncDataConn::drop 1",
1408 ]);
1409 }
1410
1411 #[tokio::test]
1412 async fn test_commit_and_rollback_but_fail_second_pre_commit() {
1413 let logger = Arc::new(Mutex::new(Vec::new()));
1414
1415 {
1416 let mut manager = DataConnManager::new();
1417
1418 let conn = AsyncDataConn::new(1, logger.clone(), Fail::PreCommit);
1419 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1420 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1421 let ssnnptr = SendSyncNonNull::new(nnptr);
1422 manager.add(ssnnptr);
1423
1424 let conn = SyncDataConn::new(2, logger.clone(), Fail::Not);
1425 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1426 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1427 let ssnnptr = SendSyncNonNull::new(nnptr);
1428 manager.add(ssnnptr);
1429
1430 let mut reports = manager.new_failure_reports();
1431 if let Err(e) = manager.commit_async(&mut reports).await {
1432 match e.reason::<DataConnError>() {
1433 Ok(DataConnError::FailToPreCommitDataConn { errors }) => {
1434 assert_eq!(errors.len(), 1);
1435 assert_eq!(errors[0].index, 0);
1436 assert_eq!(errors[0].name, "foo".into());
1437 assert_eq!(errors[0].err.reason::<String>().unwrap(), "yyy");
1438 }
1439 _ => panic!(),
1440 }
1441 } else {
1442 panic!();
1443 }
1444 manager.rollback_async(reports).await;
1445 }
1446
1447 assert_eq!(
1448 *logger.lock().unwrap(),
1449 &[
1450 "AsyncDataConn::new 1",
1451 "SyncDataConn::new 2",
1452 "SyncDataConn::pre_commit 2",
1453 "AsyncDataConn::pre_commit 1 failed",
1454 "SyncDataConn::rollback 2",
1455 "AsyncDataConn::rollback 1",
1456 "SyncDataConn::on_txn_failure 2",
1457 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"yyy\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 199),
1458 "AsyncDataConn::on_txn_failure 1",
1459 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: LogicFailure(errs::Err {{ reason = alloc::string::String \"yyy\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 199),
1460 "SyncDataConn::close 2",
1461 "SyncDataConn::drop 2",
1462 "AsyncDataConn::close 1",
1463 "AsyncDataConn::drop 1",
1464 ]
1465 );
1466 }
1467
1468 #[tokio::test]
1469 async fn test_commit_and_rollback_but_fail_first_sync_commit() {
1470 let logger = Arc::new(Mutex::new(Vec::new()));
1471
1472 {
1473 let mut manager = DataConnManager::new();
1474
1475 let conn = SyncDataConn::new(1, logger.clone(), Fail::Commit);
1476 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1477 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1478 let ssnnptr = SendSyncNonNull::new(nnptr);
1479 manager.add(ssnnptr);
1480
1481 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Commit);
1482 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1483 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1484 let ssnnptr = SendSyncNonNull::new(nnptr);
1485 manager.add(ssnnptr);
1486
1487 let mut reports = manager.new_failure_reports();
1488 if let Err(e) = manager.commit_async(&mut reports).await {
1489 match e.reason::<DataConnError>() {
1490 Ok(DataConnError::FailToCommitDataConn { errors }) => {
1491 assert_eq!(errors.len(), 1);
1492 assert_eq!(errors[0].index, 0);
1493 assert_eq!(errors[0].name, "foo".into());
1494 assert_eq!(errors[0].err.reason::<String>().unwrap(), "ZZZ");
1495 }
1496 _ => panic!(),
1497 }
1498 } else {
1499 panic!();
1500 }
1501 manager.rollback_async(reports).await;
1502 }
1503
1504 #[cfg(unix)]
1505 assert_eq!(
1506 *logger.lock().unwrap(),
1507 &[
1508 "SyncDataConn::new 1",
1509 "AsyncDataConn::new 2",
1510 "SyncDataConn::pre_commit 1",
1511 "AsyncDataConn::pre_commit 2",
1512 "SyncDataConn::commit 1 failed",
1513 "SyncDataConn::rollback 1",
1514 "AsyncDataConn::rollback 2",
1515 "SyncDataConn::on_txn_failure 1",
1516 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"ZZZ\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 52),
1517 "AsyncDataConn::on_txn_failure 2",
1518 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"ZZZ\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 52),
1519 "AsyncDataConn::close 2",
1520 "AsyncDataConn::drop 2",
1521 "SyncDataConn::close 1",
1522 "SyncDataConn::drop 1",
1523 ]
1524 );
1525 #[cfg(windows)]
1526 assert_eq!(
1527 *logger.lock().unwrap(),
1528 &[
1529 "SyncDataConn::new 1",
1530 "AsyncDataConn::new 2",
1531 "SyncDataConn::pre_commit 1",
1532 "AsyncDataConn::pre_commit 2",
1533 "SyncDataConn::commit 1 failed",
1534 "SyncDataConn::rollback 1",
1535 "AsyncDataConn::rollback 2",
1536 "SyncDataConn::on_txn_failure 1",
1537 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"ZZZ\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 52),
1538 "AsyncDataConn::on_txn_failure 2",
1539 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"ZZZ\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 52),
1540 "AsyncDataConn::close 2",
1541 "AsyncDataConn::drop 2",
1542 "SyncDataConn::close 1",
1543 "SyncDataConn::drop 1",
1544 ]
1545 );
1546 }
1547
1548 #[tokio::test]
1549 async fn test_commit_and_rollback_but_fail_first_async_commit() {
1550 let logger = Arc::new(Mutex::new(Vec::new()));
1551
1552 {
1553 let mut manager = DataConnManager::new();
1554
1555 let conn = AsyncDataConn::new(1, logger.clone(), Fail::Commit);
1556 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1557 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1558 let ssnnptr = SendSyncNonNull::new(nnptr);
1559 manager.add(ssnnptr);
1560
1561 let conn = SyncDataConn::new(2, logger.clone(), Fail::Not);
1562 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1563 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1564 let ssnnptr = SendSyncNonNull::new(nnptr);
1565 manager.add(ssnnptr);
1566
1567 let mut reports = manager.new_failure_reports();
1568 if let Err(e) = manager.commit_async(&mut reports).await {
1569 match e.reason::<DataConnError>() {
1570 Ok(DataConnError::FailToCommitDataConn { errors }) => {
1571 assert_eq!(errors.len(), 1);
1572 assert_eq!(errors[0].index, 0);
1573 assert_eq!(errors[0].name, "foo".into());
1574 assert_eq!(errors[0].err.reason::<String>().unwrap(), "YYY");
1575 }
1576 _ => panic!(),
1577 }
1578 } else {
1579 panic!();
1580 }
1581 manager.rollback_async(reports).await;
1582 }
1583
1584 #[cfg(unix)]
1585 assert_eq!(
1586 *logger.lock().unwrap(),
1587 &[
1588 "AsyncDataConn::new 1",
1589 "SyncDataConn::new 2",
1590 "SyncDataConn::pre_commit 2",
1591 "AsyncDataConn::pre_commit 1",
1592 "SyncDataConn::commit 2",
1593 "AsyncDataConn::commit 1 failed",
1594 "AsyncDataConn::rollback 1",
1595 "SyncDataConn::on_txn_failure 2",
1596 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]", BASE_LINE + 177),
1597 "AsyncDataConn::on_txn_failure 1",
1598 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]", BASE_LINE + 177),
1599 "SyncDataConn::close 2",
1600 "SyncDataConn::drop 2",
1601 "AsyncDataConn::close 1",
1602 "AsyncDataConn::drop 1",
1603 ]
1604 );
1605 #[cfg(windows)]
1606 assert_eq!(
1607 *logger.lock().unwrap(),
1608 &[
1609 "AsyncDataConn::new 1",
1610 "SyncDataConn::new 2",
1611 "SyncDataConn::pre_commit 2",
1612 "AsyncDataConn::pre_commit 1",
1613 "SyncDataConn::commit 2",
1614 "AsyncDataConn::commit 1 failed",
1615 "AsyncDataConn::rollback 1",
1616 "SyncDataConn::on_txn_failure 2",
1617 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]", BASE_LINE + 173),
1618 "AsyncDataConn::on_txn_failure 1",
1619 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]", BASE_LINE + 173),
1620 "SyncDataConn::close 2",
1621 "SyncDataConn::drop 2",
1622 "AsyncDataConn::close 1",
1623 "AsyncDataConn::drop 1",
1624 ]
1625 );
1626 }
1627
1628 #[tokio::test]
1629 async fn test_commit_and_rollback_but_fail_second_commit() {
1630 let logger = Arc::new(Mutex::new(Vec::new()));
1631
1632 {
1633 let mut manager = DataConnManager::new();
1634
1635 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
1636 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1637 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1638 let ssnnptr = SendSyncNonNull::new(nnptr);
1639 manager.add(ssnnptr);
1640
1641 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Commit);
1642 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1643 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1644 let ssnnptr = SendSyncNonNull::new(nnptr);
1645 manager.add(ssnnptr);
1646
1647 let mut reports = manager.new_failure_reports();
1648 if let Err(e) = manager.commit_async(&mut reports).await {
1649 match e.reason::<DataConnError>() {
1650 Ok(DataConnError::FailToCommitDataConn { errors }) => {
1651 assert_eq!(errors.len(), 1);
1652 assert_eq!(errors[0].index, 1);
1653 assert_eq!(errors[0].name, "bar".into());
1654 assert_eq!(errors[0].err.reason::<String>().unwrap(), "YYY");
1655 }
1656 _ => panic!(),
1657 }
1658 } else {
1659 panic!();
1660 }
1661 manager.rollback_async(reports).await;
1662 }
1663
1664 #[cfg(unix)]
1665 assert_eq!(
1666 *logger.lock().unwrap(),
1667 &[
1668 "SyncDataConn::new 1",
1669 "AsyncDataConn::new 2",
1670 "SyncDataConn::pre_commit 1",
1671 "AsyncDataConn::pre_commit 2",
1672 "SyncDataConn::commit 1",
1673 "AsyncDataConn::commit 2 failed",
1674 "AsyncDataConn::rollback 2",
1675 "SyncDataConn::on_txn_failure 1",
1676 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 177),
1677 "AsyncDataConn::on_txn_failure 2",
1678 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 177),
1679 "AsyncDataConn::close 2",
1680 "AsyncDataConn::drop 2",
1681 "SyncDataConn::close 1",
1682 "SyncDataConn::drop 1",
1683 ]
1684 );
1685 #[cfg(windows)]
1686 assert_eq!(
1687 *logger.lock().unwrap(),
1688 &[
1689 "SyncDataConn::new 1",
1690 "AsyncDataConn::new 2",
1691 "SyncDataConn::pre_commit 1",
1692 "AsyncDataConn::pre_commit 2",
1693 "SyncDataConn::commit 1",
1694 "AsyncDataConn::commit 2 failed",
1695 "AsyncDataConn::rollback 2",
1696 "SyncDataConn::on_txn_failure 1",
1697 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 173),
1698 "AsyncDataConn::on_txn_failure 2",
1699 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 173),
1700 "AsyncDataConn::close 2",
1701 "AsyncDataConn::drop 2",
1702 "SyncDataConn::close 1",
1703 "SyncDataConn::drop 1",
1704 ]
1705 );
1706 }
1707
1708 #[tokio::test]
1709 async fn test_commit_and_rollback_but_fail_first_sync_post_commit() {
1710 let logger = Arc::new(Mutex::new(Vec::new()));
1711
1712 {
1713 let mut manager = DataConnManager::new();
1714
1715 let conn = SyncDataConn::new(1, logger.clone(), Fail::PostCommit);
1716 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1717 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1718 let ssnnptr = SendSyncNonNull::new(nnptr);
1719 manager.add(ssnnptr);
1720
1721 let conn = AsyncDataConn::new(2, logger.clone(), Fail::PostCommit);
1722 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1723 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1724 let ssnnptr = SendSyncNonNull::new(nnptr);
1725 manager.add(ssnnptr);
1726
1727 let mut reports = manager.new_failure_reports();
1728 if let Err(e) = manager.commit_async(&mut reports).await {
1729 match e.reason::<DataConnError>() {
1730 Ok(DataConnError::FailToPostCommitDataConn { errors }) => {
1731 assert_eq!(errors.len(), 2);
1732 assert_eq!(errors[0].index, 0);
1733 assert_eq!(errors[0].name, "foo".into());
1734 assert_eq!(errors[0].err.reason::<String>().unwrap(), "!!!");
1735 assert_eq!(errors[1].index, 1);
1736 assert_eq!(errors[1].name, "bar".into());
1737 assert_eq!(errors[1].err.reason::<String>().unwrap(), "!!!");
1738 }
1739 _ => panic!(),
1740 }
1741 } else {
1742 panic!();
1743 }
1744 manager.rollback_async(reports).await;
1745 }
1746
1747 #[cfg(unix)]
1748 assert_eq!(
1749 *logger.lock().unwrap(),
1750 &[
1751 "SyncDataConn::new 1",
1752 "AsyncDataConn::new 2",
1753 "SyncDataConn::pre_commit 1",
1754 "AsyncDataConn::pre_commit 2",
1755 "SyncDataConn::commit 1",
1756 "AsyncDataConn::commit 2",
1757 "SyncDataConn::post_commit 1 failed",
1758 "AsyncDataConn::post_commit 2 failed",
1759 "SyncDataConn::on_txn_failure 1",
1760 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89, BASE_LINE + 220),
1761 "AsyncDataConn::on_txn_failure 2",
1762 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89, BASE_LINE + 220),
1763 "AsyncDataConn::close 2",
1764 "AsyncDataConn::drop 2",
1765 "SyncDataConn::close 1",
1766 "SyncDataConn::drop 1",
1767 ]
1768 );
1769 #[cfg(windows)]
1770 assert_eq!(
1771 *logger.lock().unwrap(),
1772 &[
1773 "SyncDataConn::new 1",
1774 "AsyncDataConn::new 2",
1775 "SyncDataConn::pre_commit 1",
1776 "AsyncDataConn::pre_commit 2",
1777 "SyncDataConn::commit 1",
1778 "AsyncDataConn::commit 2",
1779 "SyncDataConn::post_commit 1 failed",
1780 "AsyncDataConn::post_commit 2 failed",
1781 "SyncDataConn::on_txn_failure 1",
1782 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89, BASE_LINE + 216),
1783 "AsyncDataConn::on_txn_failure 2",
1784 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89, BASE_LINE + 216),
1785 "AsyncDataConn::close 2",
1786 "AsyncDataConn::drop 2",
1787 "SyncDataConn::close 1",
1788 "SyncDataConn::drop 1",
1789 ]
1790 );
1791 }
1792
1793 #[tokio::test]
1794 async fn test_commit_and_rollback_but_fail_first_async_post_commit() {
1795 let logger = Arc::new(Mutex::new(Vec::new()));
1796
1797 {
1798 let mut manager = DataConnManager::new();
1799
1800 let conn = AsyncDataConn::new(2, logger.clone(), Fail::PostCommit);
1801 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1802 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1803 let ssnnptr = SendSyncNonNull::new(nnptr);
1804 manager.add(ssnnptr);
1805
1806 let conn = SyncDataConn::new(1, logger.clone(), Fail::PostCommit);
1807 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1808 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1809 let ssnnptr = SendSyncNonNull::new(nnptr);
1810 manager.add(ssnnptr);
1811
1812 let mut reports = manager.new_failure_reports();
1813 if let Err(e) = manager.commit_async(&mut reports).await {
1814 match e.reason::<DataConnError>() {
1815 Ok(DataConnError::FailToPostCommitDataConn { errors }) => {
1816 assert_eq!(errors.len(), 2);
1817 assert_eq!(errors[0].index, 1);
1818 assert_eq!(errors[0].name, "foo".into());
1819 assert_eq!(errors[0].err.reason::<String>().unwrap(), "!!!");
1820 assert_eq!(errors[1].index, 0);
1821 assert_eq!(errors[1].name, "bar".into());
1822 assert_eq!(errors[1].err.reason::<String>().unwrap(), "!!!");
1823 }
1824 _ => panic!(),
1825 }
1826 } else {
1827 panic!();
1828 }
1829 manager.rollback_async(reports).await;
1830 }
1831
1832 #[cfg(unix)]
1833 assert_eq!(*logger.lock().unwrap(), &[
1834 "AsyncDataConn::new 2",
1835 "SyncDataConn::new 1",
1836 "SyncDataConn::pre_commit 1",
1837 "AsyncDataConn::pre_commit 2",
1838 "SyncDataConn::commit 1",
1839 "AsyncDataConn::commit 2",
1840 "SyncDataConn::post_commit 1 failed",
1841 "AsyncDataConn::post_commit 2 failed",
1842 "SyncDataConn::on_txn_failure 1",
1843 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 220, BASE_LINE + 89),
1844 "AsyncDataConn::on_txn_failure 2",
1845 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 220, BASE_LINE + 89),
1846 "SyncDataConn::close 1",
1847 "SyncDataConn::drop 1",
1848 "AsyncDataConn::close 2",
1849 "AsyncDataConn::drop 2",
1850 ]);
1851 #[cfg(windows)]
1852 assert_eq!(*logger.lock().unwrap(), &[
1853 "AsyncDataConn::new 2",
1854 "SyncDataConn::new 1",
1855 "SyncDataConn::pre_commit 1",
1856 "AsyncDataConn::pre_commit 2",
1857 "SyncDataConn::commit 1",
1858 "AsyncDataConn::commit 2",
1859 "SyncDataConn::post_commit 1 failed",
1860 "AsyncDataConn::post_commit 2 failed",
1861 "SyncDataConn::on_txn_failure 1",
1862 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = 610 }}), rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89),
1863 "AsyncDataConn::on_txn_failure 2",
1864 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = 610 }}), rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89),
1865 "SyncDataConn::close 1",
1866 "SyncDataConn::drop 1",
1867 "AsyncDataConn::close 2",
1868 "AsyncDataConn::drop 2",
1869 ]);
1870 }
1871
1872 #[tokio::test]
1873 async fn test_commit_and_rollback_but_fail_second_post_commit() {
1874 let logger = Arc::new(Mutex::new(Vec::new()));
1875
1876 {
1877 let mut manager = DataConnManager::new();
1878
1879 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
1880 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1881 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1882 let ssnnptr = SendSyncNonNull::new(nnptr);
1883 manager.add(ssnnptr);
1884
1885 let conn = SyncDataConn::new(1, logger.clone(), Fail::PostCommit);
1886 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1887 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1888 let ssnnptr = SendSyncNonNull::new(nnptr);
1889 manager.add(ssnnptr);
1890
1891 let mut reports = manager.new_failure_reports();
1892 if let Err(e) = manager.commit_async(&mut reports).await {
1893 match e.reason::<DataConnError>() {
1894 Ok(DataConnError::FailToPostCommitDataConn { errors }) => {
1895 assert_eq!(errors.len(), 1);
1896 assert_eq!(errors[0].index, 1);
1897 assert_eq!(errors[0].name, "foo".into());
1898 assert_eq!(errors[0].err.reason::<String>().unwrap(), "!!!");
1899 }
1900 _ => panic!(),
1901 }
1902 } else {
1903 panic!();
1904 }
1905 manager.rollback_async(reports).await;
1906 }
1907
1908 #[cfg(unix)]
1909 assert_eq!(*logger.lock().unwrap(), &[
1910 "AsyncDataConn::new 2",
1911 "SyncDataConn::new 1",
1912 "SyncDataConn::pre_commit 1",
1913 "AsyncDataConn::pre_commit 2",
1914 "SyncDataConn::commit 1",
1915 "AsyncDataConn::commit 2",
1916 "SyncDataConn::post_commit 1 failed",
1917 "AsyncDataConn::post_commit 2",
1918 "SyncDataConn::on_txn_failure 1",
1919 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89),
1920 "AsyncDataConn::on_txn_failure 2",
1921 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89),
1922 "SyncDataConn::close 1",
1923 "SyncDataConn::drop 1",
1924 "AsyncDataConn::close 2",
1925 "AsyncDataConn::drop 2",
1926 ]);
1927 #[cfg(windows)]
1928 assert_eq!(*logger.lock().unwrap(), &[
1929 "AsyncDataConn::new 2",
1930 "SyncDataConn::new 1",
1931 "SyncDataConn::pre_commit 1",
1932 "AsyncDataConn::pre_commit 2",
1933 "SyncDataConn::commit 1",
1934 "AsyncDataConn::commit 2",
1935 "SyncDataConn::post_commit 1 failed",
1936 "AsyncDataConn::post_commit 2",
1937 "SyncDataConn::on_txn_failure 1",
1938 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89),
1939 "AsyncDataConn::on_txn_failure 2",
1940 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: PostCommitFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByNotRolledBack }}]", BASE_LINE + 89),
1941 "SyncDataConn::close 1",
1942 "SyncDataConn::drop 1",
1943 "AsyncDataConn::close 2",
1944 "AsyncDataConn::drop 2",
1945 ]);
1946 }
1947
1948 #[tokio::test]
1949 async fn test_commit_and_rollback_but_fail_second_post_commit_and_contains_no_commit() {
1950 let logger = Arc::new(Mutex::new(Vec::new()));
1951
1952 {
1953 let mut manager = DataConnManager::new();
1954
1955 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
1956 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
1957 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1958 let ssnnptr = SendSyncNonNull::new(nnptr);
1959 manager.add(ssnnptr);
1960
1961 let conn = AsyncDataConn::new(2, logger.clone(), Fail::PostCommit);
1962 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
1963 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1964 let ssnnptr = SendSyncNonNull::new(nnptr);
1965 manager.add(ssnnptr);
1966
1967 let conn = NoCommitDataConn::new(3, logger.clone());
1968 let boxed = Box::new(DataConnContainer::new("baz", Box::new(conn)));
1969 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
1970 let ssnnptr = SendSyncNonNull::new(nnptr);
1971 manager.add(ssnnptr);
1972
1973 let mut reports = manager.new_failure_reports();
1974
1975 if let Err(e) = manager.commit_async(&mut reports).await {
1976 match e.reason::<DataConnError>() {
1977 Ok(DataConnError::FailToPostCommitDataConn { errors }) => {
1978 assert_eq!(errors.len(), 1);
1979 assert_eq!(errors[0].index, 1);
1980 assert_eq!(errors[0].name, "bar".into());
1981 assert_eq!(errors[0].err.reason::<String>().unwrap(), "!!!");
1982 }
1983 _ => panic_any(e),
1984 }
1985 } else {
1986 panic!();
1987 }
1988 manager.rollback_async(reports).await;
1989 }
1990
1991 #[cfg(unix)]
1992 assert_eq!(
1993 &logger.lock().unwrap()[0..24],
1994 &[
1995 "SyncDataConn::new 1",
1996 "AsyncDataConn::new 2",
1997 "NoCommitDataConn::new 3",
1998 "SyncDataConn::pre_commit 1",
1999 "NoCommitDataConn::pre_commit 3",
2000 "AsyncDataConn::pre_commit 2",
2001 "SyncDataConn::commit 1",
2002 "NoCommitDataConn::commit 3",
2003 "AsyncDataConn::commit 2",
2004 "SyncDataConn::post_commit 1",
2005 "NoCommitDataConn::post_commit 3",
2006 "AsyncDataConn::post_commit 2 failed",
2007 "SyncDataConn::on_txn_failure 1",
2008 "TxnFailureReports=[TxnFailureReport { data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err { reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = 657 }), rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"baz\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::NoCommitDataConn\", cause: NoneByUncommitted, rollback: NoneByNotRolledBack }]",
2009 "NoCommitDataConn::on_txn_failure 3",
2010 "TxnFailureReports=[TxnFailureReport { data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err { reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = 657 }), rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"baz\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::NoCommitDataConn\", cause: NoneByUncommitted, rollback: NoneByNotRolledBack }]",
2011 "AsyncDataConn::on_txn_failure 2",
2012 "TxnFailureReports=[TxnFailureReport { data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err { reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = 657 }), rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"baz\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::NoCommitDataConn\", cause: NoneByUncommitted, rollback: NoneByNotRolledBack }]",
2013 "NoCommitDataConn::close 3",
2014 "NoCommitDataConn::drop 3",
2015 "AsyncDataConn::close 2",
2016 "AsyncDataConn::drop 2",
2017 "SyncDataConn::close 1",
2018 "SyncDataConn::drop 1",
2019 ]
2020 );
2021 #[cfg(windows)]
2022 assert_eq!(
2023 &logger.lock().unwrap()[0..24],
2024 &[
2025 "SyncDataConn::new 1",
2026 "AsyncDataConn::new 2",
2027 "NoCommitDataConn::new 3",
2028 "SyncDataConn::pre_commit 1",
2029 "NoCommitDataConn::pre_commit 3",
2030 "AsyncDataConn::pre_commit 2",
2031 "SyncDataConn::commit 1",
2032 "NoCommitDataConn::commit 3",
2033 "AsyncDataConn::commit 2",
2034 "SyncDataConn::post_commit 1",
2035 "NoCommitDataConn::post_commit 3",
2036 "AsyncDataConn::post_commit 2 failed",
2037 "SyncDataConn::on_txn_failure 1",
2038 "TxnFailureReports=[TxnFailureReport { data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err { reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = 657 }), rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"baz\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::NoCommitDataConn\", cause: NoneByUncommitted, rollback: NoneByNotRolledBack }]",
2039 "NoCommitDataConn::on_txn_failure 3",
2040 "TxnFailureReports=[TxnFailureReport { data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err { reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = 657 }), rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"baz\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::NoCommitDataConn\", cause: NoneByUncommitted, rollback: NoneByNotRolledBack }]",
2041 "AsyncDataConn::on_txn_failure 2",
2042 "TxnFailureReports=[TxnFailureReport { data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: PostCommitFailure(errs::Err { reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = 657 }), rollback: NoneByNotRolledBack }, TxnFailureReport { data_conn_name: \"baz\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::NoCommitDataConn\", cause: NoneByUncommitted, rollback: NoneByNotRolledBack }]",
2043 "NoCommitDataConn::close 3",
2044 "NoCommitDataConn::drop 3",
2045 "AsyncDataConn::close 2",
2046 "AsyncDataConn::drop 2",
2047 "SyncDataConn::close 1",
2048 "SyncDataConn::drop 1",
2049 ]
2050 );
2051 }
2052
2053 #[tokio::test]
2054 async fn test_only_rollback_and_first_is_sync() {
2055 let logger = Arc::new(Mutex::new(Vec::new()));
2056
2057 {
2058 let mut manager = DataConnManager::new();
2059
2060 let conn = SyncDataConn::new(1, logger.clone(), Fail::Not);
2061 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
2062 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2063 let ssnnptr = SendSyncNonNull::new(nnptr);
2064 manager.add(ssnnptr);
2065
2066 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Not);
2067 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
2068 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2069 let ssnnptr = SendSyncNonNull::new(nnptr);
2070 manager.add(ssnnptr);
2071
2072 let reports = manager.new_failure_reports();
2073 manager.rollback_async(reports).await;
2074 }
2075
2076 assert_eq!(*logger.lock().unwrap(), &[
2077 "SyncDataConn::new 1",
2078 "AsyncDataConn::new 2",
2079 "SyncDataConn::rollback 1",
2080 "AsyncDataConn::rollback 2",
2081 "SyncDataConn::on_txn_failure 1",
2082 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]"),
2083 "AsyncDataConn::on_txn_failure 2",
2084 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]"),
2085 "AsyncDataConn::close 2",
2086 "AsyncDataConn::drop 2",
2087 "SyncDataConn::close 1",
2088 "SyncDataConn::drop 1",
2089 ]);
2090 }
2091
2092 #[tokio::test]
2093 async fn test_only_rollback_and_first_is_async() {
2094 let logger = Arc::new(Mutex::new(Vec::new()));
2095
2096 {
2097 let mut manager = DataConnManager::new();
2098
2099 let conn = AsyncDataConn::new(1, logger.clone(), Fail::Not);
2100 let boxed = Box::new(DataConnContainer::new("foo".to_string(), Box::new(conn)));
2101 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2102 let ssnnptr = SendSyncNonNull::new(nnptr);
2103 manager.add(ssnnptr);
2104
2105 let conn = SyncDataConn::new(2, logger.clone(), Fail::Not);
2106 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
2107 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2108 let ssnnptr = SendSyncNonNull::new(nnptr);
2109 manager.add(ssnnptr);
2110
2111 let reports = manager.new_failure_reports();
2112 manager.rollback_async(reports).await;
2113 }
2114
2115 assert_eq!(*logger.lock().unwrap(), &[
2116 "AsyncDataConn::new 1",
2117 "SyncDataConn::new 2",
2118 "SyncDataConn::rollback 2",
2119 "AsyncDataConn::rollback 1",
2120 "SyncDataConn::on_txn_failure 2",
2121 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]"),
2122 "AsyncDataConn::on_txn_failure 1",
2123 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]"),
2124 "SyncDataConn::close 2",
2125 "SyncDataConn::drop 2",
2126 "AsyncDataConn::close 1",
2127 "AsyncDataConn::drop 1",
2128 ]);
2129 }
2130
2131 #[tokio::test]
2132 async fn test_only_rollback_and_second_rollback_failed() {
2133 let logger = Arc::new(Mutex::new(Vec::new()));
2134
2135 {
2136 let mut manager = DataConnManager::new();
2137
2138 let conn = AsyncDataConn::new(1, logger.clone(), Fail::Not);
2139 let boxed = Box::new(DataConnContainer::new("foo".to_string(), Box::new(conn)));
2140 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2141 let ssnnptr = SendSyncNonNull::new(nnptr);
2142 manager.add(ssnnptr);
2143
2144 let conn = SyncDataConn::new(2, logger.clone(), Fail::Rollback);
2145 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
2146 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2147 let ssnnptr = SendSyncNonNull::new(nnptr);
2148 manager.add(ssnnptr);
2149
2150 let reports = manager.new_failure_reports();
2151 manager.rollback_async(reports).await;
2152 }
2153
2154 #[cfg(unix)]
2155 assert_eq!(*logger.lock().unwrap(), &[
2156 "AsyncDataConn::new 1",
2157 "SyncDataConn::new 2",
2158 "SyncDataConn::rollback 2 failed",
2159 "AsyncDataConn::rollback 1",
2160 "SyncDataConn::on_txn_failure 2",
2161 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}) }}]", BASE_LINE + 110),
2162 "AsyncDataConn::on_txn_failure 1",
2163 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src/tokio/data_conn.rs, line = {} }}) }}]", BASE_LINE + 110),
2164 "SyncDataConn::close 2",
2165 "SyncDataConn::drop 2",
2166 "AsyncDataConn::close 1",
2167 "AsyncDataConn::drop 1",
2168 ]);
2169 #[cfg(windows)]
2170 assert_eq!(*logger.lock().unwrap(), &[
2171 "AsyncDataConn::new 1",
2172 "SyncDataConn::new 2",
2173 "SyncDataConn::rollback 2 failed",
2174 "AsyncDataConn::rollback 1",
2175 "SyncDataConn::on_txn_failure 2",
2176 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}) }}]", BASE_LINE + 110),
2177 "AsyncDataConn::on_txn_failure 1",
2178 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"!!!\", file = src\\tokio\\data_conn.rs, line = {} }}) }}]", BASE_LINE + 110),
2179 "SyncDataConn::close 2",
2180 "SyncDataConn::drop 2",
2181 "AsyncDataConn::close 1",
2182 "AsyncDataConn::drop 1",
2183 ]);
2184 }
2185
2186 #[tokio::test]
2187 async fn test_only_rollback_and_first_rollback_failed() {
2188 let logger = Arc::new(Mutex::new(Vec::new()));
2189
2190 {
2191 let mut manager = DataConnManager::new();
2192
2193 let conn = AsyncDataConn::new(1, logger.clone(), Fail::Rollback);
2194 let boxed = Box::new(DataConnContainer::new("foo".to_string(), Box::new(conn)));
2195 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2196 let ssnnptr = SendSyncNonNull::new(nnptr);
2197 manager.add(ssnnptr);
2198
2199 let conn = SyncDataConn::new(2, logger.clone(), Fail::Not);
2200 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
2201 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2202 let ssnnptr = SendSyncNonNull::new(nnptr);
2203 manager.add(ssnnptr);
2204
2205 let reports = manager.new_failure_reports();
2206 manager.rollback_async(reports).await;
2207 }
2208
2209 #[cfg(unix)]
2210 assert_eq!(*logger.lock().unwrap(), &[
2211 "AsyncDataConn::new 1",
2212 "SyncDataConn::new 2",
2213 "SyncDataConn::rollback 2",
2214 "AsyncDataConn::rollback 1 failed",
2215 "SyncDataConn::on_txn_failure 2",
2216 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"???\", file = src/tokio/data_conn.rs, line = {} }}) }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 244),
2217 "AsyncDataConn::on_txn_failure 1",
2218 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"???\", file = src/tokio/data_conn.rs, line = {} }}) }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]", BASE_LINE + 244),
2219 "SyncDataConn::close 2",
2220 "SyncDataConn::drop 2",
2221 "AsyncDataConn::close 1",
2222 "AsyncDataConn::drop 1",
2223 ]);
2224 #[cfg(windows)]
2225 assert_eq!(*logger.lock().unwrap(), &[
2226 "AsyncDataConn::new 1",
2227 "SyncDataConn::new 2",
2228 "SyncDataConn::rollback 2",
2229 "AsyncDataConn::rollback 1 failed",
2230 "SyncDataConn::on_txn_failure 2",
2231 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"???\", file = src\\tokio\\data_conn.rs, line = 634 }}) }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]"),
2232 "AsyncDataConn::on_txn_failure 1",
2233 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"???\", file = src\\tokio\\data_conn.rs, line = 634 }}) }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByUncommitted, rollback: NoneByRolledBack }}]"),
2234 "SyncDataConn::close 2",
2235 "SyncDataConn::drop 2",
2236 "AsyncDataConn::close 1",
2237 "AsyncDataConn::drop 1",
2238 ]);
2239 }
2240
2241 #[tokio::test]
2242 async fn test_commit_and_rollback_and_first_commit_failed_and_second_rollback_failed() {
2243 let logger = Arc::new(Mutex::new(Vec::new()));
2244
2245 {
2246 let mut manager = DataConnManager::new();
2247
2248 let conn = SyncDataConn::new(1, logger.clone(), Fail::Commit);
2249 let boxed = Box::new(DataConnContainer::new("bar", Box::new(conn)));
2250 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2251 let ssnnptr = SendSyncNonNull::new(nnptr);
2252 manager.add(ssnnptr);
2253
2254 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Rollback);
2255 let boxed = Box::new(DataConnContainer::new("foo".to_string(), Box::new(conn)));
2256 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2257 let ssnnptr = SendSyncNonNull::new(nnptr);
2258 manager.add(ssnnptr);
2259
2260 let mut reports = manager.new_failure_reports();
2261
2262 if let Err(e) = manager.commit_async(&mut reports).await {
2263 match e.reason::<DataConnError>() {
2264 Ok(DataConnError::FailToCommitDataConn { errors }) => {
2265 assert_eq!(errors.len(), 1);
2266 assert_eq!(errors[0].index, 0);
2267 assert_eq!(errors[0].name, "bar".into());
2268 assert_eq!(errors[0].err.reason::<String>().unwrap(), "ZZZ");
2269 }
2270 _ => panic!(),
2271 }
2272 } else {
2273 panic!();
2274 }
2275
2276 manager.rollback_async(reports).await;
2277 }
2278
2279 #[cfg(unix)]
2280 assert_eq!(*logger.lock().unwrap(), &[
2281 "SyncDataConn::new 1",
2282 "AsyncDataConn::new 2",
2283 "SyncDataConn::pre_commit 1",
2284 "AsyncDataConn::pre_commit 2",
2285 "SyncDataConn::commit 1 failed",
2286 "SyncDataConn::rollback 1",
2287 "AsyncDataConn::rollback 2 failed",
2288 "SyncDataConn::on_txn_failure 1",
2289 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"ZZZ\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"???\", file = src/tokio/data_conn.rs, line = {} }}) }}]", BASE_LINE + 52, BASE_LINE + 244),
2290 "AsyncDataConn::on_txn_failure 2",
2291 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"ZZZ\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"???\", file = src/tokio/data_conn.rs, line = {} }}) }}]", BASE_LINE + 52, BASE_LINE + 244),
2292 "AsyncDataConn::close 2",
2293 "AsyncDataConn::drop 2",
2294 "SyncDataConn::close 1",
2295 "SyncDataConn::drop 1",
2296 ]);
2297 #[cfg(windows)]
2298 assert_eq!(*logger.lock().unwrap(), &[
2299 "SyncDataConn::new 1",
2300 "AsyncDataConn::new 2",
2301 "SyncDataConn::pre_commit 1",
2302 "AsyncDataConn::pre_commit 2",
2303 "SyncDataConn::commit 1 failed",
2304 "SyncDataConn::rollback 1",
2305 "AsyncDataConn::rollback 2 failed",
2306 "SyncDataConn::on_txn_failure 1",
2307 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"ZZZ\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"???\", file = src\\tokio\\data_conn.rs, line = {} }}) }}]", BASE_LINE + 52, BASE_LINE + 240),
2308 "AsyncDataConn::on_txn_failure 2",
2309 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"ZZZ\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}, TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByUncommitted, rollback: RollbackFailure(errs::Err {{ reason = alloc::string::String \"???\", file = src\\tokio\\data_conn.rs, line = {} }}) }}]", BASE_LINE + 52, BASE_LINE + 240),
2310 "AsyncDataConn::close 2",
2311 "AsyncDataConn::drop 2",
2312 "SyncDataConn::close 1",
2313 "SyncDataConn::drop 1",
2314 ]);
2315 }
2316
2317 #[tokio::test]
2318 async fn test_commit_and_rollback_and_secod_commit_failed_and_first_rollback_failed() {
2319 let logger = Arc::new(Mutex::new(Vec::new()));
2320
2321 {
2322 let mut manager = DataConnManager::new();
2323
2324 let conn = SyncDataConn::new(1, logger.clone(), Fail::Rollback);
2325 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
2326 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2327 let ssnnptr = SendSyncNonNull::new(nnptr);
2328 manager.add(ssnnptr);
2329
2330 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Commit);
2331 let boxed = Box::new(DataConnContainer::new("bar".to_string(), Box::new(conn)));
2332 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2333 let ssnnptr = SendSyncNonNull::new(nnptr);
2334 manager.add(ssnnptr);
2335
2336 let mut reports = manager.new_failure_reports();
2337
2338 if let Err(e) = manager.commit_async(&mut reports).await {
2339 match e.reason::<DataConnError>() {
2340 Ok(DataConnError::FailToCommitDataConn { errors }) => {
2341 assert_eq!(errors.len(), 1);
2342 assert_eq!(errors[0].index, 1);
2343 assert_eq!(errors[0].name, "bar".into());
2344 assert_eq!(errors[0].err.reason::<String>().unwrap(), "YYY");
2345 }
2346 _ => panic!(),
2347 }
2348 } else {
2349 panic!();
2350 }
2351
2352 manager.rollback_async(reports).await;
2353 }
2354
2355 #[cfg(unix)]
2356 assert_eq!(*logger.lock().unwrap(), &[
2357 "SyncDataConn::new 1",
2358 "AsyncDataConn::new 2",
2359 "SyncDataConn::pre_commit 1",
2360 "AsyncDataConn::pre_commit 2",
2361 "SyncDataConn::commit 1",
2362 "AsyncDataConn::commit 2 failed",
2363 "AsyncDataConn::rollback 2",
2364 "SyncDataConn::on_txn_failure 1",
2365 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 177),
2366 "AsyncDataConn::on_txn_failure 2",
2367 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 177),
2368 "AsyncDataConn::close 2",
2369 "AsyncDataConn::drop 2",
2370 "SyncDataConn::close 1",
2371 "SyncDataConn::drop 1",
2372 ]);
2373 #[cfg(windows)]
2374 assert_eq!(*logger.lock().unwrap(), &[
2375 "SyncDataConn::new 1",
2376 "AsyncDataConn::new 2",
2377 "SyncDataConn::pre_commit 1",
2378 "AsyncDataConn::pre_commit 2",
2379 "SyncDataConn::commit 1",
2380 "AsyncDataConn::commit 2 failed",
2381 "AsyncDataConn::rollback 2",
2382 "SyncDataConn::on_txn_failure 1",
2383 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 173),
2384 "AsyncDataConn::on_txn_failure 2",
2385 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 173),
2386 "AsyncDataConn::close 2",
2387 "AsyncDataConn::drop 2",
2388 "SyncDataConn::close 1",
2389 "SyncDataConn::drop 1",
2390 ]);
2391 }
2392
2393 #[tokio::test]
2394 async fn test_commit_and_rollback_and_pre_commit_become_committed_and_ok() {
2395 let logger = Arc::new(Mutex::new(Vec::new()));
2396
2397 {
2398 let mut manager = DataConnManager::new();
2399
2400 let conn = SyncDataConn::new(1, logger.clone(), Fail::PreCommitBecomeCommitted);
2401 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
2402 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2403 let ssnnptr = SendSyncNonNull::new(nnptr);
2404 manager.add(ssnnptr);
2405
2406 let conn = AsyncDataConn::new(2, logger.clone(), Fail::PreCommitBecomeCommitted);
2407 let boxed = Box::new(DataConnContainer::new("bar".to_string(), Box::new(conn)));
2408 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2409 let ssnnptr = SendSyncNonNull::new(nnptr);
2410 manager.add(ssnnptr);
2411
2412 let mut reports = manager.new_failure_reports();
2413 assert!(manager.commit_async(&mut reports).await.is_ok());
2414 manager.rollback_async(reports).await;
2415 }
2416
2417 assert_eq!(*logger.lock().unwrap(), &[
2418 "SyncDataConn::new 1",
2419 "AsyncDataConn::new 2",
2420 "SyncDataConn::pre_commit 1",
2421 "AsyncDataConn::pre_commit 2",
2422 "SyncDataConn::commit 1",
2423 "AsyncDataConn::commit 2",
2424 "SyncDataConn::post_commit 1",
2425 "AsyncDataConn::post_commit 2",
2426 "SyncDataConn::on_txn_failure 1",
2427 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]"),
2428 "AsyncDataConn::on_txn_failure 2",
2429 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}]"),
2430 "AsyncDataConn::close 2",
2431 "AsyncDataConn::drop 2",
2432 "SyncDataConn::close 1",
2433 "SyncDataConn::drop 1",
2434 ]);
2435 }
2436
2437 #[tokio::test]
2438 async fn test_commit_and_rollback_and_pre_commit_become_committed_but_failed() {
2439 let logger = Arc::new(Mutex::new(Vec::new()));
2440
2441 {
2442 let mut manager = DataConnManager::new();
2443
2444 let conn = SyncDataConn::new(1, logger.clone(), Fail::PreCommitBecomeCommitted);
2445 let boxed = Box::new(DataConnContainer::new("foo", Box::new(conn)));
2446 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2447 let ssnnptr = SendSyncNonNull::new(nnptr);
2448 manager.add(ssnnptr);
2449
2450 let conn = AsyncDataConn::new(2, logger.clone(), Fail::Commit);
2451 let boxed = Box::new(DataConnContainer::new("bar".to_string(), Box::new(conn)));
2452 let nnptr = ptr::NonNull::from(Box::leak(boxed)).cast::<DataConnContainer>();
2453 let ssnnptr = SendSyncNonNull::new(nnptr);
2454 manager.add(ssnnptr);
2455
2456 let mut reports = manager.new_failure_reports();
2457
2458 if let Err(e) = manager.commit_async(&mut reports).await {
2459 match e.reason::<DataConnError>() {
2460 Ok(DataConnError::FailToCommitDataConn { errors }) => {
2461 assert_eq!(errors.len(), 1);
2462 assert_eq!(errors[0].index, 1);
2463 assert_eq!(errors[0].name, "bar".into());
2464 assert_eq!(errors[0].err.reason::<String>().unwrap(), "YYY");
2465 }
2466 _ => panic!(),
2467 }
2468 } else {
2469 panic!();
2470 }
2471
2472 manager.rollback_async(reports).await;
2473 }
2474
2475 #[cfg(unix)]
2476 assert_eq!(*logger.lock().unwrap(), &[
2477 "SyncDataConn::new 1",
2478 "AsyncDataConn::new 2",
2479 "SyncDataConn::pre_commit 1",
2480 "AsyncDataConn::pre_commit 2",
2481 "SyncDataConn::commit 1",
2482 "AsyncDataConn::commit 2 failed",
2483 "AsyncDataConn::rollback 2",
2484 "SyncDataConn::on_txn_failure 1",
2485 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 177),
2486 "AsyncDataConn::on_txn_failure 2",
2487 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src/tokio/data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 177),
2488 "AsyncDataConn::close 2",
2489 "AsyncDataConn::drop 2",
2490 "SyncDataConn::close 1",
2491 "SyncDataConn::drop 1",
2492 ]);
2493 #[cfg(windows)]
2494 assert_eq!(*logger.lock().unwrap(), &[
2495 "SyncDataConn::new 1",
2496 "AsyncDataConn::new 2",
2497 "SyncDataConn::pre_commit 1",
2498 "AsyncDataConn::pre_commit 2",
2499 "SyncDataConn::commit 1",
2500 "AsyncDataConn::commit 2 failed",
2501 "AsyncDataConn::rollback 2",
2502 "SyncDataConn::on_txn_failure 1",
2503 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 173),
2504 "AsyncDataConn::on_txn_failure 2",
2505 &format!("TxnFailureReports=[TxnFailureReport {{ data_conn_name: \"foo\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::SyncDataConn\", cause: NoneByCommitted, rollback: NoneByNotRolledBack }}, TxnFailureReport {{ data_conn_name: \"bar\", data_conn_type: \"sabi::tokio::data_conn::tests_of_data_conn::AsyncDataConn\", cause: CommitFailure(errs::Err {{ reason = alloc::string::String \"YYY\", file = src\\tokio\\data_conn.rs, line = {} }}), rollback: NoneByRolledBack }}]", BASE_LINE + 173),
2506 "AsyncDataConn::close 2",
2507 "AsyncDataConn::drop 2",
2508 "SyncDataConn::close 1",
2509 "SyncDataConn::drop 1",
2510 ]);
2511 }
2512 }
2513}