cpg-test.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. // Test the CPG library. Requires that corosync is running and that we are root.
  2. extern crate rust_corosync as corosync;
  3. use corosync::{cpg, NodeId};
  4. use std::str;
  5. fn deliver_fn(
  6. _handle: &cpg::Handle,
  7. group_name: String,
  8. nodeid: NodeId,
  9. pid: u32,
  10. msg: &[u8],
  11. msg_len: usize,
  12. ) {
  13. println!(
  14. "TEST deliver_fn called for {group_name}, from nodeid/pid {nodeid}/{pid}. len={msg_len}"
  15. );
  16. // Print as text if it's valid UTF8
  17. match str::from_utf8(msg) {
  18. Ok(s) => println!(" {s}"),
  19. Err(_) => {
  20. for i in msg {
  21. print!("{i:02x} ");
  22. }
  23. println!();
  24. }
  25. }
  26. }
  27. fn confchg_fn(
  28. _handle: &cpg::Handle,
  29. group_name: &str,
  30. member_list: Vec<cpg::Address>,
  31. left_list: Vec<cpg::Address>,
  32. joined_list: Vec<cpg::Address>,
  33. ) {
  34. println!("TEST confchg_fn called for {group_name}");
  35. println!(" members: {member_list:?}");
  36. println!(" left: {left_list:?}");
  37. println!(" joined: {joined_list:?}");
  38. }
  39. fn totem_confchg_fn(_handle: &cpg::Handle, ring_id: cpg::RingId, member_list: Vec<NodeId>) {
  40. println!(
  41. "TEST totem_confchg_fn called for {}/{}",
  42. ring_id.nodeid, ring_id.seq
  43. );
  44. println!(" members: {member_list:?}");
  45. }
  46. fn main() {
  47. // Initialise the model data
  48. let md = cpg::ModelData::ModelV1(cpg::Model1Data {
  49. flags: cpg::Model1Flags::None,
  50. deliver_fn: Some(deliver_fn),
  51. confchg_fn: Some(confchg_fn),
  52. totem_confchg_fn: Some(totem_confchg_fn),
  53. });
  54. let handle = match cpg::initialize(&md, 99_u64) {
  55. Ok(h) => h,
  56. Err(e) => {
  57. println!("Error in CPG init: {e}");
  58. return;
  59. }
  60. };
  61. if let Err(e) = cpg::join(handle, "TEST") {
  62. println!("Error in CPG join: {e}");
  63. return;
  64. }
  65. match cpg::local_get(handle) {
  66. Ok(n) => {
  67. println!("Local nodeid is {n}");
  68. }
  69. Err(e) => {
  70. println!("Error in CPG local_get: {e}");
  71. }
  72. }
  73. // Test membership_get()
  74. match cpg::membership_get(handle, "TEST") {
  75. Ok(m) => {
  76. println!(" members: {m:?}");
  77. println!();
  78. }
  79. Err(e) => {
  80. println!("Error in CPG membership_get: {e}");
  81. }
  82. }
  83. // Test context APIs
  84. let set_context: u64 = 0xabcdbeefcafe;
  85. if let Err(e) = cpg::context_set(handle, set_context) {
  86. println!("Error in CPG context_set: {e}");
  87. return;
  88. }
  89. // NOTE This will fail on 32 bit systems because void* is not u64
  90. match cpg::context_get(handle) {
  91. Ok(c) => {
  92. if c != set_context {
  93. println!("Error: context_get() returned {c:x}, context should be {set_context:x}");
  94. }
  95. }
  96. Err(e) => {
  97. println!("Error in CPG context_get: {e}");
  98. }
  99. }
  100. // Test iterator
  101. match cpg::CpgIterStart::new(handle, "", cpg::CpgIterType::All) {
  102. Ok(cpg_iter) => {
  103. for i in cpg_iter {
  104. println!("ITER: {i:?}");
  105. }
  106. println!();
  107. }
  108. Err(e) => {
  109. println!("Error in CPG iter start: {e}");
  110. }
  111. }
  112. // We should receive our own message (at least) in the event loop
  113. if let Err(e) = cpg::mcast_joined(
  114. handle,
  115. cpg::Guarantee::TypeAgreed,
  116. &"This is a test".to_string().into_bytes(),
  117. ) {
  118. println!("Error in CPG mcast_joined: {e}");
  119. }
  120. // Wait for events
  121. loop {
  122. if cpg::dispatch(handle, corosync::DispatchFlags::One).is_err() {
  123. break;
  124. }
  125. }
  126. println!("ERROR: Corosync quit");
  127. }