综合平台编程器项目的远程存储
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 

96 rader
3.7 KiB

  1. #include "domain/active_register_repository.h"
  2. #include "domain/register_monitor_model.h"
  3. #include "domain/register_repository.h"
  4. #include "services/register_monitor_service.h"
  5. #include <iostream>
  6. #include <stdexcept>
  7. #include <string>
  8. namespace {
  9. void require(bool condition, const std::string &message)
  10. {
  11. if (!condition)
  12. {
  13. throw std::runtime_error(message);
  14. }
  15. }
  16. void testRangeManagement()
  17. {
  18. VirtualRegisterRepository repository;
  19. RegisterMonitorService service(repository);
  20. int change_count = 0;
  21. service.setAddressesChangedCallback([&change_count] { ++change_count; });
  22. const RegisterMonitorResult added = service.addRange(" d10 ", 3);
  23. require(added.succeeded && added.affectedCount == 3
  24. && service.addresses().size() == 3U,
  25. "monitor service must expand a normalized continuous address range");
  26. require(service.addresses().front() == RegisterAddress{RegisterArea::D, 10}
  27. && service.addresses().back() == RegisterAddress{RegisterArea::D, 12},
  28. "monitor service must preserve expanded address order");
  29. const RegisterMonitorResult duplicate = service.addRange("D11", 2);
  30. require(!duplicate.succeeded && duplicate.error == RegisterMonitorError::NoChange,
  31. "monitor service must reject a fully duplicated range");
  32. require(!service.addRange("M4000", 2).succeeded,
  33. "monitor service must reject a range crossing address 4000");
  34. require(change_count == 1,
  35. "failed additions must not report a monitor address change");
  36. require(service.remove({RegisterAddress{RegisterArea::D, 11}}).succeeded
  37. && service.addresses().size() == 2U,
  38. "monitor service must remove selected addresses");
  39. require(service.clear().succeeded && service.addresses().empty(),
  40. "monitor service must clear the current monitor table");
  41. require(change_count == 3,
  42. "successful add, remove and clear operations must notify address changes");
  43. }
  44. void testSharedActiveRepositoryValues()
  45. {
  46. VirtualRegisterRepository virtual_repository;
  47. VirtualRegisterRepository plc_repository;
  48. ActiveRegisterRepository active_repository(virtual_repository);
  49. RegisterMonitorService service(active_repository);
  50. require(service.addRange("M0", 1).succeeded
  51. && service.addRange("D0", 1).succeeded,
  52. "monitor service must accept one M and one D address");
  53. virtual_repository.writeBit({RegisterArea::M, 0}, true);
  54. virtual_repository.writeWord({RegisterArea::D, 0}, -123);
  55. std::vector<MonitorValue> values = service.values(false);
  56. require(values.size() == 2U && values[0].bitValue && values[1].wordValue == -123,
  57. "monitor values must reflect the active virtual repository");
  58. plc_repository.writeBit({RegisterArea::M, 0}, false);
  59. plc_repository.writeWord({RegisterArea::D, 0}, 456);
  60. active_repository.use(plc_repository);
  61. values = service.values(false);
  62. require(!values[0].bitValue && values[1].wordValue == 456,
  63. "monitor values must follow the active repository switch");
  64. values = service.values(true);
  65. require(values[0].state == MonitorValueState::CommunicationFault
  66. && values[1].state == MonitorValueState::CommunicationFault,
  67. "valid cached values must be marked stale during a communication fault");
  68. }
  69. } // namespace
  70. int main()
  71. {
  72. try
  73. {
  74. testRangeManagement();
  75. testSharedActiveRepositoryValues();
  76. }
  77. catch (const std::exception &error)
  78. {
  79. std::cerr << "register monitor service tests failed: " << error.what() << '\n';
  80. return 1;
  81. }
  82. std::cout << "register monitor service tests passed\n";
  83. return 0;
  84. }