| 1 | package host |
| 2 | |
| 3 | import ( |
| 4 | "context" |
| 5 | "encoding/json" |
| 6 | "errors" |
| 7 | "testing" |
| 8 | |
| 9 | "github.com/carlosframework/platform/internal/release" |
| 10 | ) |
| 11 | |
| 12 | func TestParseMemAvailable(t *testing.T) { |
| 13 | const meminfo = "MemTotal: 16000000 kB\nMemFree: 500000 kB\nMemAvailable: 2263040 kB\n" |
| 14 | if got := parseMemAvailableMiB(meminfo); got != 2210 { |
| 15 | t.Fatalf("got %d, want 2210", got) |
| 16 | } |
| 17 | if got := parseMemAvailableMiB("MemTotal: 1 kB\n"); got != 0 { |
| 18 | t.Fatalf("no MemAvailable line: got %d, want 0", got) |
| 19 | } |
| 20 | if got := parseMemAvailableMiB("MemAvailable: lots kB\n"); got != 0 { |
| 21 | t.Fatalf("unparseable: got %d, want 0", got) |
| 22 | } |
| 23 | } |
| 24 | |
| 25 | func TestHeadroomOnlyPublishedWithTheCapability(t *testing.T) { |
| 26 | reg := edgesTestRegistry(t) |
| 27 | if got := headroomFor(nil, t.TempDir(), reg); got != nil { |
| 28 | t.Fatalf("flag off: headroom = %+v, want nil", got) |
| 29 | } |
| 30 | if got := headroomFor([]string{capRegionHA1}, t.TempDir(), reg); got == nil { |
| 31 | t.Fatal("flag on: headroom is nil") |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | // Region HA spec 2 §7: the totals ride beside the free figures, and a |
| 36 | // failed reading is 0, never a guess. |
| 37 | func TestCapacityMiBReadsTotalsAndZeroesFailures(t *testing.T) { |
| 38 | gib := int64(8 << 30) |
| 39 | mem := func() (*int64, *int64) { return &gib, nil } |
| 40 | disk := func() (uint64, uint64, error) { return 100 << 30, 1 << 30, nil } |
| 41 | if m, d := capacityMiB(mem, disk); m != 8192 || d != 102400 { |
| 42 | t.Fatalf("capacity = %d, %d; want 8192, 102400", m, d) |
| 43 | } |
| 44 | noMem := func() (*int64, *int64) { return nil, nil } |
| 45 | noDisk := func() (uint64, uint64, error) { return 0, 0, errors.New("statfs") } |
| 46 | if m, d := capacityMiB(noMem, noDisk); m != 0 || d != 0 { |
| 47 | t.Fatalf("failed readings = %d, %d; want 0, 0", m, d) |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | func TestHeadroomCarriesTheDataVolumeSize(t *testing.T) { |
| 52 | h := headroomFor([]string{capRegionHA1}, t.TempDir(), edgesTestRegistry(t)) |
| 53 | if h == nil || h.DiskTotalMiB <= 0 { |
| 54 | t.Fatalf("headroom %+v: want the data volume's size", h) |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | func TestEdgesFileWireCarriesHeadroomTotals(t *testing.T) { |
| 59 | s, reg := release.NewDirStore(t.TempDir()), edgesTestRegistry(t) |
| 60 | var last []byte |
| 61 | ident := edgesFile{Box: "annie", BoxID: "i-0abc", Capabilities: []string{"region-ha-1"}, |
| 62 | Headroom: &edgeHeadroom{MemFreeMiB: 2210, DiskFreeMiB: 31200, Awake: 14, MemTotalMiB: 7900, DiskTotalMiB: 61000}} |
| 63 | if err := edgesFilePass(context.Background(), s, reg, ident, "1.2.3.4", &last); err != nil { |
| 64 | t.Fatal(err) |
| 65 | } |
| 66 | body, _, err := s.Get(context.Background(), "control/edges/annie.json") |
| 67 | if err != nil { |
| 68 | t.Fatal(err) |
| 69 | } |
| 70 | var raw map[string]json.RawMessage |
| 71 | if err := json.Unmarshal(body, &raw); err != nil { |
| 72 | t.Fatal(err) |
| 73 | } |
| 74 | if want := `{"mem_free_mib":2210,"disk_free_mib":31200,"awake":14,"mem_total_mib":7900,"disk_total_mib":61000}`; string(raw["headroom"]) != want { |
| 75 | t.Fatalf("headroom = %s, want %s", raw["headroom"], want) |
| 76 | } |
| 77 | } |
| 78 | |