Skip to content

Commit

Permalink
test: move test utils files to the test-utils folder
Browse files Browse the repository at this point in the history
Tests that are currently on the main branch only runs against a qemu VM. We have other use cases that needs to be tested like running against a vfkit VM.
This commit reorganizes the tests code a bit by moving the files that can be shared to support different implementation in their own folder.
The reasoning behind this is that every hypervisor should have its own beforeSuite func to download/run a specific VM image. By moving the utils files we can reuse the same code.

For the same reason the code targeting qemu is moved to the test-qemu folder. By doing so, we can run the tests within the test-qemu folder on the ubuntu workflow and, in future, when the nested virt will be enabled on github runners, the vfkit tests on macOS.

Signed-off-by: Luca Stocchi <[email protected]>
  • Loading branch information
lstocchi committed Jan 9, 2025
1 parent 5f09250 commit b525dc8
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 108 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:

- name: Test
run: |
sudo -s -u ${USER} bash -c 'make test'
sudo -s -u ${USER} bash -c 'make test-linux'
- uses: actions/upload-artifact@v4
if: always()
Expand Down
6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,6 @@ cross: $(TOOLS_BINDIR)/makefat
test-companion:
GOOS=linux go build -ldflags "$(LDFLAGS)" -o bin/test-companion ./cmd/test-companion

.PHONY: test
test: gvproxy test-companion
go test -timeout 20m -v ./...
.PHONY: test-linux
test-linux: gvproxy test-companion
go test -timeout 20m -v ./test-qemu
45 changes: 45 additions & 0 deletions test-qemu/basic_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package e2eqemu

import (
"github.com/containers/gvisor-tap-vsock/pkg/types"
e2e "github.com/containers/gvisor-tap-vsock/test"
"github.com/onsi/ginkgo"
"github.com/onsi/gomega"
)

var _ = ginkgo.Describe("connectivity with qemu", func() {
e2e.BasicConnectivityTests(e2e.BasicTestProps{
SSHExec: sshExec,
})
})

var _ = ginkgo.Describe("dns with qemu", func() {
e2e.BasicDNSTests(e2e.BasicTestProps{
SSHExec: sshExec,
Sock: sock,
})
})

var _ = ginkgo.Describe("command-line format", func() {
ginkgo.It("should convert Command to command line format", func() {
command := types.NewGvproxyCommand()
command.AddEndpoint("unix:///tmp/network.sock")
command.Debug = true
command.AddQemuSocket("tcp://0.0.0.0:1234")
command.PidFile = "~/gv-pidfile.txt"
command.LogFile = "~/gv.log"
command.AddForwardUser("demouser")

cmd := command.ToCmdline()
gomega.Expect(cmd).To(gomega.Equal([]string{
"-listen", "unix:///tmp/network.sock",
"-debug",
"-mtu", "1500",
"-ssh-port", "2222",
"-listen-qemu", "tcp://0.0.0.0:1234",
"-forward-user", "demouser",
"-pid-file", "~/gv-pidfile.txt",
"-log-file", "~/gv.log",
}))
})
})
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package e2e
package e2eqemu

import (
"fmt"
Expand Down
2 changes: 1 addition & 1 deletion test/efi_generic.go → test-qemu/efi_generic.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//go:build !(darwin && arm64)

package e2e
package e2eqemu

func efiArgs() (string, error) {
return "", nil
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package e2e
package e2eqemu

import (
"context"
Expand Down
35 changes: 8 additions & 27 deletions test/suite_test.go → test-qemu/suite_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package e2e
package e2eqemu

import (
"flag"
Expand All @@ -13,9 +13,10 @@ import (
"testing"
"time"

e2e_utils "github.com/containers/gvisor-tap-vsock/test-utils"

"github.com/onsi/ginkgo"
"github.com/onsi/gomega"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -63,15 +64,15 @@ func init() {
var _ = ginkgo.BeforeSuite(func() {
gomega.Expect(os.MkdirAll(filepath.Join(tmpDir, "disks"), os.ModePerm)).Should(gomega.Succeed())

downloader, err := NewFcosDownloader(filepath.Join(tmpDir, "disks"))
downloader, err := e2e_utils.NewFcosDownloader(filepath.Join(tmpDir, "disks"))
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())
qemuImage, err := downloader.DownloadImage()
qemuImage, err := downloader.DownloadImage("qemu", "qcow2.xz")
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())

publicKey, err := createSSHKeys()
publicKey, err := e2e_utils.CreateSSHKeys(publicKeyFile, privateKeyFile)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())

err = CreateIgnition(ignFile, publicKey, ignitionUser, ignitionPasswordHash)
err = e2e_utils.CreateIgnition(ignFile, publicKey, ignitionUser, ignitionPasswordHash)
gomega.Expect(err).ShouldNot(gomega.HaveOccurred())

outer:
Expand Down Expand Up @@ -154,7 +155,7 @@ outer:
})

func qemuExecutable() string {
qemuBinaries := []string{"qemu-kvm", fmt.Sprintf("qemu-system-%s", coreosArch())}
qemuBinaries := []string{"qemu-kvm", fmt.Sprintf("qemu-system-%s", e2e_utils.CoreosArch())}
for _, binary := range qemuBinaries {
path, err := exec.LookPath(binary)
if err == nil && path != "" {
Expand Down Expand Up @@ -182,26 +183,6 @@ func qemuArgs() string {
return fmt.Sprintf("-machine %s,accel=%s:tcg -smp 4 -cpu host ", machine, accel)
}

func createSSHKeys() (string, error) {
_ = os.Remove(publicKeyFile)
_ = os.Remove(privateKeyFile)
err := exec.Command("ssh-keygen", "-N", "", "-t", "ed25519", "-f", privateKeyFile).Run()
if err != nil {
return "", errors.Wrap(err, "Could not generate ssh keys")
}

return readPublicKey()
}

func readPublicKey() (string, error) {
publicKey, err := os.ReadFile(publicKeyFile)
if err != nil {
return "", nil
}

return strings.TrimSpace(string(publicKey)), nil
}

func scp(src, dst string) error {
sshCmd := exec.Command("scp",
"-o", "UserKnownHostsFile=/dev/null",
Expand Down
32 changes: 17 additions & 15 deletions test/fcos.go → test-utils/fcos.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package e2e
package e2eutils

import (
"os"
Expand Down Expand Up @@ -27,6 +27,11 @@ type fcosDownloadInfo struct {
Sha256Sum string
}

type ArtifactFormat struct {
Artifact string
Format string
}

func NewFcosDownloader(dataDir string) (*FcosDownload, error) {
return &FcosDownload{
DataDir: dataDir,
Expand All @@ -38,14 +43,13 @@ func imageName(info *fcosDownloadInfo) string {
return urlSplit[len(urlSplit)-1]
}

func (downloader *FcosDownload) DownloadImage() (string, error) {
info, err := getFCOSDownload()
func (downloader *FcosDownload) DownloadImage(artifactType string, formatType string) (string, error) {
info, err := getFCOSDownload(artifactType, formatType)
if err != nil {
return "", err
}

compressedImage := filepath.Join(downloader.DataDir, imageName(info))
uncompressedImage := strings.TrimSuffix(filepath.Join(filepath.Dir(compressedImage), imageName(info)), ".xz")

// check if the latest image is already present
ok, err := downloader.updateAvailable(info, compressedImage)
Expand All @@ -58,10 +62,8 @@ func (downloader *FcosDownload) DownloadImage() (string, error) {
}
}

if _, err := os.Stat(uncompressedImage); err == nil {
return uncompressedImage, nil
}
if err := Decompress(compressedImage, uncompressedImage); err != nil {
uncompressedImage := ""
if uncompressedImage, err = Decompress(compressedImage); err != nil {
return "", err
}
return uncompressedImage, nil
Expand Down Expand Up @@ -91,7 +93,7 @@ func (downloader *FcosDownload) updateAvailable(info *fcosDownloadInfo, compress

// as of 2024-05-28, these are the 4 architectures available in
// curl https://builds.coreos.fedoraproject.org/streams/next.json
func coreosArch() string {
func CoreosArch() string {
switch runtime.GOARCH {
case "amd64":
return "x86_64"
Expand All @@ -107,7 +109,7 @@ func coreosArch() string {

// This should get Exported and stay put as it will apply to all fcos downloads
// getFCOS parses fedoraCoreOS's stream and returns the image download URL and the release version
func getFCOSDownload() (*fcosDownloadInfo, error) {
func getFCOSDownload(artifactType string, formatType string) (*fcosDownloadInfo, error) {
streamurl := fedoracoreos.GetStreamURL(fedoracoreos.StreamNext)
resp, err := http.Get(streamurl.String())
if err != nil {
Expand All @@ -127,27 +129,27 @@ func getFCOSDownload() (*fcosDownloadInfo, error) {
if err := json.Unmarshal(body, &fcosstable); err != nil {
return nil, err
}
arch, ok := fcosstable.Architectures[coreosArch()]
arch, ok := fcosstable.Architectures[CoreosArch()]
if !ok {
return nil, fmt.Errorf("unable to pull VM image: no targetArch in stream")
}
artifacts := arch.Artifacts
if artifacts == nil {
return nil, fmt.Errorf("unable to pull VM image: no artifact in stream")
}
qemu, ok := artifacts["qemu"]
artifact, ok := artifacts[artifactType]
if !ok {
return nil, fmt.Errorf("unable to pull VM image: no qemu artifact in stream")
}
formats := qemu.Formats
formats := artifact.Formats
if formats == nil {
return nil, fmt.Errorf("unable to pull VM image: no formats in stream")
}
qcow, ok := formats["qcow2.xz"]
format, ok := formats[formatType]
if !ok {
return nil, fmt.Errorf("unable to pull VM image: no qcow2.xz format in stream")
}
disk := qcow.Disk
disk := format.Disk
if disk == nil {
return nil, fmt.Errorf("unable to pull VM image: no disk in stream")
}
Expand Down
2 changes: 1 addition & 1 deletion test/ignition.go → test-utils/ignition.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package e2e
package e2eutils

import (
"encoding/json"
Expand Down
2 changes: 1 addition & 1 deletion test/ignition_schema.go → test-utils/ignition_schema.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package e2e
package e2eutils

// Taken from https://github.com/coreos/ignition/blob/master/config/v3_2/types/schema.go

Expand Down
30 changes: 22 additions & 8 deletions test/pull.go → test-utils/pull.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package e2e
package e2eutils

import (
"fmt"
Expand Down Expand Up @@ -48,18 +48,32 @@ func DownloadVMImage(downloadURL string, localImagePath string) error {
return nil
}

func Decompress(localPath, uncompressedPath string) error {
uncompressedFileWriter, err := os.OpenFile(uncompressedPath, os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
return err
func Decompress(localPath string) (string, error) {
uncompressedPath := ""
if strings.HasSuffix(localPath, ".xz") {
uncompressedPath = strings.TrimSuffix(localPath, ".xz")
}

if !strings.HasSuffix(localPath, ".xz") {
return fmt.Errorf("unsupported compression for %s", localPath)
if uncompressedPath == "" {
return "", fmt.Errorf("unsupported compression for %s", localPath)
}

// we remove the uncompressed file if already exists. Maybe it has been used earlier and can affect the tests result
os.Remove(uncompressedPath)

uncompressedFileWriter, err := os.OpenFile(uncompressedPath, os.O_CREATE|os.O_RDWR, 0600)
if err != nil {
return "", err
}

fmt.Printf("Extracting %s\n", localPath)
return decompressXZ(localPath, uncompressedFileWriter)

err = decompressXZ(localPath, uncompressedFileWriter)

if err != nil {
return "", err
}
return uncompressedPath, nil
}

// Will error out if file without .xz already exists
Expand Down
29 changes: 29 additions & 0 deletions test-utils/ssh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package e2eutils

import (
"os"
"os/exec"
"strings"

"github.com/pkg/errors"
)

func CreateSSHKeys(publicKeyFile, privateKeyFile string) (string, error) {
_ = os.Remove(publicKeyFile)
_ = os.Remove(privateKeyFile)
err := exec.Command("ssh-keygen", "-N", "", "-t", "ed25519", "-f", privateKeyFile).Run()
if err != nil {
return "", errors.Wrap(err, "Could not generate ssh keys")
}

return readPublicKey(publicKeyFile)
}

func readPublicKey(publicKeyFile string) (string, error) {
publicKey, err := os.ReadFile(publicKeyFile)
if err != nil {
return "", nil
}

return strings.TrimSpace(string(publicKey)), nil
}
Loading

0 comments on commit b525dc8

Please sign in to comment.