test_utils.rs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. use crate::{parser::Propagate, AmlContext, AmlValue, Handler};
  2. use alloc::boxed::Box;
  3. struct TestHandler;
  4. impl Handler for TestHandler {
  5. fn read_u8(&self, _address: usize) -> u8 {
  6. unimplemented!()
  7. }
  8. fn read_u16(&self, _address: usize) -> u16 {
  9. unimplemented!()
  10. }
  11. fn read_u32(&self, _address: usize) -> u32 {
  12. unimplemented!()
  13. }
  14. fn read_u64(&self, _address: usize) -> u64 {
  15. unimplemented!()
  16. }
  17. fn write_u8(&mut self, _address: usize, _value: u8) {
  18. unimplemented!()
  19. }
  20. fn write_u16(&mut self, _address: usize, _value: u16) {
  21. unimplemented!()
  22. }
  23. fn write_u32(&mut self, _address: usize, _value: u32) {
  24. unimplemented!()
  25. }
  26. fn write_u64(&mut self, _address: usize, _value: u64) {
  27. unimplemented!()
  28. }
  29. fn read_io_u8(&self, _port: u16) -> u8 {
  30. unimplemented!()
  31. }
  32. fn read_io_u16(&self, _port: u16) -> u16 {
  33. unimplemented!()
  34. }
  35. fn read_io_u32(&self, _port: u16) -> u32 {
  36. unimplemented!()
  37. }
  38. fn write_io_u8(&self, _port: u16, _value: u8) {
  39. unimplemented!()
  40. }
  41. fn write_io_u16(&self, _port: u16, _value: u16) {
  42. unimplemented!()
  43. }
  44. fn write_io_u32(&self, _port: u16, _value: u32) {
  45. unimplemented!()
  46. }
  47. fn read_pci_u8(&self, _segment: u16, _bus: u8, device: u8, _function: u8, _offset: u16) -> u8 {
  48. unimplemented!()
  49. }
  50. fn read_pci_u16(&self, _segment: u16, _bus: u8, device: u8, _function: u8, _offset: u16) -> u16 {
  51. unimplemented!()
  52. }
  53. fn read_pci_u32(&self, _segment: u16, _bus: u8, device: u8, _function: u8, _offset: u16) -> u32 {
  54. unimplemented!()
  55. }
  56. fn write_pci_u8(&self, _segment: u16, _bus: u8, device: u8, _function: u8, _offset: u16, _value: u8) {
  57. unimplemented!()
  58. }
  59. fn write_pci_u16(&self, _segment: u16, _bus: u8, device: u8, _function: u8, _offset: u16, _value: u16) {
  60. unimplemented!()
  61. }
  62. fn write_pci_u32(&self, _segment: u16, _bus: u8, device: u8, _function: u8, _offset: u16, _value: u32) {
  63. unimplemented!()
  64. }
  65. }
  66. pub(crate) fn make_test_context() -> AmlContext {
  67. AmlContext::new(Box::new(TestHandler), crate::DebugVerbosity::None)
  68. }
  69. pub(crate) macro check_err($parse: expr, $error: pat, $remains: expr) {
  70. match $parse {
  71. Ok((remains, _, result)) => panic!("Expected Err, got {:#?}. Remaining = {:#x?}", result, remains),
  72. Err((remains, _, Propagate::Err($error))) if *remains == *$remains => (),
  73. Err((remains, _, Propagate::Err($error))) => {
  74. panic!("Correct error, incorrect stream returned: {:#x?}", remains)
  75. }
  76. Err((_, _, err)) => panic!("Got wrong error: {:?}", err),
  77. }
  78. }
  79. pub(crate) macro check_ok($parse: expr, $expected: expr, $remains: expr) {
  80. match $parse {
  81. Ok((remains, _, ref result)) if remains == *$remains && result == &$expected => (),
  82. Ok((remains, _, ref result)) if result == &$expected => {
  83. panic!("Correct result, incorrect slice returned: {:x?}", remains)
  84. }
  85. Ok((_, _, ref result)) => panic!("Successfully parsed Ok, but it was wrong: {:#?}", result),
  86. Err((_, _, err)) => panic!("Expected Ok, got {:#?}", err),
  87. }
  88. }
  89. pub(crate) macro check_ok_value($parse: expr, $expected: expr, $remains: expr) {
  90. match $parse {
  91. Ok((remains, _, ref result)) if remains == *$remains && crudely_cmp_values(result, &$expected) => (),
  92. Ok((remains, _, ref result)) if crudely_cmp_values(result, &$expected) => {
  93. panic!("Correct result, incorrect slice returned: {:x?}", remains)
  94. }
  95. Ok((_, _, ref result)) => panic!("Successfully parsed Ok, but it was wrong: {:#?}", result),
  96. Err((_, _, err)) => panic!("Expected Ok, got {:#?}", err),
  97. }
  98. }
  99. /// This is a bad (but good for testing) way of comparing `AmlValue`s, which tests that they're exactly the same if
  100. /// it can, and gives up if it can't. It's useful in tests to be able to see if you're getting the `AmlValue` that
  101. /// you're expecting.
  102. ///
  103. /// NOTE: almost all of the `AmlValue` variants are `Eq`, and so for a long time, `AmlValue` implemented `Eq`.
  104. /// However, this is a footgun as, in the real interpreter, you rarely want to directly compare values, as you need
  105. /// to apply the AML value conversion rules to compare them correctly. This is therefore only useful for artificial
  106. /// testing scenarios.
  107. pub(crate) fn crudely_cmp_values(a: &AmlValue, b: &AmlValue) -> bool {
  108. match a {
  109. AmlValue::Boolean(a) => match b {
  110. AmlValue::Boolean(b) => a == b,
  111. _ => false,
  112. },
  113. AmlValue::Integer(a) => match b {
  114. AmlValue::Integer(b) => a == b,
  115. _ => false,
  116. },
  117. AmlValue::String(ref a) => match b {
  118. AmlValue::String(ref b) => a == b,
  119. _ => false,
  120. },
  121. AmlValue::OpRegion { region, offset, length, parent_device } => match b {
  122. AmlValue::OpRegion {
  123. region: b_region,
  124. offset: b_offset,
  125. length: b_length,
  126. parent_device: b_parent_device,
  127. } => {
  128. region == b_region && offset == b_offset && length == b_length && parent_device == b_parent_device
  129. }
  130. _ => false,
  131. },
  132. AmlValue::Field { region, flags, offset, length } => match b {
  133. AmlValue::Field { region: b_region, flags: b_flags, offset: b_offset, length: b_length } => {
  134. region == b_region && flags == b_flags && offset == b_offset && length == b_length
  135. }
  136. _ => false,
  137. },
  138. AmlValue::Method { flags, code } => match b {
  139. AmlValue::Method { flags: b_flags, code: b_code } => flags == b_flags && code == b_code,
  140. _ => false,
  141. },
  142. AmlValue::Buffer(a) => match b {
  143. AmlValue::Buffer(b) => a == b,
  144. _ => false,
  145. },
  146. AmlValue::Processor { id, pblk_address, pblk_len } => match b {
  147. AmlValue::Processor { id: b_id, pblk_address: b_pblk_address, pblk_len: b_pblk_len } => {
  148. id == b_id && pblk_address == b_pblk_address && pblk_len == b_pblk_len
  149. }
  150. _ => false,
  151. },
  152. AmlValue::Mutex { sync_level } => match b {
  153. AmlValue::Mutex { sync_level: b_sync_level } => sync_level == b_sync_level,
  154. _ => false,
  155. },
  156. AmlValue::Package(a) => match b {
  157. AmlValue::Package(b) => {
  158. for (a, b) in a.iter().zip(b) {
  159. if crudely_cmp_values(a, b) == false {
  160. return false;
  161. }
  162. }
  163. true
  164. }
  165. _ => false,
  166. },
  167. }
  168. }