blob: b2a93b2ea55402ef50dee6943ac09f0554236cfb [file] [log] [blame]
package utils
import (
"testing"
"github.com/google/go-cmp/cmp"
)
func TestParseColumns(t *testing.T) {
tests := []struct {
name string
rows []string
allTitles []string
wantTitles []string
want map[string][]string
wantErr bool
}{
{
name: "vmstat's output with spaced rows",
rows: []string{
"r b swpd free buff cache si so bi bo in cs us sy id wa st",
" ",
"5 0 0 14827096 0 25608 0 0 2 5 57 2 1 0 99 0 0",
" ",
"2 0 0 14827096 0 25608 0 0 0 0 1131 1594 2 1 97 0 1",
" ",
"2 0 0 14827096 0 25608 0 0 0 0 5283 8037 7 3 90 0 0",
},
allTitles: []string{"r", "b", "swpd", "free", "buff", "cache", "si", "so", "bi", "bo",
"in", "cs", "us", "sy", "id", "wa", "st"},
wantTitles: []string{"us", "sy", "st"},
want: map[string][]string{
"us": {"1", "2", "7"},
"sy": {"0", "1", "3"},
"st": {"0", "1", "0"},
},
},
{
name: "df's output with empty titles slice",
rows: []string{
"Filesystem Size Used Avail Use% Mounted on",
"/dev/vdb 7.5G 4.5G 2.4G 66% /",
"none 492K 0 492K 0% /dev",
"devtmpfs 7.1G 0 7.1G 0% /dev/tty",
"/dev/vdb 7.5G 4.5G 2.4G 66% /dev/kvm",
},
allTitles: []string{"Filesystem", "Size", "Used", "Avail",
"Use%", "Mounted on"},
want: map[string][]string{
"Filesystem": {"/dev/vdb", "none", "devtmpfs", "/dev/vdb"},
"Size": {"7.5G", "492K", "7.1G", "7.5G"},
"Used": {"4.5G", "0", "0", "4.5G"},
"Avail": {"2.4G", "492K", "7.1G", "2.4G"},
"Use%": {"66%", "0%", "0%", "66%"},
"Mounted on": {"/", "/dev", "/dev/tty", "/dev/kvm"},
},
},
{
name: "empty slice",
rows: []string{},
want: map[string][]string{},
},
{
name: "empty titles",
rows: []string{
"r b swpd free buff",
"5 0 0 14827096 0",
},
allTitles: []string{"r", "b", "swpd", "free", "buff"},
want: map[string][]string{
"r": {"5"},
"b": {"0"},
"swpd": {"0"},
"free": {"14827096"},
"buff": {"0"},
},
},
{
name: "repeated headers",
rows: []string{
"Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util",
"vdb 0.01 0.58 0.86 20.79 0.00 0.19 0.24 25.02 8.44 1552.07 0.90 96.44 35.68 95.00 5.62",
"vda 0.00 0.00 0.04 0.00 0.00 0.00 2.73 0.00 3.08 0.00 0.00 62.55 0.00 2.20 0.00",
" ",
"Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util",
" ",
"Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util",
" ",
"Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s %rrqm %wrqm r_await w_await aqu-sz rareq-sz wareq-sz svctm %util",
},
allTitles: []string{"Device", "r/s", "w/s", "rkB/s", "wkB/s", "rrqm/s", "wrqm/s", "%rrqm", "%wrqm", "%r_await", "w_await", "aqu-sz", "rareq-sz",
"wareq-sz", "svctm", "%util"},
wantTitles: []string{"%util"},
want: map[string][]string{
"%util": {"5.62", "0.00"},
},
},
{
name: "missing titles on some columns",
rows: []string{
" total used free shared buff/cache available",
"Mem: 14520 13 14481 0 25 14506",
"Swap: 0 0 0",
},
allTitles: []string{"total", "used", "free", "shared", "buff/cache", "available"},
wantTitles: []string{"total"},
wantErr: true,
},
{
name: "unknown titles",
rows: []string{
"r b swpd free buff cache",
"5 0 0 14827096 0 25608",
},
allTitles: []string{"r", "b", "swpd", "free", "buff", "cache"},
wantTitles: []string{"r", "b", "used"},
wantErr: true,
},
{
name: "incomplete slice of all titles",
rows: []string{
"Filesystem Size Used Avail Use% Mounted on",
"/dev/vdb 7.5G 4.5G 2.4G 67% /",
"none 492K 0 492K 0% /dev",
"devtmpfs 7.1G 0 7.1G 0% /dev/tty",
"/dev/vdb 7.5G 4.5G 2.4G 67% /dev/kvm",
},
allTitles: []string{"Filesystem", "Size", "Used", "Avail", "Use%"},
wantErr: true,
},
}
for _, test := range tests {
got, err := ParseColumns(test.rows, test.allTitles, test.wantTitles...)
if gotErr := err != nil; gotErr != test.wantErr {
t.Fatalf("ParseColumns(%v, %v, %v) err %v, wantErr: %t", test.rows, test.allTitles, test.wantTitles, err, test.wantErr)
}
if diff := cmp.Diff(test.want, got); diff != "" {
t.Errorf("Ran ParseColumns(%v, %v, %v), but got mismatch between got and want (+got, -want): \n diff %s", test.rows,
test.allTitles, test.wantTitles, diff)
}
}
}
func TestParseRows(t *testing.T) {
tests := []struct {
name string
rows []string
delim string
titles []string
want map[string][]string
wantErr bool
}{
{
name: "lscpu's output with spaced rows",
rows: []string{
"Architecture: x86_64",
" ",
"CPU op-mode(s): 32-bit, 64-bit",
"Byte Order: Little Endian",
" ",
"Address sizes: 39 bits physical, 48 bits virtual",
" ",
"CPU(s): 8",
"On-line CPU(s) list: 0-7",
},
delim: ":",
titles: []string{"CPU(s)"},
want: map[string][]string{
"CPU(s)": {"8"},
},
},
{
name: "whitespace delimiter",
rows: []string{
"vdb 0.63 0.86 22.19 760760 19680952",
"vda 0.00 0.04 0.00 37845 0",
},
delim: " ",
want: map[string][]string{
"vdb": {"0.63", "0.86", "22.19", "760760", "19680952"},
"vda": {"0.00", "0.04", "0.00", "37845", "0"},
},
},
{
name: "empty slice",
rows: []string{},
want: map[string][]string{},
},
{
name: "empty titles",
rows: []string{
"processor : 0",
"vendor_id : GenuineIntel",
"cpu family : 6",
"model : 142",
"model name : 06/8e",
},
delim: ":",
titles: []string{},
want: map[string][]string{
"processor": {"0"},
"vendor_id": {"GenuineIntel"},
"cpu family": {"6"},
"model": {"142"},
"model name": {"06/8e"},
},
},
{
name: "wrong delimiter",
rows: []string{
"vdb 0.63 0.86 22.30 760860 19808528",
"vda 0.00 0.04 0.00 37845 0",
},
delim: ":",
wantErr: true,
},
{
name: "unknown titles",
rows: []string{
"Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn",
"vdb 0.60 1.54 21.54 836516 11703972",
"vda 0.00 0.07 0.00 37901 0",
},
delim: " ",
titles: []string{"sda"},
wantErr: true,
},
}
for _, test := range tests {
got, err := ParseRows(test.rows, test.delim, test.titles...)
if gotErr := err != nil; gotErr != test.wantErr {
t.Fatalf("ParseRows(%v, %v) = %v, wantErr: %t", test.rows, test.titles, err, test.wantErr)
}
if diff := cmp.Diff(test.want, got); diff != "" {
t.Errorf("Ran ParseRows(%v, %v), but got mismatch between got and want (+got,-want): \n diff %s", test.rows, test.titles, diff)
}
}
}
func TestParseRowsAndColumns(t *testing.T) {
tests := []struct {
name string
rows []string
titles []string
want map[string][]string
wantErr bool
}{
{
name: "free",
rows: []string{
" total used free shared buff/cache available",
"Mem: 14520 13 14481 0 25 14506",
"Swap: 0 0 0",
},
titles: []string{"Mem:used", "Mem:total", "Swap:used", "Swap:total"},
want: map[string][]string{
"Mem:used": {"13"},
"Mem:total": {"14520"},
"Swap:used": {"0"},
"Swap:total": {"0"},
},
},
{
name: "iostat with spaced rows",
rows: []string{
"Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn",
" ",
"vdb 1.27 3.79 41.80 732408 8072028",
" ",
"vda 0.00 0.20 0.00 37845 0",
},
titles: []string{"vdb:tps", "vda:kB_read", "vdb:kB_wrtn"},
want: map[string][]string{
"vdb:tps": {"1.27"},
"vdb:kB_wrtn": {"8072028"},
"vda:kB_read": {"37845"},
},
},
{
name: "wrongly formatted titles",
rows: []string{
"Device tps kB_read/s kB_wrtn/s kB_read kB_wrtn",
"vdb 1.27 3.79 41.80 732408 8072028",
"vda 0.00 0.20 0.00 37845 0",
},
titles: []string{":tps"},
wantErr: true,
},
}
for _, test := range tests {
got, err := ParseRowsAndColumns(test.rows, test.titles...)
if gotErr := err != nil; gotErr != test.wantErr {
t.Fatalf("ParseRowsAndColumns(%v, %v) = %v, wantErr: %t", test.rows, test.titles, err, test.wantErr)
}
if diff := cmp.Diff(test.want, got); diff != "" {
t.Errorf("Ran ParseRowsAndColumns(%v, %v), but got mismatch between got and want (+got, -want): \n diff %s", test.rows, test.titles, diff)
}
}
}