opcode406_item_state_regression_tests.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include <array>
  2. #include <cstddef>
  3. #include <cstdint>
  4. #include <cstdio>
  5. #include <span>
  6. #include "middleware/web_service/messages/opcode406.h"
  7. extern int failures;
  8. namespace {
  9. namespace opcode406 = sunrise::middleware::web_service::messages::opcode406;
  10. void expect(bool value, const char* label) noexcept {
  11. if (!value) {
  12. std::fprintf(stderr, "FAIL %s\n", label);
  13. ++failures;
  14. }
  15. }
  16. void write_bits(std::span<std::byte> output,
  17. std::size_t& position,
  18. std::uint64_t value,
  19. std::uint8_t width) noexcept {
  20. for (std::uint8_t index = 0; index < width; ++index) {
  21. const unsigned shift = static_cast<unsigned>(width - index - 1);
  22. const auto bit = static_cast<unsigned>((value >> shift) & 1U);
  23. const std::size_t byteIndex = position / 8;
  24. const unsigned byteShift = static_cast<unsigned>(7 - (position % 8));
  25. output[byteIndex] |= std::byte{static_cast<unsigned char>(bit << byteShift)};
  26. ++position;
  27. }
  28. }
  29. std::array<std::byte, 15> payload(std::uint32_t flags) noexcept {
  30. std::array<std::byte, 15> output{};
  31. std::size_t position = 0;
  32. write_bits(output, position, 1, 1);
  33. write_bits(output, position, 0x1234U, 64);
  34. write_bits(output, position, 1, 1);
  35. write_bits(output, position, 42, 15);
  36. write_bits(output, position, 0x80000000ULL + flags, 32);
  37. write_bits(output, position, 0, 7);
  38. return output;
  39. }
  40. } // namespace
  41. void test_opcode406_item_state() noexcept {
  42. for (std::uint32_t flags = 0; flags <= 7; ++flags) {
  43. const auto bytes = payload(flags);
  44. const sunrise::middleware::web_service::Message message{
  45. opcode406::kOpcode, 1, bytes};
  46. opcode406::Request request{};
  47. expect(opcode406::parse_request(message, request),
  48. "opcode 406 accepts known item-state bits");
  49. expect(request.instanceSoid == 0x1234U && request.definitionIndex == 42
  50. && request.flags == flags,
  51. "opcode 406 preserves known item-state bits");
  52. }
  53. const auto bytes = payload(8);
  54. const sunrise::middleware::web_service::Message message{opcode406::kOpcode, 1, bytes};
  55. opcode406::Request request{};
  56. expect(!opcode406::parse_request(message, request),
  57. "opcode 406 rejects unknown item-state bits");
  58. }