Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 12 additions & 38 deletions qcow2reader_test.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
package qcow2reader
// Package qcow2reader_test keeps blackbox tests for qcow2reader.
package qcow2reader_test
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test should use the same package as the code, no?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for whitebox tests that need access to the internals. For blackbox tests, it is better to have the test in the special *_test package. This way we use the code in the same way a user would use the code.

I think the default should be blackbox test, and whitebox tests should be used only if needed.

golang/go#25223

Copy link
Member

@AkihiroSuda AkihiroSuda Oct 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, could you add that context as a code comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, will add.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a package comment.


import (
"bytes"
"errors"
"fmt"
"io"
"math/rand"
"os"
"os/exec"
"path/filepath"
"testing"

"github.com/lima-vm/go-qcow2reader"
"github.com/lima-vm/go-qcow2reader/convert"
"github.com/lima-vm/go-qcow2reader/image"
"github.com/lima-vm/go-qcow2reader/image/qcow2"
"github.com/lima-vm/go-qcow2reader/test/qemuimg"
)

const (
MiB = int64(1) << 20
GiB = int64(1) << 30

CompressionTypeNone = qcow2.CompressionType(255)
)

// Benchmark completely empty sparse image (0% utilization). This is the best
Expand All @@ -33,7 +29,7 @@ func Benchmark0p(b *testing.B) {
}
b.Run("qcow2", func(b *testing.B) {
img := base + ".qocw2"
if err := qemuImgConvert(base, img, qcow2.Type, CompressionTypeNone); err != nil {
if err := qemuimg.Convert(base, img, qemuimg.FormatQcow2, qemuimg.CompressionNone); err != nil {
b.Fatal(err)
}
b.Run("read", func(b *testing.B) {
Expand All @@ -51,7 +47,7 @@ func Benchmark0p(b *testing.B) {
})
b.Run("qcow2 zlib", func(b *testing.B) {
img := base + ".zlib.qcow2"
if err := qemuImgConvert(base, img, qcow2.Type, qcow2.CompressionTypeZlib); err != nil {
if err := qemuimg.Convert(base, img, qemuimg.FormatQcow2, qemuimg.CompressionZlib); err != nil {
b.Fatal(err)
}
b.Run("read", func(b *testing.B) {
Expand Down Expand Up @@ -79,7 +75,7 @@ func Benchmark50p(b *testing.B) {
}
b.Run("qcow2", func(b *testing.B) {
img := base + ".qocw2"
if err := qemuImgConvert(base, img, qcow2.Type, CompressionTypeNone); err != nil {
if err := qemuimg.Convert(base, img, qemuimg.FormatQcow2, qemuimg.CompressionNone); err != nil {
b.Fatal(err)
}
b.Run("read", func(b *testing.B) {
Expand All @@ -97,7 +93,7 @@ func Benchmark50p(b *testing.B) {
})
b.Run("qcow2 zlib", func(b *testing.B) {
img := base + ".zlib.qcow2"
if err := qemuImgConvert(base, img, qcow2.Type, qcow2.CompressionTypeZlib); err != nil {
if err := qemuimg.Convert(base, img, qemuimg.FormatQcow2, qemuimg.CompressionZlib); err != nil {
b.Fatal(err)
}
b.Run("read", func(b *testing.B) {
Expand Down Expand Up @@ -126,7 +122,7 @@ func Benchmark100p(b *testing.B) {
}
b.Run("qcow2", func(b *testing.B) {
img := base + ".qocw2"
if err := qemuImgConvert(base, img, qcow2.Type, CompressionTypeNone); err != nil {
if err := qemuimg.Convert(base, img, qemuimg.FormatQcow2, qemuimg.CompressionNone); err != nil {
b.Fatal(err)
}
b.Run("read", func(b *testing.B) {
Expand All @@ -144,7 +140,7 @@ func Benchmark100p(b *testing.B) {
})
b.Run("qcow2 zlib", func(b *testing.B) {
img := base + ".zlib.qcow2"
if err := qemuImgConvert(base, img, qcow2.Type, qcow2.CompressionTypeZlib); err != nil {
if err := qemuimg.Convert(base, img, qemuimg.FormatQcow2, qemuimg.CompressionZlib); err != nil {
b.Fatal(err)
}
b.Run("read", func(b *testing.B) {
Expand All @@ -171,7 +167,7 @@ func benchmarkRead(b *testing.B, filename string) {
b.Fatal(err)
}
defer f.Close()
img, err := Open(f)
img, err := qcow2reader.Open(f)
if err != nil {
b.Fatal(err)
}
Expand All @@ -198,7 +194,7 @@ func benchmarkConvert(b *testing.B, filename string) {
b.Fatal(err)
}
defer f.Close()
img, err := Open(f)
img, err := qcow2reader.Open(f)
if err != nil {
b.Fatal(err)
}
Expand Down Expand Up @@ -289,25 +285,3 @@ func (g *Generator) Read(b []byte) (int, error) {
})
return len(b), nil
}

func qemuImgConvert(src, dst string, dstFormat image.Type, compressionType qcow2.CompressionType) error {
args := []string{"convert", "-O", string(dstFormat)}
if compressionType != CompressionTypeNone {
args = append(args, "-c", "-o", "compression_type="+compressionType.String())
}
args = append(args, src, dst)
cmd := exec.Command("qemu-img", args...)

var stderr bytes.Buffer
cmd.Stderr = &stderr

if err := cmd.Run(); err != nil {
// Return qemu-img stderr instead of the unhelpful default error (exited
// with status 1).
if _, ok := err.(*exec.ExitError); ok {
return errors.New(stderr.String())
}
return err
}
return nil
}
43 changes: 43 additions & 0 deletions test/qemuimg/qemuimg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package qemuimg

import (
"bytes"
"errors"
"os/exec"
)

type CompressionType string
type Format string

const (
// Compression types.
CompressionNone = CompressionType("")
CompressionZlib = CompressionType("zlib")
CompressionZstd = CompressionType("zstd")

// Image formats.
FormatQcow2 = Format("qcow2")
FormatRaw = Format("raw")
)

func Convert(src, dst string, dstFormat Format, compressionType CompressionType) error {
args := []string{"convert", "-O", string(dstFormat)}
if compressionType != CompressionNone {
args = append(args, "-c", "-o", "compression_type="+string(compressionType))
}
args = append(args, src, dst)
cmd := exec.Command("qemu-img", args...)

var stderr bytes.Buffer
cmd.Stderr = &stderr

if err := cmd.Run(); err != nil {
// Return qemu-img stderr instead of the unhelpful default error (exited
// with status 1).
if _, ok := err.(*exec.ExitError); ok {
return errors.New(stderr.String())
}
return err
}
return nil
}
Loading