e2e: test SSH port on NodeSSHHosts

Before assuming that a certain host runs an SSH server, we now test its
`SSHPort` for connectivity. This means that the test `should be able to
run crictl on the node` can be now more failure proof by checking only
hosts where SSH actually runs. Beside that, we can also test all hosts
and not only the first one.

Signed-off-by: Sascha Grunert <sgrunert@redhat.com>
This commit is contained in:
Sascha Grunert 2021-05-10 14:21:32 +02:00
parent 27af788a17
commit 9e372bffef
No known key found for this signature in database
GPG Key ID: 09D97D153EF94D93
2 changed files with 48 additions and 18 deletions

View File

@ -24,6 +24,7 @@ import (
"net" "net"
"os" "os"
"path/filepath" "path/filepath"
"sync"
"time" "time"
"github.com/onsi/gomega" "github.com/onsi/gomega"
@ -133,13 +134,41 @@ func NodeSSHHosts(c clientset.Interface) ([]string, error) {
len(hosts), len(nodelist.Items), nodelist) len(hosts), len(nodelist.Items), nodelist)
} }
sshHosts := make([]string, 0, len(hosts)) lenHosts := len(hosts)
for _, h := range hosts { wg := &sync.WaitGroup{}
sshHosts = append(sshHosts, net.JoinHostPort(h, SSHPort)) wg.Add(lenHosts)
sshHosts := make([]string, 0, lenHosts)
var sshHostsLock sync.Mutex
for _, host := range hosts {
go func(host string) {
defer wg.Done()
if canConnect(host) {
e2elog.Logf("Assuming SSH on host %s", host)
sshHostsLock.Lock()
sshHosts = append(sshHosts, net.JoinHostPort(host, SSHPort))
sshHostsLock.Unlock()
} else {
e2elog.Logf("Skipping host %s because it does not run anything on port %s", host, SSHPort)
}
}(host)
} }
wg.Wait()
return sshHosts, nil return sshHosts, nil
} }
// canConnect returns true if a network connection is possible to the SSHPort.
func canConnect(host string) bool {
hostPort := net.JoinHostPort(host, SSHPort)
conn, err := net.DialTimeout("tcp", hostPort, 3*time.Second)
if err != nil {
return false
}
conn.Close()
return true
}
// Result holds the execution result of SSH command // Result holds the execution result of SSH command
type Result struct { type Result struct {
User string User string

View File

@ -44,6 +44,7 @@ var _ = SIGDescribe("crictl", func() {
if err != nil { if err != nil {
framework.Failf("Error getting node hostnames: %v", err) framework.Failf("Error getting node hostnames: %v", err)
} }
e2eskipper.SkipUnlessAtLeast(len(hosts), 1, "Skipping test because found no SSH'able node")
testCases := []struct { testCases := []struct {
cmd string cmd string
@ -53,22 +54,22 @@ var _ = SIGDescribe("crictl", func() {
} }
for _, testCase := range testCases { for _, testCase := range testCases {
// Choose an arbitrary node to test. for _, host := range hosts {
host := hosts[0] ginkgo.By(fmt.Sprintf("SSH'ing to node %q to run %q", host, testCase.cmd))
ginkgo.By(fmt.Sprintf("SSH'ing to node %q to run %q", host, testCase.cmd))
result, err := e2essh.SSH(testCase.cmd, host, framework.TestContext.Provider) result, err := e2essh.SSH(testCase.cmd, host, framework.TestContext.Provider)
stdout, stderr := strings.TrimSpace(result.Stdout), strings.TrimSpace(result.Stderr) stdout, stderr := strings.TrimSpace(result.Stdout), strings.TrimSpace(result.Stderr)
if err != nil { if err != nil {
framework.Failf("Ran %q on %q, got error %v", testCase.cmd, host, err) framework.Failf("Ran %q on %q, got error %v", testCase.cmd, host, err)
} }
// Log the stdout/stderr output. // Log the stdout/stderr output.
// TODO: Verify the output. // TODO: Verify the output.
if len(stdout) > 0 { if len(stdout) > 0 {
framework.Logf("Got stdout from %q:\n %s\n", host, strings.TrimSpace(stdout)) framework.Logf("Got stdout from %q:\n %s\n", host, strings.TrimSpace(stdout))
} }
if len(stderr) > 0 { if len(stderr) > 0 {
framework.Logf("Got stderr from %q:\n %s\n", host, strings.TrimSpace(stderr)) framework.Logf("Got stderr from %q:\n %s\n", host, strings.TrimSpace(stderr))
}
} }
} }
}) })