Skip to content

Commit

Permalink
feat: add reloader scenario tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Azhovan committed Oct 13, 2023
1 parent d7d7043 commit bf91118
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 0 deletions.
74 changes: 74 additions & 0 deletions apptests/appscenarios/appscenarios.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Package appscenarios provides a set of application test scenarios that can be executed
// in a Kubernetes environment. The package defines an AppScenario interface that specifies the
// behavior and name of each scenario, and a List type that implements methods to execute, get,
// and check scenarios.
//
// The package currently supports one scenario for the reloader application, but more scenarios can be
// added by implementing the AppScenario interface and registering them in the scenariosList variable.
package appscenarios

import (
"context"
"fmt"
"path/filepath"

"github.com/mesosphere/kommander-applications/apptests/environment"
)

// AppScenario defines the behavior and name of an application test scenario
type AppScenario interface {
Execute(context.Context, *environment.Env) error // logic implemented by a scenario
Name() string // scenario name
}

type List map[string]AppScenario

// Execute runs all the scenarios in the list and returns the first error encountered, if any.
func (s List) Execute(ctx context.Context, env *environment.Env) error {
for _, sc := range s {
if err := sc.Execute(ctx, env); err != nil {
return err
}
}
return nil
}

// Get returns the associated scenario for the given application name, or nil if it does not exist.
func Get(application string) AppScenario {
s, ok := scenariosList[application]
if !ok {
return nil
}
return s
}

// Has checks if the associated scenario for the given application exist.
func Has(application string) bool {
_, ok := scenariosList[application]
return ok
}

// AbsolutePathTo returns the absolute path to the given application directory.
func AbsolutePathTo(application string) (string, error) {
dir, err := filepath.Abs(filepath.Join("../../services/", application))
if err != nil {
return "", err
}

// filepath.Glob returns a sorted slice of matching paths
matches, err := filepath.Glob(filepath.Join(dir, "*"))
if err != nil {
return "", err
}

if len(matches) == 0 {
return "", fmt.Errorf("no application directory found for %s", application)
}

return matches[0], nil
}

// This is the ScenarioList of all available scenarios.
var scenariosList = List{
"reloader": reloader{},
}
17 changes: 17 additions & 0 deletions apptests/appscenarios/appscenarios_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package appscenarios

import (
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestAbsolutePathTo(t *testing.T) {
absAppPath, err := AbsolutePathTo("reloader")
assert.NoError(t, err)

expected := filepath.Join("kommander-applications", "services", "reloader")
assert.Contains(t, absAppPath, expected)
assert.NotEmpty(t, filepath.Base(absAppPath))
}
75 changes: 75 additions & 0 deletions apptests/appscenarios/reloader.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package appscenarios

import (
"context"
"path/filepath"
"time"

fluxhelmv2beta1 "github.com/fluxcd/helm-controller/api/v2beta1"
"github.com/mesosphere/kommander-applications/apptests/environment"
"github.com/mesosphere/kommander-applications/apptests/flux"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
genericCLient "sigs.k8s.io/controller-runtime/pkg/client"
)

type reloader struct{}

func (r reloader) Name() string {
return "reloader"
}

var _ AppScenario = (*reloader)(nil)

const (
pollInterval = 2 * time.Second
kommanderNamespace = "kommander"
)

func (r reloader) Execute(ctx context.Context, env *environment.Env) error {
appPath, err := AbsolutePathTo(r.Name())
if err != nil {
return err
}

// apply defaults config maps first
defaultKustomizations := filepath.Join(appPath, "/defaults")
err = env.ApplyKustomizations(ctx, defaultKustomizations, map[string]string{
"releaseNamespace": kommanderNamespace,
})
if err != nil {
return err
}
// apply the rest of kustomizations
err = env.ApplyKustomizations(ctx, appPath, map[string]string{
"releaseNamespace": kommanderNamespace,
})
if err != nil {
return err
}

client, err := genericCLient.New(env.K8sClient.Config(), genericCLient.Options{Scheme: flux.NewScheme()})
if err != nil {
return err
}

hr := &fluxhelmv2beta1.HelmRelease{}
hr.SetName(r.Name())
hr.SetNamespace(kommanderNamespace)

err = wait.PollUntilContextCancel(ctx, pollInterval, true, func(ctx context.Context) (done bool, err error) {
err = client.Get(ctx, genericCLient.ObjectKeyFromObject(hr), hr)
if err != nil {
return false, err
}

for _, cond := range hr.Status.Conditions {
return cond.Status == metav1.ConditionTrue &&
cond.Type == fluxhelmv2beta1.ReleasedCondition, nil
}

return true, nil
})

return err
}
21 changes: 21 additions & 0 deletions apptests/appscenarios/reloader_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package appscenarios

import (
"context"
"testing"

"github.com/mesosphere/kommander-applications/apptests/environment"
"github.com/stretchr/testify/assert"
)

func TestListExecute(t *testing.T) {
env := environment.Env{}
ctx := context.Background()

err := env.Provision(ctx)
assert.NoError(t, err)

r := reloader{}
err = r.Execute(ctx, &env)
assert.NoError(t, err)
}

0 comments on commit bf91118

Please sign in to comment.