Introducing acceptance test (#222)

This commit is contained in:
RoyUP9
2021-08-18 10:22:45 +03:00
committed by GitHub
parent 5d5c11c37c
commit db1f4458c5
13 changed files with 370 additions and 16 deletions

2
acceptanceTests/Makefile Normal file
View File

@@ -0,0 +1,2 @@
test: ## Run acceptance tests.
@go test ./...

3
acceptanceTests/go.mod Normal file
View File

@@ -0,0 +1,3 @@
module github.com/up9inc/mizu/tests
go 1.16

48
acceptanceTests/setup.sh Normal file
View File

@@ -0,0 +1,48 @@
#!/bin/bash
PREFIX=$HOME/local/bin
VERSION=v1.22.0
echo "Attempting to install minikube and assorted tools to $PREFIX"
if ! [ -x "$(command -v kubectl)" ]; then
echo "Installing kubectl version $VERSION"
curl -LO "https://storage.googleapis.com/kubernetes-release/release/$VERSION/bin/linux/amd64/kubectl"
chmod +x kubectl
mv kubectl "$PREFIX"
else
echo "kubetcl is already installed"
fi
if ! [ -x "$(command -v minikube)" ]; then
echo "Installing minikube version $VERSION"
curl -Lo minikube https://storage.googleapis.com/minikube/releases/$VERSION/minikube-linux-amd64
chmod +x minikube
mv minikube "$PREFIX"
else
echo "minikube is already installed"
fi
echo "Starting minikube..."
minikube start
echo "Creating mizu tests namespace"
kubectl create namespace mizu-tests
echo "Creating httpbin deployment"
kubectl create deployment httpbin --image=kennethreitz/httpbin -n mizu-tests
echo "Creating httpbin service"
kubectl expose deployment httpbin --type=NodePort --port=80 -n mizu-tests
echo "Starting proxy"
kubectl proxy --port=8080 &
echo "Setting minikube docker env"
eval $(minikube docker-env)
echo "Build agent image"
make build-docker-ci
echo "Build cli"
make build-cli-ci

125
acceptanceTests/tap_test.go Normal file
View File

@@ -0,0 +1,125 @@
package acceptanceTests
import (
"fmt"
"io/ioutil"
"os/exec"
"testing"
"time"
)
func TestTapAndFetch(t *testing.T) {
if testing.Short() {
t.Skip("ignored acceptance test")
}
tests := []int{1, 100}
for _, entriesCount := range tests {
t.Run(fmt.Sprintf("%d", entriesCount), func(t *testing.T) {
cliPath, cliPathErr := GetCliPath()
if cliPathErr != nil {
t.Errorf("failed to get cli path, err: %v", cliPathErr)
return
}
tapCmdArgs := GetDefaultTapCommandArgs()
tapCmd := exec.Command(cliPath, tapCmdArgs...)
t.Logf("running command: %v", tapCmd.String())
t.Cleanup(func() {
if err := CleanupCommand(tapCmd); err != nil {
t.Logf("failed to cleanup tap command, err: %v", err)
}
})
if err := tapCmd.Start(); err != nil {
t.Errorf("failed to start tap command, err: %v", err)
return
}
time.Sleep(30 * time.Second)
proxyUrl := "http://localhost:8080/api/v1/namespaces/mizu-tests/services/httpbin/proxy/get"
for i := 0; i < entriesCount; i++ {
if _, requestErr := ExecuteHttpRequest(proxyUrl); requestErr != nil {
t.Errorf("failed to send proxy request, err: %v", requestErr)
return
}
}
time.Sleep(5 * time.Second)
timestamp := time.Now().UnixNano() / int64(time.Millisecond)
entriesUrl := fmt.Sprintf("http://localhost:8899/mizu/api/entries?limit=%v&operator=lt&timestamp=%v", entriesCount, timestamp)
requestResult, requestErr := ExecuteHttpRequest(entriesUrl)
if requestErr != nil {
t.Errorf("failed to get entries, err: %v", requestErr)
return
}
entries, ok := requestResult.([]interface{})
if !ok {
t.Errorf("invalid entries type")
return
}
if len(entries) != entriesCount {
t.Errorf("unexpected entries result - Expected: %v, actual: %v", entriesCount, len(entries))
return
}
entry, ok := entries[0].(map[string]interface{})
if !ok {
t.Errorf("invalid entry type")
return
}
entryUrl := fmt.Sprintf("http://localhost:8899/mizu/api/entries/%v", entry["id"])
requestResult, requestErr = ExecuteHttpRequest(entryUrl)
if requestErr != nil {
t.Errorf("failed to get entry, err: %v", requestErr)
return
}
if requestResult == nil {
t.Errorf("unexpected nil entry result")
return
}
fetchCmdArgs := GetDefaultFetchCommandArgs()
fetchCmd := exec.Command(cliPath, fetchCmdArgs...)
t.Logf("running command: %v", fetchCmd.String())
t.Cleanup(func() {
if err := CleanupCommand(fetchCmd); err != nil {
t.Logf("failed to cleanup fetch command, err: %v", err)
}
})
if err := fetchCmd.Start(); err != nil {
t.Errorf("failed to start fetch command, err: %v", err)
return
}
time.Sleep(5 * time.Second)
harBytes, readFileErr := ioutil.ReadFile("./unknown_source.har")
if readFileErr != nil {
t.Errorf("failed to read har file, err: %v", readFileErr)
return
}
harEntries, err := GetEntriesFromHarBytes(harBytes)
if err != nil {
t.Errorf("failed to get entries from har, err: %v", err)
return
}
if len(harEntries) != entriesCount {
t.Errorf("unexpected har entries result - Expected: %v, actual: %v", entriesCount, len(harEntries))
return
}
})
}
}

View File

@@ -0,0 +1,113 @@
package acceptanceTests
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"os/exec"
"path"
"syscall"
)
func GetCliPath() (string, error) {
dir, filePathErr := os.Getwd()
if filePathErr != nil {
return "", filePathErr
}
cliPath := path.Join(dir, "../cli/bin/mizu_ci")
return cliPath, nil
}
func GetDefaultCommandArgs() []string {
setFlag := "--set"
telemetry := "telemetry=false"
return []string{setFlag, telemetry}
}
func GetDefaultTapCommandArgs() []string {
tapCommand := "tap"
setFlag := "--set"
namespaces := "tap.namespaces=mizu-tests"
agentImage := "agent-image=gcr.io/up9-docker-hub/mizu/ci:0.0.0"
imagePullPolicy := "image-pull-policy=Never"
defaultCmdArgs := GetDefaultCommandArgs()
return append([]string{tapCommand, setFlag, namespaces, setFlag, agentImage, setFlag, imagePullPolicy}, defaultCmdArgs...)
}
func GetDefaultFetchCommandArgs() []string {
tapCommand := "fetch"
defaultCmdArgs := GetDefaultCommandArgs()
return append([]string{tapCommand}, defaultCmdArgs...)
}
func JsonBytesToInterface(jsonBytes []byte) (interface{}, error) {
var result interface{}
if parseErr := json.Unmarshal(jsonBytes, &result); parseErr != nil {
return nil, parseErr
}
return result, nil
}
func ExecuteHttpRequest(url string) (interface{}, error) {
response, requestErr := http.Get(url)
if requestErr != nil {
return nil, requestErr
} else if response.StatusCode != 200 {
return nil, fmt.Errorf("invalid status code %v", response.StatusCode)
}
data, readErr := ioutil.ReadAll(response.Body)
if readErr != nil {
return nil, readErr
}
return JsonBytesToInterface(data)
}
func CleanupCommand(cmd *exec.Cmd) error {
if err := cmd.Process.Signal(syscall.SIGQUIT); err != nil {
return err
}
if err := cmd.Wait(); err != nil {
return err
}
return nil
}
func GetEntriesFromHarBytes(harBytes []byte) ([]interface{}, error){
harInterface, convertErr := JsonBytesToInterface(harBytes)
if convertErr != nil {
return nil, convertErr
}
har, ok := harInterface.(map[string]interface{})
if !ok {
return nil, errors.New("invalid har type")
}
harLogInterface := har["log"]
harLog, ok := harLogInterface.(map[string]interface{})
if !ok {
return nil, errors.New("invalid har log type")
}
harEntriesInterface := harLog["entries"]
harEntries, ok := harEntriesInterface.([]interface{})
if !ok {
return nil, errors.New("invalid har entries type")
}
return harEntries, nil
}