@@ -6,15 +6,19 @@ import (
66 "encoding/json"
77 "fmt"
88 "io"
9+ "math"
910 "net/http"
1011 "os"
1112 "os/user"
1213 "path/filepath"
1314 "runtime"
15+ "slices"
16+ "strconv"
1417 "strings"
1518 "time"
1619
1720 "github.com/containers/common/pkg/strongunits"
21+ "github.com/crc-org/crc/v2/pkg/crc/ssh"
1822 "github.com/spf13/cast"
1923
2024 "github.com/crc-org/crc/v2/pkg/crc/constants"
@@ -562,6 +566,8 @@ func InitializeScenario(s *godog.ScenarioContext) {
562566 EnsureCrcVersionIsCorrect )
563567 s .Step (`^ensure service "(.*)" is accessible via NodePort with response body "(.*)"$` ,
564568 EnsureApplicationIsAccessibleViaNodePort )
569+ s .Step (`^persistent volume of size "([^"]*)"GB exists$` ,
570+ EnsureVMPartitionSizeCorrect )
565571
566572 s .After (func (ctx context.Context , _ * godog.Scenario , err error ) (context.Context , error ) {
567573
@@ -1215,3 +1221,79 @@ func EnsureMicroshiftClusterIsOperational() error {
12151221
12161222 return nil
12171223}
1224+
1225+ func EnsureVMPartitionSizeCorrect (expectedPVSizeStr string ) error {
1226+ expectedPVSize , err := strconv .Atoi (expectedPVSizeStr )
1227+ if err != nil {
1228+ return fmt .Errorf ("invalid expected persistent volume size provided in test input" )
1229+ }
1230+ err = util .ExecuteCommand ("crc ip" )
1231+ if err != nil {
1232+ return fmt .Errorf ("error in determining crc vm's ip address: %v" , err )
1233+ }
1234+ crcIP := util .GetLastCommandOutput ("stdout" )
1235+ runner , err := ssh .CreateRunner (crcIP , 2222 , filepath .Join (util .CRCHome , "machines" , "crc" , "id_ed25519" ))
1236+ if err != nil {
1237+ return fmt .Errorf ("error creating ssh runner: %v" , err )
1238+ }
1239+ out , _ , err := runner .Run ("lsblk -oTYPE,SIZE -n" )
1240+ if err != nil {
1241+ return fmt .Errorf ("error in executing command in crc vm: %v" , err )
1242+ }
1243+
1244+ actualPVSize , err := deserializeListBlockDeviceCommandOutputToExtractPVSize (out )
1245+ if err != nil {
1246+ return err
1247+ }
1248+ if actualPVSize != expectedPVSize {
1249+ return fmt .Errorf ("expecting persistent volume size to be %d, got %d" , expectedPVSize , actualPVSize )
1250+ }
1251+ return nil
1252+ }
1253+
1254+ func deserializeListBlockDeviceCommandOutputToExtractPVSize (lsblkOutput string ) (int , error ) {
1255+ type BlockDevice struct {
1256+ DeviceType string
1257+ Size string
1258+ }
1259+ blockDevices := make ([]BlockDevice , 0 )
1260+ lines := strings .Split (lsblkOutput , "\n " )
1261+
1262+ for _ , line := range lines {
1263+ fields := strings .Fields (line )
1264+ if len (fields ) < 2 {
1265+ continue
1266+ }
1267+
1268+ blockDevices = append (blockDevices , BlockDevice {
1269+ DeviceType : fields [0 ],
1270+ Size : fields [1 ],
1271+ })
1272+ }
1273+
1274+ var lvmSize int
1275+ lvmBlockDeviceIndex := slices .IndexFunc (blockDevices , func (b BlockDevice ) bool {
1276+ return b .DeviceType == "lvm"
1277+ })
1278+ if lvmBlockDeviceIndex == - 1 {
1279+ return - 1 , fmt .Errorf ("expecting lsblk output to contain a lvm device, got no device with type lvm" )
1280+ }
1281+ _ , err := fmt .Sscanf (blockDevices [lvmBlockDeviceIndex ].Size , "%dG" , & lvmSize )
1282+ if err != nil {
1283+ return - 1 , fmt .Errorf ("error in scanning lvm device size: %v" , err )
1284+ }
1285+
1286+ var diskSize = math .MinInt64
1287+ for _ , blockDevice := range blockDevices {
1288+ if blockDevice .DeviceType == "disk" {
1289+ diskSizeValue , err := strconv .ParseFloat (strings .TrimSuffix (blockDevice .Size , "G" ), 64 )
1290+ if err != nil {
1291+ return - 1 , fmt .Errorf ("error in parsing disk size: %v" , err )
1292+ }
1293+ if int (diskSizeValue ) > diskSize {
1294+ diskSize = int (diskSizeValue )
1295+ }
1296+ }
1297+ }
1298+ return diskSize - (lvmSize + 1 ), nil
1299+ }
0 commit comments