talos/internal/pkg/partition/format_test.go
Andrey Smirnov e0f383598e
chore: clean up the output of the imager
Use `Progress`, and options to pass around the way messages are written.

Fixed some tiny issues in the code, but otherwise no functional changes.

To make colored output work with `docker run`, switched back image
generation to use volume mount for output (old mode is still
functioning, but it's not the default, and it works when docker is not
running on the same host).

Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
2023-08-07 16:00:14 +04:00

158 lines
4.0 KiB
Go

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Package partition provides common utils for system partition format.
package partition_test
import (
"bytes"
"io"
"os"
"testing"
"github.com/siderolabs/go-blockdevice/blockdevice"
"github.com/siderolabs/go-blockdevice/blockdevice/loopback"
"github.com/siderolabs/go-blockdevice/blockdevice/partition/gpt"
"github.com/stretchr/testify/suite"
"github.com/siderolabs/talos/internal/pkg/partition"
)
type manifestSuite struct {
suite.Suite
disk *os.File
loopbackDevice *os.File
}
const (
diskSize = 10 * 1024 * 1024 // 10 MiB
)
func TestManifestSuite(t *testing.T) {
suite.Run(t, new(manifestSuite))
}
func (suite *manifestSuite) SetupTest() {
suite.skipIfNotRoot()
var err error
suite.disk, err = os.CreateTemp("", "talos")
suite.Require().NoError(err)
suite.Require().NoError(suite.disk.Truncate(diskSize))
suite.loopbackDevice, err = loopback.NextLoopDevice()
suite.Require().NoError(err)
suite.T().Logf("Using %s", suite.loopbackDevice.Name())
suite.Require().NoError(loopback.Loop(suite.loopbackDevice, suite.disk))
suite.Require().NoError(loopback.LoopSetReadWrite(suite.loopbackDevice))
}
func (suite *manifestSuite) TearDownTest() {
if suite.loopbackDevice != nil {
suite.Assert().NoError(loopback.Unloop(suite.loopbackDevice))
}
if suite.disk != nil {
suite.Assert().NoError(os.Remove(suite.disk.Name()))
suite.Assert().NoError(suite.disk.Close())
}
}
func (suite *manifestSuite) skipIfNotRoot() {
if os.Getuid() != 0 {
suite.T().Skip("can't run the test as non-root")
}
}
func (suite *manifestSuite) skipUnderBuildkit() {
hostname, _ := os.Hostname() //nolint:errcheck
if hostname == "buildkitsandbox" {
suite.T().Skip("test not supported under buildkit as partition devices are not propagated from /dev")
}
}
func (suite *manifestSuite) TestZeroPartition() {
suite.skipUnderBuildkit()
bd, err := blockdevice.Open(suite.loopbackDevice.Name(), blockdevice.WithExclusiveLock(true))
suite.Require().NoError(err)
defer bd.Close() //nolint:errcheck
pt, err := gpt.New(bd.Device(), gpt.WithMarkMBRBootable(false))
suite.Require().NoError(err)
// Create a partition table with a single partition.
_, err = pt.Add(0, gpt.WithMaximumSize(true), gpt.WithPartitionName("zerofill"))
suite.Require().NoError(err)
suite.Require().NoError(pt.Write())
suite.Require().NoError(bd.Close())
bd, err = blockdevice.Open(suite.loopbackDevice.Name(), blockdevice.WithExclusiveLock(true))
suite.Require().NoError(err)
defer bd.Close() //nolint:errcheck
fills := bytes.NewBuffer(bytes.Repeat([]byte{1}, 10))
parts, err := bd.GetPartition("zerofill")
suite.Require().NoError(err)
part, err := parts.Path()
suite.Require().NoError(err)
// open the partition as read write
dst, err := os.OpenFile(part, os.O_WRONLY, 0o644)
suite.Require().NoError(err)
defer dst.Close() //nolint:errcheck
// Write some data to the partition.
_, err = io.Copy(dst, fills)
suite.Require().NoError(err)
data, err := os.Open(part)
suite.Require().NoError(err)
defer data.Close() //nolint:errcheck
read := make([]byte, fills.Len())
_, err = data.Read(read)
suite.Require().NoError(err)
suite.Require().NoError(data.Close())
suite.Assert().True(bytes.Equal(fills.Bytes(), read))
suite.Require().NoError(bd.Close())
err = partition.Format(part, &partition.FormatOptions{
FileSystemType: partition.FilesystemTypeNone,
}, suite.T().Logf)
suite.Require().NoError(err)
// reading 10 times more than what we wrote should still return 0 since the partition is wiped
zerofills := bytes.NewBuffer(bytes.Repeat([]byte{0}, 100))
data, err = os.Open(part)
suite.Require().NoError(err)
defer data.Close() //nolint:errcheck
read = make([]byte, zerofills.Len())
_, err = data.Read(read)
suite.Require().NoError(err)
suite.Assert().True(bytes.Equal(zerofills.Bytes(), read))
}