github.com/NVIDIA/aistore@v1.3.23-0.20240517131212-7df6609be51d/ios/parselsblk_internal_test.go (about) 1 //go:build linux 2 3 // Package ios is a collection of interfaces to the local storage subsystem; 4 // the package includes OS-dependent implementations for those interfaces. 5 /* 6 * Copyright (c) 2018-2023, NVIDIA CORPORATION. All rights reserved. 7 */ 8 package ios 9 10 import ( 11 "strings" 12 "testing" 13 14 jsoniter "github.com/json-iterator/go" 15 ) 16 17 func TestLsblk_LVM(t *testing.T) { 18 var lsblk LsBlk 19 rawJSON := jsoniter.RawMessage(` 20 { 21 "blockdevices": [ 22 {"name":"loop0", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "ra":128, "wsame":"0B"}, 23 {"name":"loop1", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "ra":128, "wsame":"0B"}, 24 {"name":"loop2", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "ra":128, "wsame":"0B"}, 25 {"name":"loop3", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "ra":128, "wsame":"0B"}, 26 {"name":"loop4", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "ra":128, "wsame":"0B"}, 27 {"name":"loop5", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "ra":128, "wsame":"0B"}, 28 {"name":"loop6", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "ra":128, "wsame":"0B"}, 29 {"name":"loop7", "alignment":0, "min-io":512, "opt-io":0, "phy-sec":512, "log-sec":512, "rota":false, "sched":"mq-deadline", "rq-size":256, "ra":128, "wsame":"0B"}, 30 {"name":"nvme0n1", "alignment":0, "min-io":512, "opt-io":512, "phy-sec":512, "log-sec":512, "rota":false, "sched":"none", "rq-size":1023, "ra":128, "wsame":"0B", 31 "children": [ 32 {"name":"nvme0n1p1", "alignment":0, "min-io":512, "opt-io":512, "phy-sec":512, "log-sec":512, "rota":false, "sched":"none", "rq-size":1023, "ra":128, "wsame":"0B"}, 33 {"name":"nvme0n1p2", "alignment":0, "min-io":512, "opt-io":512, "phy-sec":512, "log-sec":512, "rota":false, "sched":"none", "rq-size":1023, "ra":128, "wsame":"0B", 34 "children": [ 35 {"name":"ubuntu-root", "alignment":0, "min-io":512, "opt-io":512, "phy-sec":512, "log-sec":512, "rota":false, "sched":null, "rq-size":128, "ra":128, "wsame":"0B"} 36 ] 37 } 38 ] 39 } 40 ] 41 }`) 42 if err := jsoniter.Unmarshal(rawJSON, &lsblk); err != nil { 43 t.Fatalf("Failed to unmarshal %s: %v", string(rawJSON), err) 44 } 45 var ( 46 fs = "/dev/mapper/ubuntu-root" 47 trimmedFS string 48 ) 49 if strings.HasPrefix(fs, devPrefixLVM) { 50 trimmedFS = strings.TrimPrefix(fs, devPrefixLVM) 51 } else { 52 trimmedFS = strings.TrimPrefix(fs, devPrefixReg) 53 } 54 disks := make(FsDisks, 4) 55 findDevs(lsblk.BlockDevices, trimmedFS, "", disks) 56 if len(disks) == 0 { 57 t.Fatal("No disks") 58 } else { 59 t.Logf("Found %s => %v\n", fs, disks) 60 } 61 } 62 63 func TestLsblk_Reg(t *testing.T) { 64 var lsblk LsBlk 65 rawJSON := jsoniter.RawMessage( 66 `{ 67 "blockdevices": [ 68 {"name": "sda", "alignment": "0", "phy-sec": "512", "log-sec": "512", "rota": "1", "sched": "deadline", 69 "children": [ 70 {"name": "sda1", "alignment": "0", "phy-sec": "512", "log-sec": "512", "rota": "1", "sched": "deadline"}, 71 {"name": "sda2", "alignment": "0", "phy-sec": "512", "log-sec": "512", "rota": "1", "sched": "deadline"} 72 ] 73 }, 74 {"name": "sdb", "alignment": "0", "min-io": "262144", "opt-io": "1048576", "phy-sec": "1024", "log-sec": "512", "rota": "1", "sched": "deadline", "rq-size": "4096", "ra": "1024", "wsame": "0B"}] 75 }`) 76 out, _ := jsoniter.Marshal(&rawJSON) 77 jsoniter.Unmarshal(out, &lsblk) 78 if len(lsblk.BlockDevices) != 2 { 79 t.Fatalf("expected 2 block devices, got %d", len(lsblk.BlockDevices)) 80 } 81 if sec, _ := lsblk.BlockDevices[0].PhySec.Int64(); sec != 512 { 82 t.Fatalf("expected 512 sector, got %d", sec) 83 } 84 if sec, _ := lsblk.BlockDevices[1].PhySec.Int64(); sec != 1024 { 85 t.Fatalf("expected 1024 sector, got %d", sec) 86 } 87 if lsblk.BlockDevices[0].BlockDevices[1].Name != "sda2" { 88 t.Fatalf("expected sda2 device, got %s", lsblk.BlockDevices[0].BlockDevices[1].Name) 89 } 90 if len(lsblk.BlockDevices[0].BlockDevices) != 2 { 91 t.Fatalf("expected 2 block children devices, got %d", len(lsblk.BlockDevices[0].BlockDevices)) 92 } 93 } 94 95 // This test is similar to previous one but does not use strings to encode 96 // integers for fields like "phy-sec" or "log-sec". Such format should be 97 // parsed too. 98 func TestLsblk_Int(t *testing.T) { 99 var lsblk LsBlk 100 rawJSON := jsoniter.RawMessage( 101 `{ 102 "blockdevices": [ 103 {"name": "sda", "alignment": 0, "phy-sec": 512, "log-sec": 512, "rota": 1, "sched": "deadline", 104 "children": [ 105 {"name": "sda1", "alignment": 0, "phy-sec": 512, "log-sec": 512, "rota": 1, "sched": "deadline"}, 106 {"name": "sda2", "alignment": 0, "phy-sec": 512, "log-sec": 512, "rota": 1, "sched": "deadline"} 107 ] 108 }, 109 {"name": "sdb", "alignment": "0", "min-io": 262144, "opt-io": 1048576, "phy-sec": 1024, "log-sec": 512, "rota": 1, "sched": "deadline", "rq-size": 4096, "ra": 1024, "wsame": "0B"}] 110 }`) 111 out, _ := jsoniter.Marshal(&rawJSON) 112 jsoniter.Unmarshal(out, &lsblk) 113 if len(lsblk.BlockDevices) != 2 { 114 t.Fatalf("expected 2 block devices, got %d", len(lsblk.BlockDevices)) 115 } 116 if sec, _ := lsblk.BlockDevices[1].PhySec.Int64(); sec != 1024 { 117 t.Fatalf("expected 1024 sector, got %d", sec) 118 } 119 if lsblk.BlockDevices[0].BlockDevices[1].Name != "sda2" { 120 t.Fatalf("expected sda2 device, got %s", lsblk.BlockDevices[0].BlockDevices[1].Name) 121 } 122 if len(lsblk.BlockDevices[0].BlockDevices) != 2 { 123 t.Fatalf("expected 2 block children devices, got %d", len(lsblk.BlockDevices[0].BlockDevices)) 124 } 125 }