blob: 7c706117b27462fd3f608d102e56eba5cbe6f334 [file] [log] [blame]
// Package genpromcrd implements all the functionality for the genpromcrd
// command line application.
package genpromcrd
import (
"io/ioutil"
"os"
"path/filepath"
"strings"
"testing"
"github.com/otiai10/copy"
"github.com/stretchr/testify/require"
"go.skia.org/infra/go/testutils"
"go.skia.org/infra/go/testutils/unittest"
)
var alertTarget = AlertTarget{
AppGroup: "perf",
Namespace: "perfns",
Directory: "/some/sub-directory/in/the/git/checkout/",
}
func TestAlertTarget_TargetFilename_Success(t *testing.T) {
unittest.SmallTest(t)
require.Equal(t, "/some/sub-directory/in/the/git/checkout/perf_perfns_appgroup_alerts.yml", alertTarget.TargetFilename())
}
func TestAlertTarget_PodMonitoring_Success(t *testing.T) {
unittest.SmallTest(t)
expected := `apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
name: perf-perfns
spec:
selector:
matchLabels:
appgroup: perf
endpoints:
- port: prom
interval: 15s
targetLabels:
fromPod:
- from: app
- from: appgroup
`
got, err := alertTarget.PodMonitoring()
require.NoError(t, err)
require.Equal(t, expected, got)
}
func TestNameSpaceOrDefault_NoNamespaceProvided_ReturnsDefault(t *testing.T) {
unittest.SmallTest(t)
require.Equal(t, "default", NamespaceOrDefault(""))
}
func TestNameSpaceOrDefault_NamespaceProvided_ReturnsGivenNamespace(t *testing.T) {
unittest.SmallTest(t)
require.Equal(t, "foo", NamespaceOrDefault("foo"))
}
func TestGetAlertTargetsFromFilename_ContainsOneDeploymentInDefaultNamespace_Success(t *testing.T) {
unittest.MediumTest(t)
got, err := getAlertTargetsFromFilename(filepath.Join(testutils.TestDataDir(t), "deployment.yaml"))
require.NoError(t, err)
require.Len(t, got, 1)
// The key into alertTarget contains alertTarget.Directory, which will
// change based on where the code is being run, so iternate over the map to
// test the members.
for alertTarget := range got {
require.Equal(t, "perf", alertTarget.AppGroup)
require.Equal(t, "default", alertTarget.Namespace)
require.Contains(t, alertTarget.Directory, "/promk/go/genpromcrd/genpromcrd/testdata")
}
}
func TestGetAlertTargetsFromFilename_ContainsOneStatefulSetInNonDefaultNamespace_Success(t *testing.T) {
unittest.MediumTest(t)
got, err := getAlertTargetsFromFilename(filepath.Join(testutils.TestDataDir(t), "statefulset.yml"))
require.NoError(t, err)
require.Len(t, got, 1)
// The key into alertTarget contains alertTarget.Directory, which will
// change based on where the code is being run, so iternate over the map to
// test the members.
for alertTarget := range got {
require.Equal(t, "prometheus", alertTarget.AppGroup)
require.Equal(t, "prometheus", alertTarget.Namespace)
require.Contains(t, alertTarget.Directory, "/promk/go/genpromcrd/genpromcrd/testdata")
}
}
func TestGetAlertTargetsFromFilename_FileDoesNotExist_ReturnsError(t *testing.T) {
unittest.MediumTest(t)
_, err := getAlertTargetsFromFilename(filepath.Join(testutils.TestDataDir(t), "the-name-of-a-file-that-does-not-exist.yml"))
require.Error(t, err)
}
func TestGetAllAlertTargetsUnderDir_DirContainsYAMLFilesThatShouldBeSkipped_OnlyTheOneValidFileIsRead(t *testing.T) {
unittest.MediumTest(t)
// The 'fake-checkout' directory has deployment files in this tree:
//
// fake-checkout/
// ├── monitoring
// │ └── appgroups
// │ └── perf.yml
// ├── skia-infra-public
// │ └── deployment.yml
// ├── templates
// │ └── this-deployment-is-ignored.yml
// └── this-deployment-is-ignored.yaml
//
// Only the file under skia-infra-public should be read as
// getAllAlertTargetsUnderDir only looks file files under directories that
// correspond to cluster names.
alertTargets, err := getAllAlertTargetsUnderDir(filepath.Join(testutils.TestDataDir(t), "fake-checkout"))
require.NoError(t, err)
require.Len(t, alertTargets, 1)
}
func TestAppMain_NoDirectoryFlagSupplied_ReturnsError(t *testing.T) {
unittest.SmallTest(t)
require.Error(t, NewApp().Main([]string{"path/to/exe/goes/here"}))
}
func TestAppMain_DryRunOverFakeCheckout_PrintsListOfFilesWritten(t *testing.T) {
unittest.MediumTest(t)
// Setup to capture stdout.
backup := os.Stdout
defer func() {
os.Stdout = backup
}()
r, w, _ := os.Pipe()
os.Stdout = w
// Run Main with the --dryrun flag which only prints the names of the files it would write.
require.NoError(t, NewApp().Main(
[]string{
"path/to/exe/goes/here",
"--dryrun",
"--directory", filepath.Join(testutils.TestDataDir(t), "fake-checkout"),
}))
err := w.Close()
require.NoError(t, err)
out, err := ioutil.ReadAll(r)
require.NoError(t, err)
// We only expect a single file to be written.
parts := strings.Split(string(out), "\n")
require.Len(t, parts, 2)
require.Contains(t, parts[0], "/testdata/fake-checkout/skia-infra-public/perf_mytestnamespace_appgroup_alerts.yml")
require.Equal(t, "", parts[1])
}
func TestAppMain_RunOverFakeCheckout_CorrectFileContentsAreWritten(t *testing.T) {
unittest.MediumTest(t)
tmpDir := t.TempDir()
err := copy.Copy(filepath.Join(testutils.TestDataDir(t), "fake-checkout"), tmpDir)
require.NoError(t, err)
require.NoError(t, NewApp().Main(
[]string{
"path/to/exe/goes/here",
"--directory", tmpDir,
}))
newlyWrittenFilename := filepath.Join(tmpDir, "skia-infra-public/perf_mytestnamespace_appgroup_alerts.yml")
require.FileExists(t, newlyWrittenFilename)
b, err := ioutil.ReadFile(newlyWrittenFilename)
require.NoError(t, err)
expected := `apiVersion: monitoring.googleapis.com/v1
kind: Rules
metadata:
name: perf
namespace: mytestnamespace
spec:
groups:
- name: perf
interval: 30s
rules:
- alert: AlwaysFiringAlertToSeeIfAlertsAreWorking
expr: vector(1)
labels: {}
annotations: {}
- name: absent-perf
interval: 30s
rules: []
---
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
name: perf-mytestnamespace
spec:
selector:
matchLabels:
appgroup: perf
endpoints:
- port: prom
interval: 15s
targetLabels:
fromPod:
- from: app
- from: appgroup
`
require.Equal(t, expected, string(b))
}