Updated tests fixing some issues

This commit is contained in:
David Allen 2024-09-20 16:40:31 -06:00 committed by David Allen
parent affba7dfa3
commit 18d5ef10b0
No known key found for this signature in database
GPG key ID: 717C593FF60A2ACC
2 changed files with 169 additions and 101 deletions

View file

@ -8,9 +8,12 @@
package tests package tests
import ( import (
"bytes"
"crypto/tls"
"fmt" "fmt"
"net" "net"
"net/http" "net/http"
"os"
"os/exec" "os/exec"
"testing" "testing"
"time" "time"
@ -20,70 +23,72 @@ import (
magellan "github.com/OpenCHAMI/magellan/internal" magellan "github.com/OpenCHAMI/magellan/internal"
"github.com/OpenCHAMI/magellan/internal/util" "github.com/OpenCHAMI/magellan/internal/util"
"github.com/OpenCHAMI/magellan/pkg/client" "github.com/OpenCHAMI/magellan/pkg/client"
"github.com/rs/zerolog/log"
) )
var ( var (
scanParams = &magellan.ScanParams{ exePath = flag.String("exe", "../magellan", "path to 'magellan' binary executable")
TargetHosts: [][]string{
[]string{
"http://127.0.0.1:443",
"http://127.0.0.1:5000",
},
},
Scheme: "https",
Protocol: "tcp",
Concurrency: 1,
Timeout: 30,
DisableProbing: false,
Verbose: false,
}
exePath = flag.String("exe", "./magellan", "path to 'magellan' binary executable")
emuPath = flag.String("emu", "./emulator/setup.sh", "path to emulator 'setup.sh' script") emuPath = flag.String("emu", "./emulator/setup.sh", "path to emulator 'setup.sh' script")
) )
func runEmulator() {}
func TestScanAndCollect(t *testing.T) { func TestScanAndCollect(t *testing.T) {
var ( var (
err error err error
emuErr error
output []byte
tempDir = t.TempDir() tempDir = t.TempDir()
command string command string
cwd string
cmd *exec.Cmd
buf bytes.Buffer
) )
// try and start the emulator in the background if arg passed // set up the emulator to run before test
if *emuPath != "" { err = waitUntilEmulatorIsReady()
t.Parallel() if err != nil {
t.Run("emulator", func(t *testing.T) { t.Fatalf("failed while waiting for emulator: %v", err)
_, emuErr = exec.Command("bash", "-c", *emuPath).CombinedOutput()
if emuErr != nil {
t.Fatalf("failed to start emulator: %v", emuErr)
}
})
} }
// get the current working directory and print
cwd, err = os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
fmt.Printf("cwd: %s\n", cwd)
// path, err := exec.LookPath("dexdump")
// if err != nil {
// log.Fatal(err)
// }
// try and run a "scan" with the emulator // try and run a "scan" with the emulator
command = fmt.Sprintf("%s scan --subnet 127.0.0.1 --subnet-mask 255.255.255.0 --cache %s", exePath, tempDir) command = fmt.Sprintf("%s scan https://172.23.0.2 --port 5000 --cache %s", *exePath, tempDir)
output, err = exec.Command("bash", "-c", command).CombinedOutput() cmd = exec.Command("bash", "-c", command)
cmd.Stdout = &buf
err = cmd.Run()
if err != nil { if err != nil {
t.Fatalf("failed to run 'scan' command: %v", err) t.Fatalf("failed to run 'scan' command: %v", err)
} }
// make sure that the expected output is not empty // make sure that the expected output is not empty
if len(output) <= 0 { if len(buf.Bytes()) <= 0 {
t.Fatalf("expected the 'scan' output to not be empty") t.Fatalf("expected the 'scan' output to not be empty")
} }
// try and run a "collect" with the emulator // try and run a "collect" with the emulator
command = fmt.Sprintf("%s collect --username root --password root_password --cache %s", exePath, tempDir) command = fmt.Sprintf("%s collect --username root --password root_password --cache %s", *exePath, tempDir)
output, err = exec.Command("bash", "-c", command).CombinedOutput() cmd = exec.Command("bash", "-c", command)
cmd.Stdout = &buf
err = cmd.Start()
if err != nil { if err != nil {
t.Fatalf("failed to run 'collect' command: %v", err) t.Fatalf("failed to run 'collect' command: %v", err)
} }
err = cmd.Wait()
if err != nil {
t.Fatalf("failed to call 'wait' for scan: %v", err)
}
// make sure that the output is not empty // make sure that the output is not empty
if len(output) <= 0 { if len(buf.Bytes()) <= 0 {
t.Fatalf("expected the 'collect' output to not be empty") t.Fatalf("expected the 'collect' output to not be empty")
} }
@ -93,67 +98,57 @@ func TestScanAndCollect(t *testing.T) {
func TestCrawlCommand(t *testing.T) { func TestCrawlCommand(t *testing.T) {
var ( var (
err error err error
emuErr error
output []byte
command string command string
cmd *exec.Cmd
buf bytes.Buffer
) )
// set up the emulator to run before test // set up the emulator to run before test
err = waitUntilEmulatorIsReady() err = waitUntilEmulatorIsReady()
if err != nil { if err != nil {
t.Fatalf("failed to start emulator: %v", err) t.Fatalf("failed while waiting for emulator: %v", err)
}
// try and start the emulator in the background if arg passed
if *emuPath != "" {
t.Parallel()
t.Run("emulator", func(t *testing.T) {
_, emuErr = exec.Command("bash", "-c", *emuPath).CombinedOutput()
if emuErr != nil {
t.Fatalf("failed to start emulator: %v", emuErr)
}
})
} }
// try and run a "collect" with the emulator // try and run a "collect" with the emulator
command = fmt.Sprintf("%s crawl --username root --password root_password -i", exePath) command = fmt.Sprintf("%s crawl --username root --password root_password -i", *exePath)
output, err = exec.Command("bash", "-c", command).CombinedOutput() cmd = exec.Command("bash", "-c", command)
cmd.Stdout = &buf
err = cmd.Start()
if err != nil { if err != nil {
t.Fatalf("failed to run 'crawl' command: %v", err) t.Fatalf("failed to run 'crawl' command: %v", err)
} }
err = cmd.Wait()
if err != nil {
t.Fatalf("failed to call 'wait' for crawl: %v", err)
}
// make sure that the output is not empty // make sure that the output is not empty
if len(output) <= 0 { if len(buf.Bytes()) <= 0 {
t.Fatalf("expected the 'crawl' output to not be empty") t.Fatalf("expected the 'crawl' output to not be empty")
} }
} }
func TestListCommand(t *testing.T) { func TestListCommand(t *testing.T) {
// TODO: need magellan binary to test command
var ( var (
cmd *exec.Cmd err error
err error cmd *exec.Cmd
output []byte
) )
// set up the emulator to run before test // set up the emulator to run before test
err = waitUntilEmulatorIsReady() err = waitUntilEmulatorIsReady()
if err != nil { if err != nil {
t.Fatalf("failed to start emulator: %v", err) t.Fatalf("failed while waiting for emulator: %v", err)
} }
// set up temporary directory // set up temporary directory
cmd = exec.Command("bash", "-c", fmt.Sprintf("%s list", *exePath)) cmd = exec.Command("bash", "-c", fmt.Sprintf("%s list", *exePath))
output, err = cmd.CombinedOutput() err = cmd.Start()
if err != nil { if err != nil {
t.Fatalf("failed to run 'list' command: %v", err) t.Fatalf("failed to run 'list' command: %v", err)
} }
// NOTE: the output of `list` can be empty if no scan has been performed
// make sure that the output is not empty
if len(output) <= 0 {
t.Fatalf("expected the 'list' output to not be empty")
}
} }
@ -161,28 +156,23 @@ func TestUpdateCommand(t *testing.T) {
// TODO: add test that does a Redfish simple update checking it success and // TODO: add test that does a Redfish simple update checking it success and
// failure points // failure points
var ( var (
cmd *exec.Cmd cmd *exec.Cmd
err error err error
output []byte
) )
// set up the emulator to run before test // set up the emulator to run before test
err = waitUntilEmulatorIsReady() err = waitUntilEmulatorIsReady()
if err != nil { if err != nil {
t.Fatalf("failed to start emulator: %v", err) t.Fatalf("failed while waiting for emulator: %v", err)
} }
// set up temporary directory // set up temporary directory
cmd = exec.Command("bash", "-c", fmt.Sprintf("%s list", *exePath)) cmd = exec.Command("bash", "-c", fmt.Sprintf("%s update", *exePath))
output, err = cmd.CombinedOutput() err = cmd.Start()
if err != nil { if err != nil {
t.Fatalf("failed to run 'list' command: %v", err) t.Fatalf("failed to run 'update' command: %v", err)
} }
// make sure that the output is not empty
if len(output) <= 0 {
t.Fatalf("expected the 'list' output to not be empty")
}
} }
func TestGofishFunctions(t *testing.T) { func TestGofishFunctions(t *testing.T) {
@ -193,9 +183,8 @@ func TestGofishFunctions(t *testing.T) {
// TestGenerateHosts() tests creating a collection of hosts by changing arguments // TestGenerateHosts() tests creating a collection of hosts by changing arguments
// and calling GenerateHostsWithSubnet(). // and calling GenerateHostsWithSubnet().
func TestGenerateHosts(t *testing.T) { func TestGenerateHosts(t *testing.T) {
// TODO: add test to generate hosts using a collection of subnets/masks
var ( var (
subnet = "127.0.0.1" subnet = "172.23.0.0"
subnetMask = &net.IPMask{255, 255, 255, 0} subnetMask = &net.IPMask{255, 255, 255, 0}
ports = []int{443} ports = []int{443}
scheme = "https" scheme = "https"
@ -221,7 +210,7 @@ func TestGenerateHosts(t *testing.T) {
}) })
t.Run("generate-hosts-with-subnet-mask", func(t *testing.T) { t.Run("generate-hosts-with-subnet-mask", func(t *testing.T) {
subnetMask = &net.IPMask{255, 255, 125, 0} subnetMask = &net.IPMask{255, 255, 0, 0}
hosts = magellan.GenerateHostsWithSubnet(subnet, subnetMask, ports, scheme) hosts = magellan.GenerateHostsWithSubnet(subnet, subnetMask, ports, scheme)
// check for at least one host to be generated // check for at least one host to be generated
@ -232,29 +221,74 @@ func TestGenerateHosts(t *testing.T) {
} }
func startEmulatorInBackground(path string) (int, error) {
// try and start the emulator in the background if arg passed
var (
cmd *exec.Cmd
err error
)
if path != "" {
cmd = exec.Command("bash", "-c", path)
err = cmd.Start()
if err != nil {
return -1, fmt.Errorf("failed while executing emulator startup script: %v", err)
}
} else {
return -1, fmt.Errorf("path to emulator start up script is required")
}
return cmd.Process.Pid, nil
}
// waitUntilEmulatorIsReady() polls with // waitUntilEmulatorIsReady() polls with
func waitUntilEmulatorIsReady() error { func waitUntilEmulatorIsReady() error {
var ( var (
interval = time.Second * 5 interval = time.Second * 5
timeout = time.Second * 60 timeout = time.Second * 15
testClient = &http.Client{} testClient = &http.Client{
body client.HTTPBody Transport: &http.Transport{
header client.HTTPHeader TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
err error },
}
body client.HTTPBody
header client.HTTPHeader
err error
) )
err = util.CheckUntil(interval, timeout, func() (bool, error) { err = util.CheckUntil(interval, timeout, func() (bool, error) {
// send request to host until we get expected response // send request to host until we get expected response
res, _, err := client.MakeRequest(testClient, "http://127.0.0.1", http.MethodPost, body, header) res, _, err := client.MakeRequest(testClient, "https://172.23.0.2:5000/redfish/v1/", http.MethodGet, body, header)
if err != nil { if err != nil {
return false, fmt.Errorf("failed to start emulator: %w", err) return false, fmt.Errorf("failed to make request to emulator: %w", err)
} }
if res == nil { if res == nil {
return false, fmt.Errorf("response returned nil") return false, fmt.Errorf("invalid response from emulator (response is nil)")
} }
if res.StatusCode == http.StatusOK { if res.StatusCode == http.StatusOK {
return true, nil return true, nil
} else {
return false, fmt.Errorf("unexpected status code %d", res.StatusCode)
} }
return false, nil
}) })
return err return err
} }
func init() {
var (
cwd string
err error
)
// get the current working directory
cwd, err = os.Getwd()
if err != nil {
log.Error().Err(err).Msg("failed to get working directory")
}
fmt.Printf("cwd: %s\n", cwd)
// start emulator in the background before running tests
pid, err := startEmulatorInBackground(*emuPath)
if err != nil {
log.Error().Err(err).Msg("failed to start emulator in background")
os.Exit(1)
}
_ = pid
}

View file

@ -7,6 +7,7 @@
package tests package tests
import ( import (
"crypto/tls"
"encoding/json" "encoding/json"
"flag" "flag"
"fmt" "fmt"
@ -18,9 +19,9 @@ import (
) )
var ( var (
host = flag.String("host", "localhost", "set the BMC host") host = flag.String("host", "https://172.23.0.2:5000", "set the BMC host")
username = flag.String("username", "", "set the BMC username used for the tests") username = flag.String("username", "root", "set the BMC username used for the tests")
password = flag.String("password", "", "set the BMC password used for the tests") password = flag.String("password", "root_password", "set the BMC password used for the tests")
) )
func checkResponse(res *http.Response, b []byte) error { func checkResponse(res *http.Response, b []byte) error {
@ -35,7 +36,7 @@ func checkResponse(res *http.Response, b []byte) error {
} }
// make sure the response body is in a valid JSON format // make sure the response body is in a valid JSON format
if json.Valid(b) { if !json.Valid(b) {
return fmt.Errorf("expected response body to be valid JSON") return fmt.Errorf("expected response body to be valid JSON")
} }
return nil return nil
@ -44,11 +45,24 @@ func checkResponse(res *http.Response, b []byte) error {
// Simple test to fetch the base Redfish URL and assert a 200 OK response. // Simple test to fetch the base Redfish URL and assert a 200 OK response.
func TestRedfishV1ServiceRootAvailability(t *testing.T) { func TestRedfishV1ServiceRootAvailability(t *testing.T) {
var ( var (
url = fmt.Sprintf("%s/redfish/v1", *host) url = fmt.Sprintf("%s/redfish/v1/", *host)
body = []byte{} body = []byte{}
headers = map[string]string{} headers = map[string]string{}
testClient = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
err error
) )
res, b, err := client.MakeRequest(nil, url, http.MethodGet, body, headers)
// set up the emulator to run before test
err = waitUntilEmulatorIsReady()
if err != nil {
t.Fatalf("failed while waiting for emulator: %v", err)
}
res, b, err := client.MakeRequest(testClient, url, http.MethodGet, body, headers)
if err != nil { if err != nil {
t.Fatalf("failed to make request to BMC node: %v", err) t.Fatalf("failed to make request to BMC node: %v", err)
} }
@ -63,13 +77,19 @@ func TestRedfishV1ServiceRootAvailability(t *testing.T) {
// Simple test to ensure an expected Redfish version minimum requirement. // Simple test to ensure an expected Redfish version minimum requirement.
func TestRedfishV1Version(t *testing.T) { func TestRedfishV1Version(t *testing.T) {
var ( var (
url string = fmt.Sprintf("%s/redfish/v1", *host) url string = fmt.Sprintf("%s/redfish/v1/", *host)
body client.HTTPBody = []byte{} body client.HTTPBody = []byte{}
headers client.HTTPHeader = map[string]string{} headers client.HTTPHeader = map[string]string{}
err error testClient = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
},
}
root map[string]any
err error
) )
res, b, err := client.MakeRequest(nil, url, http.MethodGet, body, headers) res, b, err := client.MakeRequest(testClient, url, http.MethodGet, body, headers)
if err != nil { if err != nil {
t.Fatalf("failed to make request to BMC node: %v", err) t.Fatalf("failed to make request to BMC node: %v", err)
} }
@ -77,6 +97,17 @@ func TestRedfishV1Version(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("failed to check response for redfish version: %v", err) t.Fatalf("failed to check response for redfish version: %v", err)
} }
// check the "RedfishVersion" from service root
err = json.Unmarshal(b, &root)
if err != nil {
t.Fatalf("failed to unmarshal redfish response: %v", err)
}
_, ok := root["RedfishVersion"]
if !ok {
t.Fatalf("failed to get 'RedfishVersion' from service root")
}
} }
// Crawls a BMC node and checks that we're able to query certain properties // Crawls a BMC node and checks that we're able to query certain properties
@ -89,6 +120,12 @@ func TestExpectedOutput(t *testing.T) {
t.Fatal("invalid host (host is nil)") t.Fatal("invalid host (host is nil)")
} }
// set up the emulator to run before test
err := waitUntilEmulatorIsReady()
if err != nil {
t.Fatalf("failed while waiting for emulator: %v", err)
}
systems, err := crawler.CrawlBMC( systems, err := crawler.CrawlBMC(
crawler.CrawlerConfig{ crawler.CrawlerConfig{
URI: *host, URI: *host,
@ -117,8 +154,5 @@ func TestExpectedOutput(t *testing.T) {
if len(system.EthernetInterfaces) <= 0 { if len(system.EthernetInterfaces) <= 0 {
t.Errorf("no ethernet interfaces found for system '%s'", system.Name) t.Errorf("no ethernet interfaces found for system '%s'", system.Name)
} }
if len(system.NetworkInterfaces) <= 0 {
t.Errorf("no network interfaces found for system '%s'", system.Name)
}
} }
} }