blob: 5d338a33b983c1cf18b52fd0ac41f92a705aa770 [file] [log] [blame]
// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package partutil
import (
"errors"
"fmt"
"os"
"os/exec"
"strconv"
"testing"
"cos.googlesource.com/cos/tools.git/src/pkg/tools/partutil/partutiltest"
)
// A file in tools/partutil/testdata is used as the simulation of a disk.
// When a test program starts, it will copy the file and work on it. Its size is 600K. It has three partitions as follows:
// 1. partition 8, OEM partition, 100K
// 2. partition 2, middle partition, 100K
// 3. partition 1, stateful partition, 100K
// 4. partition 12, small partition, 3.5K
func TestExtendPartitionFails(t *testing.T) {
var testNames partutiltest.TestNames
t.Cleanup(func() { partutiltest.TearDown(&testNames) })
partutiltest.SetupFakeDisk("tmp_disk_extend_partition_fails", "", t, &testNames)
diskName := testNames.DiskName
testData := []struct {
testName string
disk string
partNum int
end uint64
}{
{
testName: "SameSize",
disk: diskName,
partNum: 1,
end: 633,
}, {
testName: "InvalidDisk",
disk: "./testdata/no_disk",
partNum: 1,
end: 833,
}, {
testName: "InvalidPartition",
disk: diskName,
partNum: 0,
end: 833,
}, {
testName: "NonexistPartition",
disk: diskName,
partNum: 100,
end: 833,
}, {
testName: "SmallerSize",
disk: diskName,
partNum: 100,
end: 500,
}, {
testName: "EmptyDiskName",
disk: "",
partNum: 100,
end: 833,
}, {
testName: "TooLargeSize",
disk: diskName,
partNum: 1,
end: 3000,
},
}
for _, input := range testData {
t.Run(input.testName, func(t *testing.T) {
if err := ExtendPartition(input.disk, input.partNum, input.end); err == nil {
t.Fatalf("error not found in test %s", input.testName)
}
})
}
}
func TestExtendPartitionPasses(t *testing.T) {
var testNames partutiltest.TestNames
t.Cleanup(func() { partutiltest.TearDown(&testNames) })
partutiltest.SetupFakeDisk("tmp_disk_extend_partition_passes", "", t, &testNames)
diskName := testNames.DiskName
if err := ExtendPartition(diskName, 1, 833); err != nil {
t.Fatalf("error when extending partition 1 to 833, error msg: (%v)", err)
}
if err := os.Mkdir("./mt", 0777); err != nil {
t.Fatal("cannot create mount point ./mt")
}
defer os.Remove("./mt")
if err := exec.Command("sudo", "mount", diskName+"p1", "mt").Run(); err != nil {
t.Fatalf("error mounting disk file, partName: %q, error msg: (%v)", diskName+"p1", err)
}
defer exec.Command("sudo", "umount", "mt").Run()
cmdD := "df -h | grep mt"
out, err := exec.Command("bash", "-c", cmdD).Output()
if err != nil {
t.Fatalf("error reading df -h, error msg: (%v)", err)
}
size, err := readSize(string(out))
if err != nil {
t.Fatalf("cannot read fs size from df -h, "+
"df line: %q, error msg: (%v) ", string(out), err)
}
if size <= 180 {
t.Fatalf("wrong fs size of %q, "+
"actual size: %d, expected size: >180", diskName+"p1", size)
}
}
// readSize reads fs size from df -h, looking for the first unit K
// to find the size
func readSize(out string) (int, error) {
pos := 0
res := -1
for pos < len(out) && out[pos] != 'K' {
pos++
}
if pos == len(out) {
return 0, errors.New("cannot find unit K")
}
if !(out[pos-3] >= '0' && out[pos-3] <= '9') {
return 0, errors.New("have less than 3 digits")
}
res, err := strconv.Atoi(out[pos-3 : pos])
if err != nil {
return 0, fmt.Errorf("cannot convert %q to int", string(out[pos-3:pos]))
}
return res, nil
}