Skip to content

Commit

Permalink
Merge pull request #12859 from baude/netavarke2e
Browse files Browse the repository at this point in the history
Enable e2e tests with netavark
  • Loading branch information
openshift-merge-robot authored Feb 2, 2022
2 parents b4c9653 + 7d3ad60 commit 89f7117
Show file tree
Hide file tree
Showing 19 changed files with 327 additions and 192 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ run-docker-py-tests:
.PHONY: localunit
localunit: test/goecho/goecho test/version/version
rm -rf ${COVERAGE_PATH} && mkdir -p ${COVERAGE_PATH}
$(GOBIN)/ginkgo \
UNIT=1 $(GOBIN)/ginkgo \
-r \
$(TESTFLAGS) \
--skipPackage test/e2e,pkg/apparmor,pkg/bindings,hack \
Expand Down
1 change: 0 additions & 1 deletion cmd/podman/networks/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,6 @@ func networkList(cmd *cobra.Command, args []string) error {
if err != nil {
return err
}

// sort the networks to make sure the order is deterministic
sort.Slice(responses, func(i, j int) bool {
return responses[i].Name < responses[j].Name
Expand Down
127 changes: 114 additions & 13 deletions test/e2e/common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io/ioutil"
"math/rand"
"net"
"os"
"os/exec"
"path/filepath"
Expand Down Expand Up @@ -46,7 +47,7 @@ type PodmanTestIntegration struct {
PodmanTest
ConmonBinary string
Root string
CNIConfigDir string
NetworkConfigDir string
OCIRuntime string
RunRoot string
StorageOptions string
Expand Down Expand Up @@ -199,6 +200,7 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration {
host := GetHostDistributionInfo()
cwd, _ := os.Getwd()

root := filepath.Join(tempDir, "root")
podmanBinary := filepath.Join(cwd, "../../bin/podman")
if os.Getenv("PODMAN_BINARY") != "" {
podmanBinary = os.Getenv("PODMAN_BINARY")
Expand Down Expand Up @@ -235,11 +237,26 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration {
ociRuntime = "crun"
}
os.Setenv("DISABLE_HC_SYSTEMD", "true")
CNIConfigDir := "/etc/cni/net.d"

networkBackend := CNI
networkConfigDir := "/etc/cni/net.d"
if rootless.IsRootless() {
CNIConfigDir = filepath.Join(os.Getenv("HOME"), ".config/cni/net.d")
networkConfigDir = filepath.Join(os.Getenv("HOME"), ".config/cni/net.d")
}
if err := os.MkdirAll(CNIConfigDir, 0755); err != nil {

if strings.ToLower(os.Getenv("NETWORK_BACKEND")) == "netavark" {
networkBackend = Netavark
networkConfigDir = "/etc/containers/networks"
if rootless.IsRootless() {
networkConfigDir = filepath.Join(root, "etc", "networks")
}
}

if err := os.MkdirAll(root, 0755); err != nil {
panic(err)
}

if err := os.MkdirAll(networkConfigDir, 0755); err != nil {
panic(err)
}

Expand All @@ -251,7 +268,6 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration {
storageFs = os.Getenv("STORAGE_FS")
storageOptions = "--storage-driver " + storageFs
}

p := &PodmanTestIntegration{
PodmanTest: PodmanTest{
PodmanBinary: podmanBinary,
Expand All @@ -260,11 +276,12 @@ func PodmanTestCreateUtil(tempDir string, remote bool) *PodmanTestIntegration {
RemoteTest: remote,
ImageCacheFS: storageFs,
ImageCacheDir: ImageCacheDir,
NetworkBackend: networkBackend,
},
ConmonBinary: conmonBinary,
Root: filepath.Join(tempDir, "root"),
Root: root,
TmpDir: tempDir,
CNIConfigDir: CNIConfigDir,
NetworkConfigDir: networkConfigDir,
OCIRuntime: ociRuntime,
RunRoot: filepath.Join(tempDir, "runroot"),
StorageOptions: storageOptions,
Expand Down Expand Up @@ -754,6 +771,18 @@ func SkipIfNotActive(unit string, reason string) {
}
}

func SkipIfNetavark(p *PodmanTestIntegration) {
if p.NetworkBackend == Netavark {
Skip("This test is not compatible with the netavark network backend")
}
}

func SkipUntilAardvark(p *PodmanTestIntegration) {
if p.NetworkBackend == Netavark {
Skip("Re-enable when aardvark is functional")
}
}

// PodmanAsUser is the exec call to podman on the filesystem with the specified uid/gid and environment
func (p *PodmanTestIntegration) PodmanAsUser(args []string, uid, gid uint32, cwd string, env []string) *PodmanSessionIntegration {
podmanSession := p.PodmanAsUserBase(args, uid, gid, cwd, env, false, false, nil, nil)
Expand Down Expand Up @@ -815,7 +844,9 @@ func (p *PodmanTestIntegration) makeOptions(args []string, noEvents, noCache boo
if p.RemoteTest {
return args
}
var debug string
var (
debug string
)
if _, ok := os.LookupEnv("DEBUG"); ok {
debug = "--log-level=debug --syslog=true "
}
Expand All @@ -825,12 +856,19 @@ func (p *PodmanTestIntegration) makeOptions(args []string, noEvents, noCache boo
eventsType = "none"
}

networkBackend := p.NetworkBackend.ToString()
networkDir := p.NetworkConfigDir
if p.NetworkBackend == Netavark {
networkDir = p.NetworkConfigDir
}
podmanOptions := strings.Split(fmt.Sprintf("%s--root %s --runroot %s --runtime %s --conmon %s --network-config-dir %s --cgroup-manager %s --tmpdir %s --events-backend %s",
debug, p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, p.CNIConfigDir, p.CgroupManager, p.TmpDir, eventsType), " ")
debug, p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, networkDir, p.CgroupManager, p.TmpDir, eventsType), " ")
if os.Getenv("HOOK_OPTION") != "" {
podmanOptions = append(podmanOptions, os.Getenv("HOOK_OPTION"))
}

podmanOptions = append(podmanOptions, "--network-backend", networkBackend)

podmanOptions = append(podmanOptions, strings.Split(p.StorageOptions, " ")...)
if !noCache {
cacheOptions := []string{"--storage-opt",
Expand All @@ -842,6 +880,11 @@ func (p *PodmanTestIntegration) makeOptions(args []string, noEvents, noCache boo
}

func writeConf(conf []byte, confPath string) {
if _, err := os.Stat(filepath.Dir(confPath)); os.IsNotExist(err) {
if err := os.MkdirAll(filepath.Dir(confPath), 777); err != nil {
fmt.Println(err)
}
}
if err := ioutil.WriteFile(confPath, conf, 777); err != nil {
fmt.Println(err)
}
Expand All @@ -856,10 +899,15 @@ func removeConf(confPath string) {
// generateNetworkConfig generates a cni config with a random name
// it returns the network name and the filepath
func generateNetworkConfig(p *PodmanTestIntegration) (string, string) {
var (
path string
conf string
)
// generate a random name to prevent conflicts with other tests
name := "net" + stringid.GenerateNonCryptoID()
path := filepath.Join(p.CNIConfigDir, fmt.Sprintf("%s.conflist", name))
conf := fmt.Sprintf(`{
if p.NetworkBackend != Netavark {
path = filepath.Join(p.NetworkConfigDir, fmt.Sprintf("%s.conflist", name))
conf = fmt.Sprintf(`{
"cniVersion": "0.3.0",
"name": "%s",
"plugins": [
Expand All @@ -884,12 +932,35 @@ func generateNetworkConfig(p *PodmanTestIntegration) (string, string) {
}
]
}`, name)
} else {
path = filepath.Join(p.NetworkConfigDir, fmt.Sprintf("%s.json", name))
conf = fmt.Sprintf(`
{
"name": "%s",
"id": "e1ef2749024b88f5663ca693a9118e036d6bfc48bcfe460faf45e9614a513e5c",
"driver": "bridge",
"network_interface": "netavark1",
"created": "2022-01-05T14:15:10.975493521-06:00",
"subnets": [
{
"subnet": "10.100.0.0/16",
"gateway": "10.100.0.1"
}
],
"ipv6_enabled": false,
"internal": false,
"dns_enabled": true,
"ipam_options": {
"driver": "host-local"
}
}
`, name)
}
writeConf([]byte(conf), path)

return name, path
}

func (p *PodmanTestIntegration) removeCNINetwork(name string) {
func (p *PodmanTestIntegration) removeNetwork(name string) {
session := p.Podman([]string{"network", "rm", "-f", name})
session.WaitWithDefaultTimeout()
Expect(session.ExitCode()).To(BeNumerically("<=", 1), "Exit code must be 0 or 1")
Expand Down Expand Up @@ -937,3 +1008,33 @@ func writeYaml(content string, fileName string) error {

return nil
}

// GetPort finds an unused port on the system
func GetPort() int {
a, err := net.ResolveTCPAddr("tcp", "localhost:0")
if err != nil {
Fail(fmt.Sprintf("unable to get free port: %v", err))
}

l, err := net.ListenTCP("tcp", a)
if err != nil {
Fail(fmt.Sprintf("unable to get free port: %v", err))
}
defer l.Close()
return l.Addr().(*net.TCPAddr).Port
}

func ncz(port int) bool {
timeout := 500 * time.Millisecond
for i := 0; i < 5; i++ {
ncCmd := []string{"-z", "localhost", fmt.Sprintf("%d", port)}
fmt.Printf("Running: nc %s\n", strings.Join(ncCmd, " "))
check := SystemExec("nc", ncCmd)
if check.ExitCode() == 0 {
return true
}
time.Sleep(timeout)
timeout++
}
return false
}
6 changes: 5 additions & 1 deletion test/e2e/create_staticip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ var _ = Describe("Podman create with --ip flag", func() {
result = podmanTest.Podman([]string{"start", "test2"})
result.WaitWithDefaultTimeout()
Expect(result).To(ExitWithError())
Expect(result.ErrorToString()).To(ContainSubstring("requested IP address " + ip + " is not available"))
if podmanTest.NetworkBackend == CNI {
Expect(result.ErrorToString()).To(ContainSubstring("requested IP address " + ip + " is not available"))
} else if podmanTest.NetworkBackend == Netavark {
Expect(result.ErrorToString()).To(ContainSubstring("requested ip address %s is already allocated", ip))
}
})
})
2 changes: 1 addition & 1 deletion test/e2e/create_staticmac_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ var _ = Describe("Podman run with --mac-address flag", func() {
net := "n1" + stringid.GenerateNonCryptoID()
session := podmanTest.Podman([]string{"network", "create", net})
session.WaitWithDefaultTimeout()
defer podmanTest.removeCNINetwork(net)
defer podmanTest.removeNetwork(net)
Expect(session).Should(Exit(0))

result := podmanTest.Podman([]string{"run", "--network", net, "--mac-address", "92:d0:c6:00:29:34", ALPINE, "ip", "addr"})
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ var _ = Describe("Podman create", func() {
session := podmanTest.Podman([]string{"network", "create", netName})
session.WaitWithDefaultTimeout()
Expect(session).Should(Exit(0))
defer podmanTest.removeCNINetwork(netName)
defer podmanTest.removeNetwork(netName)

session = podmanTest.Podman([]string{"create", "--pod", name, "--network", netName, ALPINE, "top"})
session.WaitWithDefaultTimeout()
Expand Down
3 changes: 2 additions & 1 deletion test/e2e/libpod_suite_remote_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ func (p *PodmanTestIntegration) StopRemoteService() {

// MakeOptions assembles all the podman main options
func getRemoteOptions(p *PodmanTestIntegration, args []string) []string {
networkDir := p.NetworkConfigDir
podmanOptions := strings.Split(fmt.Sprintf("--root %s --runroot %s --runtime %s --conmon %s --network-config-dir %s --cgroup-manager %s",
p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, p.CNIConfigDir, p.CgroupManager), " ")
p.Root, p.RunRoot, p.OCIRuntime, p.ConmonBinary, networkDir, p.CgroupManager), " ")
if os.Getenv("HOOK_OPTION") != "" {
podmanOptions = append(podmanOptions, os.Getenv("HOOK_OPTION"))
}
Expand Down
4 changes: 1 addition & 3 deletions test/e2e/login_logout_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (

. "github.com/containers/podman/v4/test/utils"
. "github.com/onsi/ginkgo"
"github.com/onsi/ginkgo/config"
. "github.com/onsi/gomega"
. "github.com/onsi/gomega/gexec"
)
Expand All @@ -24,7 +23,6 @@ var _ = Describe("Podman login and logout", func() {
authPath string
certPath string
certDirPath string
port int
server string
testImg string
registriesConfWithSearch []byte
Expand Down Expand Up @@ -62,7 +60,7 @@ var _ = Describe("Podman login and logout", func() {

f.WriteString(session.OutputToString())
f.Sync()
port = 4999 + config.GinkgoConfig.ParallelNode
port := GetPort()
server = strings.Join([]string{"localhost", strconv.Itoa(port)}, ":")

registriesConfWithSearch = []byte(fmt.Sprintf("[registries.search]\nregistries = ['%s']", server))
Expand Down
Loading

0 comments on commit 89f7117

Please sign in to comment.