ProxmoxQuotedNumberTests.cs 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using RackPeek.Domain.Discovery;
  2. namespace Tests.Discovery;
  3. /// <summary>
  4. /// Proxmox's perl backend quotes numeric fields inconsistently — <c>"vmid":"100"</c>
  5. /// and <c>"maxdisk":"512110190592"</c> both turn up across versions. The
  6. /// <c>TryGetInt32</c> family does not return false for a string, it throws, so a
  7. /// single quoted number used to take the whole run down with a stack trace: the CLI
  8. /// printed "Unexpected error occurred" and MCP forwarded the BCL's
  9. /// "requires an element of type 'Number'" as if it were the user's fault.
  10. /// </summary>
  11. public class ProxmoxQuotedNumberTests {
  12. [Fact]
  13. public void A_guest_whose_numbers_are_quoted_is_read_rather_than_throwing() {
  14. var json = """
  15. {"data":[{"vmid":"100","name":"quoted-guest","cpus":"4",
  16. "maxmem":"4294967296","maxdisk":"512110190592","status":"running"}]}
  17. """;
  18. ProxmoxGuest guest = Assert.Single(ProxmoxResponseParser.ParseGuests(json, "pve01", "vm"));
  19. Assert.Equal(100, guest.VmId);
  20. Assert.Equal("quoted-guest", guest.Name);
  21. Assert.Equal(4, guest.Cores);
  22. Assert.Equal(4294967296, guest.MemoryBytes);
  23. Assert.Equal(512110190592, guest.DiskBytes);
  24. }
  25. [Fact]
  26. public void Plain_numbers_still_read_the_same_way() {
  27. var json = """
  28. {"data":[{"vmid":101,"name":"plain-guest","cpus":2,
  29. "maxmem":2147483648,"maxdisk":34359738368,"status":"running"}]}
  30. """;
  31. ProxmoxGuest guest = Assert.Single(ProxmoxResponseParser.ParseGuests(json, "pve01", "vm"));
  32. Assert.Equal(101, guest.VmId);
  33. Assert.Equal(2, guest.Cores);
  34. Assert.Equal(2147483648, guest.MemoryBytes);
  35. }
  36. [Fact]
  37. public void A_field_that_is_neither_a_number_nor_a_numeric_string_is_simply_absent() {
  38. // Guessing at "N/A" would be worse than leaving the field empty, and it must
  39. // still not throw.
  40. var json = """{"data":[{"vmid":102,"name":"odd-guest","cpus":"N/A","maxmem":null}]}""";
  41. ProxmoxGuest guest = Assert.Single(ProxmoxResponseParser.ParseGuests(json, "pve01", "vm"));
  42. Assert.Equal(0, guest.Cores);
  43. Assert.Equal(0, guest.MemoryBytes);
  44. }
  45. [Fact]
  46. public void A_guest_whose_vmid_is_quoted_is_still_identified() {
  47. // vmid is the guest's identity; dropping it would silently lose the guest.
  48. var json = """{"data":[{"vmid":"103","name":"id-guest"}]}""";
  49. Assert.Equal(103, Assert.Single(ProxmoxResponseParser.ParseGuests(json, "pve01", "vm")).VmId);
  50. }
  51. }