-
Notifications
You must be signed in to change notification settings - Fork 373
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Antrea's native secondary network configuration e2e framework.
Signed-off-by: Arunkumar Velayutham <arunkumar.velayutham@intel.com>
- Loading branch information
1 parent
e7486d5
commit f71fd40
Showing
3 changed files
with
491 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
// Copyright 2022 Antrea Authors | ||
// | ||
// 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 e2e | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
"net" | ||
"os" | ||
"path/filepath" | ||
"strconv" | ||
"strings" | ||
"time" | ||
|
||
corev1 "k8s.io/api/core/v1" | ||
restclient "k8s.io/client-go/rest" | ||
|
||
antreae2e "antrea.io/antrea/test/e2e" | ||
) | ||
|
||
type SNTestData struct { | ||
e2eTestData *antreae2e.TestData | ||
kubeConfig *restclient.Config | ||
logsDirForTestCase string | ||
testNamespace string | ||
} | ||
|
||
func createDirectory(path string) error { | ||
return os.Mkdir(path, 0700) | ||
} | ||
|
||
const ( | ||
busyboxImage = "projects.registry.vmware.com/antrea/busybox" | ||
defaultInterval = 1 * time.Second | ||
) | ||
|
||
var SNtestData *SNTestData | ||
|
||
type PodIPs struct { | ||
ipv4 *net.IP | ||
ipv6 *net.IP | ||
ipStrings []string | ||
} | ||
|
||
type podInfo struct { | ||
name string | ||
os string | ||
nodeName string | ||
namespace string | ||
} | ||
|
||
type ClusterInfo struct { | ||
controlPlaneNodeName string | ||
} | ||
|
||
var clusterInfo ClusterInfo | ||
|
||
// podWaitForRunning polls the k8s apiserver until the specified Pod is in the "running" state (or | ||
// until the provided timeout expires). | ||
func (data *SNTestData) podWaitForRunning(timeout time.Duration, name, namespace string) error { | ||
_, err := data.e2eTestData.PodWaitFor(timeout, name, namespace, func(pod *corev1.Pod) (bool, error) { | ||
return pod.Status.Phase == corev1.PodRunning, nil | ||
}) | ||
return err | ||
} | ||
|
||
func (data *SNTestData) setupLogDirectoryForTest(testName string) error { | ||
path := filepath.Join(testOptions.logsExportDir, testName) | ||
// remove directory if it already exists. This ensures that we start with an empty directory | ||
_ = os.RemoveAll(path) | ||
err := createDirectory(path) | ||
if err != nil { | ||
return err | ||
} | ||
data.logsDirForTestCase = path | ||
return nil | ||
} | ||
|
||
func (data *SNTestData) createClient(kubeconfigPath string) error { | ||
e2edata = &antreae2e.TestData{} | ||
if err := e2edata.CreateClient(kubeconfigPath); err != nil { | ||
log.Fatalf("Error when creating K8s ClientSet: %v", err) | ||
return err | ||
} | ||
data.e2eTestData = e2edata | ||
return nil | ||
} | ||
|
||
func (data *SNTestData) RunPingCommandFromTestPod(podInfo podInfo, ns string, targetPodIPs *PodIPs, ctrName string, count int, size int) error { | ||
if podInfo.os != "linux" { | ||
return fmt.Errorf("OS of Pod '%s' is supported", podInfo.name) | ||
} | ||
if targetPodIPs.ipv4 != nil { | ||
cmdV4 := getPingCommand(count, size, podInfo.os, targetPodIPs.ipv4) | ||
if stdout, stderr, err := data.e2eTestData.RunCommandFromPod(ns, podInfo.name, ctrName, cmdV4); err != nil { | ||
return fmt.Errorf("error when running ping command '%s': %v - stdout: %s - stderr: %s", strings.Join(cmdV4, " "), err, stdout, stderr) | ||
} | ||
} | ||
if targetPodIPs.ipv6 != nil { | ||
cmdV6 := getPingCommand(count, size, podInfo.os, targetPodIPs.ipv6) | ||
if stdout, stderr, err := data.e2eTestData.RunCommandFromPod(ns, podInfo.name, ctrName, cmdV6); err != nil { | ||
return fmt.Errorf("error when running ping command '%s': %v - stdout: %s - stderr: %s", strings.Join(cmdV6, " "), err, stdout, stderr) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func getPingCommand(count int, size int, os string, ip *net.IP) []string { | ||
countOption, sizeOption := "-c", "-s" | ||
if os == "windows" { | ||
countOption = "-n" | ||
sizeOption = "-l" | ||
} | ||
cmd := []string{"ping", countOption, strconv.Itoa(count)} | ||
if size != 0 { | ||
cmd = append(cmd, sizeOption, strconv.Itoa(size)) | ||
} | ||
if ip.To4() != nil { | ||
cmd = append(cmd, "-4", ip.String()) | ||
} else { | ||
cmd = append(cmd, "-6", ip.String()) | ||
} | ||
return cmd | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// Copyright 2022 Antrea Authors | ||
// | ||
// 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 main under directory cmd parses and validates user input, | ||
// instantiates and initializes objects imported from pkg, and runs | ||
// the process | ||
|
||
package e2e | ||
|
||
import ( | ||
"flag" | ||
"log" | ||
"os" | ||
"path" | ||
"testing" | ||
|
||
antreae2e "antrea.io/antrea/test/e2e" | ||
) | ||
|
||
type TestOptions struct { | ||
logsExportDir string | ||
enableAntreaIPAM bool | ||
skipCases string | ||
linuxVMs string | ||
} | ||
|
||
var e2edata *antreae2e.TestData | ||
var testOptions TestOptions | ||
var homeDir, _ = os.UserHomeDir() | ||
|
||
// setupLogging creates a temporary directory to export the test logs if necessary. If a directory | ||
// was provided by the user, it checks that the directory exists. | ||
func (tOptions *TestOptions) setupLogging() func() { | ||
if tOptions.logsExportDir == "" { | ||
name, err := os.MkdirTemp("", "antrea-e2e-secondary-test-") | ||
if err != nil { | ||
log.Fatalf("Error when creating temporary directory to export logs: %v", err) | ||
} | ||
log.Printf("Test logs (if any) will be exported under the '%s' directory", name) | ||
tOptions.logsExportDir = name | ||
// we will delete the temporary directory if no logs are exported | ||
return func() { | ||
if empty, _ := antreae2e.IsDirEmpty(name); empty { | ||
log.Printf("Removing empty logs directory '%s'", name) | ||
_ = os.Remove(name) | ||
} else { | ||
log.Printf("Logs exported under '%s', it is your responsibility to delete the directory when you no longer need it", name) | ||
} | ||
} | ||
} | ||
fInfo, err := os.Stat(tOptions.logsExportDir) | ||
if err != nil { | ||
log.Fatalf("Cannot stat provided directory '%s': %v", tOptions.logsExportDir, err) | ||
} | ||
if !fInfo.Mode().IsDir() { | ||
log.Fatalf("'%s' is not a valid directory", tOptions.logsExportDir) | ||
} | ||
// no-op cleanup function | ||
return func() {} | ||
} | ||
|
||
func testMain(m *testing.M) int { | ||
flag.StringVar(&testOptions.logsExportDir, "logs-export-dir", "", "Export directory for test logs") | ||
flag.BoolVar(&testOptions.enableAntreaIPAM, "antrea-ipam", false, "Run tests with AntreaIPAM") | ||
flag.StringVar(&testOptions.skipCases, "skip", "", "Key words to skip cases") | ||
flag.StringVar(&testOptions.linuxVMs, "linuxVMs", "", "hostname of Linux VMs") | ||
flag.Parse() | ||
|
||
cleanupLogging := testOptions.setupLogging() | ||
defer cleanupLogging() | ||
|
||
SNtestData = &SNTestData{} | ||
log.Println("Creating K8s ClientSet") | ||
kubeconfigPath := path.Join(homeDir, ".kube", "secondary_network_cluster", "config") | ||
if err := SNtestData.createClient(kubeconfigPath); err != nil { | ||
log.Fatalf("Error when creating K8s ClientSet: %v", err) | ||
} | ||
ret := m.Run() | ||
return ret | ||
} | ||
|
||
func TestMain(m *testing.M) { | ||
os.Exit(testMain(m)) | ||
} |
Oops, something went wrong.