Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reuse archives & refactor archive checks + some fixes #264

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 46 additions & 78 deletions test/integration/bugs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,10 @@ package integration
import (
"context"
"fmt"
"regexp"
"reflect"
"testing"
"time"

"k8s.io/api/certificates/v1beta1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
Expand All @@ -23,6 +22,9 @@ const knownFileSuffixesInsideArchiveRegex string = `(` +

//https://bugzilla.redhat.com/show_bug.cgi?id=1841057
func TestUploadNotDelayedAfterStart(t *testing.T) {
/* TODO Result is irellevant as at this point IO was already restarted
this test would most likely fail and it's known issue, better solution is needed, skipping now*/
t.Skip()
LogChecker(t).Timeout(30 * time.Second).Search(`It is safe to use fast upload`)
time1 := logLineTime(t, `Reporting status periodically to .* every`)
time2 := logLineTime(t, `Successfully reported id=`)
Expand Down Expand Up @@ -160,148 +162,114 @@ func TestUnreachableHost(t *testing.T) {
t.Log(errDegraded)
}

func genLatestArchiveCheckPattern(prettyName string, check func(*testing.T, string, []string, *regexp.Regexp) error, pattern string) func(t *testing.T) {
func genLatestArchiveCheckPattern(prettyName string, check archiveCheck, archive []string, patterns ...string) test {
return func(t *testing.T) {
err := latestArchiveCheckFiles(t, prettyName, check, pattern)
if err != nil {
t.Fatal(err)
if len(patterns) == 0 {
t.Fatal(prettyName, ": No patterns to check")
}
for _, pattern := range patterns {
err := checkArchiveFiles(t, prettyName, check, pattern, archive)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just minor - would it make sense to move the checkArchiveFiles (and probably also the latestArchiveFiles) function to bugs_test.go?
I am not very experienced with Go tests and testing, but the main_test.go looks more like some test utils file (if it is so then we can leave these functions there) .

Copy link
Member Author

@psimovec psimovec Nov 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand it as test utils file now too, checkArchiveFiles could make sense to move to bugs.go, I don't think so about latestArchiveFiles (I could want to import it to different test file).. But it would make sense to move all the util functions from main.go to different files, as it starts getting unnecessarily big, and it's not very readable what main.go is.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(should be done in different PR)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @psimovec on this one. For now, it is fine, but it is starting to become a huge and not readable file.

if err != nil {
t.Error(err)
}
}
}
}

func latestArchiveContainsConfigMaps(t *testing.T) {
configMaps, _ := clientset.CoreV1().ConfigMaps("openshift-config").List(context.Background(), metav1.ListOptions{})
if len(configMaps.Items) == 0 {
t.Fatal("Nothing to test: no config maps in openshift-config namespace")
}
for _, configMap := range configMaps.Items {
configMapPath := fmt.Sprintf("^config/configmaps/%s/.*$", configMap.Name)
err := latestArchiveCheckFiles(t, "config map", matchingFileExists, configMapPath)
if err != nil {
t.Error(err)
}
func parsePatterns(pattern string, list interface{}) (names []string) {
s := reflect.ValueOf(list)
for i := 0; i < s.Len(); i++ {
names = append(names, fmt.Sprintf(pattern, s.Index(i).FieldByName("Name")))
}
return
}

func genLatestArchiveContainsConfigMaps(archive []string) test {
configMaps, _ := clientset.CoreV1().ConfigMaps("openshift-config").List(context.Background(), metav1.ListOptions{})
return genLatestArchiveCheckPattern("config map", matchingFileExists, archive, parsePatterns("^config/configmaps/%s/.*$", configMaps.Items)...)
}

func latestArchiveContainsNodes(t *testing.T) {
func genLatestArchiveContainsNodes(archive []string) test {
Nodes, _ := clientset.CoreV1().Nodes().List(context.Background(), metav1.ListOptions{})
if len(Nodes.Items) == 0 {
t.Fatal("Nothing to test: api doesn't return any nodes")
}
for _, node := range Nodes.Items {
configMapPath := fmt.Sprintf("^config/node/%s\\.json$", node.Name)
err := latestArchiveCheckFiles(t, "node", matchingFileExists, configMapPath)
if err != nil {
t.Error(err)
}
}
return genLatestArchiveCheckPattern("node", matchingFileExists, archive, parsePatterns("^config/node/%s\\.json$", Nodes.Items)...)
}

func TestArchiveContains(t *testing.T) {
defer ChangeReportTimeInterval(t, 1)()
defer degradeOperatorMonitoring(t)()

checker := LogChecker(t).Timeout(2 * time.Minute)
checker.SinceNow().Search(`Recording events/openshift-monitoring`)
checker.EnableSinceLastCheck().Search(`Wrote \d+ records to disk in \d+`)
archive := latestArchiveFiles(t)

//https://bugzilla.redhat.com/show_bug.cgi?id=1825756
t.Run("ConfigMaps", latestArchiveContainsConfigMaps)
t.Run("ConfigMaps", genLatestArchiveContainsConfigMaps(archive))

//https://bugzilla.redhat.com/show_bug.cgi?id=1885930
t.Run("ServiceAccounts",
genLatestArchiveCheckPattern(
"service accounts", matchingFileExists,
"service accounts", matchingFileExists, archive,
`^config/serviceaccounts\.json$`))

//https://bugzilla.redhat.com/show_bug.cgi?id=1834677
t.Run("ImageRegistry",
genLatestArchiveCheckPattern(
"image registry", matchingFileExists,
"image registry", matchingFileExists, archive,
`^config/imageregistry\.json$`))

//https://bugzilla.redhat.com/show_bug.cgi?id=1873101
t.Run("SnapshotsCRD",
genLatestArchiveCheckPattern(
"snapshots CRD", matchingFileExists,
"snapshots CRD", matchingFileExists, archive,
`^config/crd/volumesnapshots\.snapshot\.storage\.k8s\.io\.json$`))

defer ChangeReportTimeInterval(t, 1)()
defer degradeOperatorMonitoring(t)()

checker := LogChecker(t).Timeout(2 * time.Minute)
checker.SinceNow().Search(`Recording events/openshift-monitoring`)
checker.EnableSinceLastCheck().Search(`Wrote \d+ records to disk in \d+`)

//https://bugzilla.redhat.com/show_bug.cgi?id=1868165
t.Run("Nodes", latestArchiveContainsNodes)
t.Run("Nodes", genLatestArchiveContainsNodes(archive))

//https://bugzilla.redhat.com/show_bug.cgi?id=1881816
t.Run("MachineSet",
genLatestArchiveCheckPattern(
"machine set", matchingFileExists,
"machine set", matchingFileExists, archive,
`^machinesets/.*\.json$`))

//https://bugzilla.redhat.com/show_bug.cgi?id=1881905
t.Run("PodDisruptionBudgets",
genLatestArchiveCheckPattern(
"pod disruption budgets", matchingFileExists,
"pod disruption budgets", matchingFileExists, archive,
`^config/pdbs/.*\.json$`))

//https://bugzilla.redhat.com/show_bug.cgi?id=1835090
t.Run("csr",
genLatestArchiveCheckPattern(
"csr", matchingFileExists,
"csr", matchingFileExists, archive,
`^config/certificatesigningrequests/.*\.json$`))

//https://bugzilla.redhat.com/show_bug.cgi?id=1879068
t.Run("HostsSubnet",
genLatestArchiveCheckPattern(
"hosts subnet", matchingFileExists,
"hosts subnet", matchingFileExists, archive,
`^config/hostsubnet/.*\.json$`))

//https://bugzilla.redhat.com/show_bug.cgi?id=1838973
t.Run("Logs",
genLatestArchiveCheckPattern(
"log", matchingFileExists,
"log", matchingFileExists, archive,
`^config/pod/openshift-monitoring/logs/.*\.log$`))

//https://bugzilla.redhat.com/show_bug.cgi?id=1767719
t.Run("Event",
genLatestArchiveCheckPattern(
"event", matchingFileExists,
"event", matchingFileExists, archive,
`^events/openshift-monitoring\.json$`))

//https://bugzilla.redhat.com/show_bug.cgi?id=1840012
t.Run("FileExtensions",
genLatestArchiveCheckPattern(
"extension of", allFilesMatch,
"extension of", allFilesMatch, archive,
knownFileSuffixesInsideArchiveRegex))
}

//https://bugzilla.redhat.com/show_bug.cgi?id=1835090
func TestCSRCollected(t *testing.T) {
certificateRequest := []byte(`-----BEGIN CERTIFICATE REQUEST-----
MIIBYzCCAQgCAQAwMDEuMCwGA1UEAxMlbXktcG9kLm15LW5hbWVzcGFjZS5wb2Qu
Y2x1c3Rlci5sb2NhbDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABKhgwkNZ1uTb
DKKwJAh9TmmpSXKlbogxqV8e0yjIa2tKHZScAiZwTw920d6PLIU984ivWYfez/gq
ATGDLWuX+Y2gdjB0BgkqhkiG9w0BCQ4xZzBlMGMGA1UdEQRcMFqCJW15LXN2Yy5t
eS1uYW1lc3BhY2Uuc3ZjLmNsdXN0ZXIubG9jYWyCJW15LXBvZC5teS1uYW1lc3Bh
Y2UucG9kLmNsdXN0ZXIubG9jYWyHBMAAAhiHBAoAIgIwCgYIKoZIzj0EAwIDSQAw
RgIhAIPCUx9FdzX1iDGxH9UgYJE07gfG+J3ObR31IHhmi+WwAiEAtzN35zYkXEaC
YLluQUO+Jy/PjOnMPw5+DeSX6asUgXE=
-----END CERTIFICATE REQUEST-----`)
name := "my-svc.my-namespace"
_, err := clientset.CertificatesV1beta1().CertificateSigningRequests().Create(context.Background(), &v1beta1.CertificateSigningRequest{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{Name: name},
Spec: v1beta1.CertificateSigningRequestSpec{Request: certificateRequest},
Status: v1beta1.CertificateSigningRequestStatus{},
}, metav1.CreateOptions{})
e(t, err, "Failed creating certificate signing request")
defer func() {
clientset.CertificatesV1beta1().CertificateSigningRequests().Delete(context.Background(), name, metav1.DeleteOptions{})
restartInsightsOperator(t)
}()
defer ChangeReportTimeInterval(t, 1)()
LogChecker(t).SinceNow().Search(`Uploaded report successfully in`)
certificatePath := `^config/certificatesigningrequests/my-svc.my-namespace.json$`
err = latestArchiveCheckFiles(t, "certificate request", matchingFileExists, certificatePath)
e(t, err, "")
}

// https://bugzilla.redhat.com/show_bug.cgi?id=1782151
func TestClusterDefaultNodeSelector(t *testing.T) {
// set default selector of node-role.kubernetes.io/worker
Expand Down
68 changes: 40 additions & 28 deletions test/integration/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ const (
var clientset = kubeClient()
var configClient = configV1Client()

type test = func(t *testing.T)
type archiveCheck = func(*testing.T, string, []string, *regexp.Regexp) error

func kubeconfig() (config *restclient.Config) {
kubeconfig, ok := os.LookupEnv("KUBECONFIG") // variable is a path to the local kubeconfig
if !ok {
Expand Down Expand Up @@ -312,10 +315,14 @@ func degradeOperatorMonitoring(t *testing.T) func() {
}

func changeReportTimeInterval(t *testing.T, newInterval []byte) []byte {
supportSecret, _ := clientset.CoreV1().Secrets(OpenShiftConfig).Get(context.Background(), Support, metav1.GetOptions{})
supportSecret, err := clientset.CoreV1().Secrets(OpenShiftConfig).Get(context.Background(), Support, metav1.GetOptions{})
e(t, err, "could not get support secret")
previousInterval := supportSecret.Data["interval"]
if previousInterval == nil {
t.Fatal("missing secret with name", Support)
}
psimovec marked this conversation as resolved.
Show resolved Hide resolved
supportSecret.Data["interval"] = newInterval
err := forceUpdateSecret(OpenShiftConfig, Support, supportSecret)
err = forceUpdateSecret(OpenShiftConfig, Support, supportSecret)
e(t, err, "changing report time interval failed")
restartInsightsOperator(t)
t.Log("forcing update secret")
Expand All @@ -335,45 +342,50 @@ func latestArchiveFiles(t *testing.T) []string {
return strings.Split(stdout, "\n")
}

func allFilesMatch(t *testing.T, prettyName string, files []string, regex *regexp.Regexp) error {
for _, file := range files {
if !regex.MatchString(file) {
t.Errorf(`%s file "%s" does not match pattern "%s"`, prettyName, file, regex.String())
var (
allFilesMatch archiveCheck = func(t *testing.T, prettyName string, files []string, regex *regexp.Regexp) error {
for _, file := range files {
if !regex.MatchString(file) {
t.Errorf(`%s file "%s" does not match pattern "%s"`, prettyName, file, regex.String())
}
}
return nil
}
return nil
}

func matchingFileExists(t *testing.T, prettyName string, files []string, regex *regexp.Regexp) error {
count := 0
for _, file := range files {
if regex.MatchString(file) {
count++
matchingFileExists archiveCheck = func(t *testing.T, prettyName string, files []string, regex *regexp.Regexp) error {
count := 0
for _, file := range files {
if regex.MatchString(file) {
count++
}
}

word := "files"
suffix := ""
if count == 1 {
word = "file"
suffix = "es"
}
}
t.Logf("%d %s %s match%s pattern `%s`", count, prettyName, word, suffix, regex.String())

word := "files"
suffix := ""
if count == 1 {
word = "file"
suffix = "es"
if count != 0 {
return nil
}
return fmt.Errorf("did not find any (%s)file matching %s", prettyName, regex.String())
}
t.Logf("%d %s %s match%s pattern `%s`", count, prettyName, word, suffix, regex.String())
)

if count != 0 {
return nil
func checkArchiveFiles(t *testing.T, prettyName string, check archiveCheck, pattern string, archiveFiles []string) error {
if archiveFiles == nil {
archiveFiles = latestArchiveFiles(t)
}
return fmt.Errorf("did not find any (%s)file matching %s", prettyName, regex.String())
}

func latestArchiveCheckFiles(t *testing.T, prettyName string, check func(*testing.T, string, []string, *regexp.Regexp) error, pattern string) error {
latestFiles := latestArchiveFiles(t)
if len(latestFiles) == 0 {
if len(archiveFiles) == 0 {
t.Fatal("No files in archive to check")
}
regex, err := regexp.Compile(pattern)
e(t, err, "failed to compile pattern")
return check(t, prettyName, latestFiles, regex)
return check(t, prettyName, archiveFiles, regex)
}

func TestMain(m *testing.M) {
Expand Down