Skip to content

Commit

Permalink
acceptance-tests: Add timestamps to logs (hashicorp#672)
Browse files Browse the repository at this point in the history
Add timestamps to logs printed out by tests
Bump terratest library to the latest version to include
Break up framework package into smaller packages
       * Move suite related code to the suite package
        * Move config-related code to the config package
        * Move test environment and test context related code to the environment package
        * Move consul cluster creation code to the consul package
        * Move flags to the flags package
        * Move the helpers package to framework/helpers
        * New logging code is all in the logger package
  • Loading branch information
ishustava authored Nov 12, 2020
1 parent 65aeb67 commit 208ee40
Show file tree
Hide file tree
Showing 41 changed files with 865 additions and 718 deletions.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package framework
package config

import (
"fmt"
Expand All @@ -8,6 +8,10 @@ import (
"gopkg.in/yaml.v2"
)

// The path to the helm chart.
// Note: this will need to be changed if this file is moved.
const HelmChartPath = "../../../.."

// TestConfig holds configuration for the test suite
type TestConfig struct {
Kubeconfig string
Expand Down Expand Up @@ -68,7 +72,7 @@ func (t *TestConfig) HelmValuesFromConfig() (map[string]string, error) {
// and sets global.image to the consul enterprise image with that version.
func (t *TestConfig) entImage() (string, error) {
if t.helmChartPath == "" {
t.helmChartPath = helmChartPath
t.helmChartPath = HelmChartPath
}

// Unmarshal Chart.yaml to get appVersion (i.e. Consul version)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package framework
package config

import (
"testing"
Expand Down Expand Up @@ -90,7 +90,7 @@ func TestConfig_HelmValuesFromConfig_EntImage(t *testing.T) {
cfg := TestConfig{
EnableEnterprise: true,
// We need to set a different path because these tests are run from a different directory.
helmChartPath: "../../..",
helmChartPath: "../../../..",
}
values, err := cfg.HelmValuesFromConfig()
require.NoError(t, err)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package framework
package consul

import (
"context"
Expand All @@ -8,21 +8,20 @@ import (
"testing"

"github.com/gruntwork-io/terratest/modules/helm"
"github.com/gruntwork-io/terratest/modules/k8s"
"github.com/gruntwork-io/terratest/modules/logger"
"github.com/hashicorp/consul-helm/test/acceptance/helpers"
terratestk8s "github.com/gruntwork-io/terratest/modules/k8s"
terratestLogger "github.com/gruntwork-io/terratest/modules/logger"
"github.com/hashicorp/consul-helm/test/acceptance/framework/config"
"github.com/hashicorp/consul-helm/test/acceptance/framework/environment"
"github.com/hashicorp/consul-helm/test/acceptance/framework/helpers"
"github.com/hashicorp/consul-helm/test/acceptance/framework/k8s"
"github.com/hashicorp/consul-helm/test/acceptance/framework/logger"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/sdk/freeport"
"github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
)

// The path to the helm chart.
// Note: this will need to be changed if this file is moved.
const helmChartPath = "../../../.."

// Cluster represents a consul cluster object
type Cluster interface {
Create(t *testing.T)
Expand All @@ -37,19 +36,20 @@ type Cluster interface {
// HelmCluster implements Cluster and uses Helm
// to create, destroy, and upgrade consul
type HelmCluster struct {
ctx TestContext
ctx environment.TestContext
helmOptions *helm.Options
releaseName string
kubernetesClient kubernetes.Interface
noCleanupOnFailure bool
debugDirectory string
logger terratestLogger.TestLogger
}

func NewHelmCluster(
t *testing.T,
helmValues map[string]string,
ctx TestContext,
cfg *TestConfig,
ctx environment.TestContext,
cfg *config.TestConfig,
releaseName string) Cluster {

// Deploy single-server cluster by default unless helmValues overwrites that
Expand All @@ -64,10 +64,12 @@ func NewHelmCluster(
mergeMaps(values, valuesFromConfig)
mergeMaps(values, helmValues)

logger := terratestLogger.New(logger.TestLogger{})

opts := &helm.Options{
SetValues: values,
KubectlOptions: ctx.KubectlOptions(t),
Logger: logger.TestingT,
Logger: logger,
}
return &HelmCluster{
ctx: ctx,
Expand All @@ -76,6 +78,7 @@ func NewHelmCluster(
kubernetesClient: ctx.KubernetesClient(t),
noCleanupOnFailure: cfg.NoCleanupOnFailure,
debugDirectory: cfg.DebugDirectory,
logger: logger,
}
}

Expand All @@ -91,16 +94,15 @@ func (h *HelmCluster) Create(t *testing.T) {
// Fail if there are any existing installations of the Helm chart.
h.checkForPriorInstallations(t)

err := helm.InstallE(t, h.helmOptions, helmChartPath, h.releaseName)
require.NoError(t, err)
helm.Install(t, h.helmOptions, config.HelmChartPath, h.releaseName)

helpers.WaitForAllPodsToBeReady(t, h.kubernetesClient, h.helmOptions.KubectlOptions.Namespace, fmt.Sprintf("release=%s", h.releaseName))
}

func (h *HelmCluster) Destroy(t *testing.T) {
t.Helper()

helpers.WritePodsDebugInfoIfFailed(t, h.helmOptions.KubectlOptions, h.debugDirectory, "release="+h.releaseName)
k8s.WritePodsDebugInfoIfFailed(t, h.helmOptions.KubectlOptions, h.debugDirectory, "release="+h.releaseName)

// Ignore the error returned by the helm delete here so that we can
// always idempotently clean up resources in the cluster.
Expand Down Expand Up @@ -174,7 +176,7 @@ func (h *HelmCluster) Upgrade(t *testing.T, helmValues map[string]string) {
t.Helper()

mergeMaps(h.helmOptions.SetValues, helmValues)
helm.Upgrade(t, h.helmOptions, helmChartPath, h.releaseName)
helm.Upgrade(t, h.helmOptions, config.HelmChartPath, h.releaseName)
helpers.WaitForAllPodsToBeReady(t, h.kubernetesClient, h.helmOptions.KubectlOptions.Namespace, fmt.Sprintf("release=%s", h.releaseName))
}

Expand All @@ -183,7 +185,7 @@ func (h *HelmCluster) SetupConsulClient(t *testing.T, secure bool) *api.Client {

namespace := h.helmOptions.KubectlOptions.Namespace
config := api.DefaultConfig()
localPort := freeport.MustTake(1)[0]
localPort := terratestk8s.GetAvailablePort(t)
remotePort := 8500 // use non-secure by default

if secure {
Expand Down Expand Up @@ -212,7 +214,13 @@ func (h *HelmCluster) SetupConsulClient(t *testing.T, secure bool) *api.Client {
}
}

tunnel := k8s.NewTunnel(h.helmOptions.KubectlOptions, k8s.ResourceTypePod, fmt.Sprintf("%s-consul-server-0", h.releaseName), localPort, remotePort)
tunnel := terratestk8s.NewTunnelWithLogger(
h.helmOptions.KubectlOptions,
terratestk8s.ResourceTypePod,
fmt.Sprintf("%s-consul-server-0", h.releaseName),
localPort,
remotePort,
h.logger)
tunnel.ForwardPort(t)

t.Cleanup(func() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package framework
package consul

import (
"testing"

"github.com/gruntwork-io/terratest/modules/k8s"
"github.com/hashicorp/consul-helm/test/acceptance/framework/config"
"github.com/stretchr/testify/require"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
Expand All @@ -19,7 +20,7 @@ func TestNewHelmCluster(t *testing.T) {
"server.bootstrapExpect": "3",
"server.replicas": "3",
}
cluster := NewHelmCluster(t, helmValues, &ctx{}, &TestConfig{ConsulImage: "test-config-image"}, "test")
cluster := NewHelmCluster(t, helmValues, &ctx{}, &config.TestConfig{ConsulImage: "test-config-image"}, "test")

require.Equal(t, cluster.(*HelmCluster).helmOptions.SetValues, helmValues)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package framework
package environment

import (
"fmt"
"testing"

"github.com/gruntwork-io/terratest/modules/k8s"
"github.com/hashicorp/consul-helm/test/acceptance/helpers"
"github.com/hashicorp/consul-helm/test/acceptance/framework/config"
"github.com/hashicorp/consul-helm/test/acceptance/framework/helpers"
"github.com/stretchr/testify/require"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
Expand All @@ -30,15 +31,15 @@ type TestContext interface {
KubernetesClient(t *testing.T) kubernetes.Interface
}

type kubernetesEnvironment struct {
type KubernetesEnvironment struct {
contexts map[string]*kubernetesContext
}

func newKubernetesEnvironmentFromConfig(config *TestConfig) *kubernetesEnvironment {
func NewKubernetesEnvironmentFromConfig(config *config.TestConfig) *KubernetesEnvironment {
defaultContext := NewContext(config.KubeNamespace, config.Kubeconfig, config.KubeContext)

// Create a kubernetes environment with default context.
kenv := &kubernetesEnvironment{
kenv := &KubernetesEnvironment{
contexts: map[string]*kubernetesContext{
DefaultContextName: defaultContext,
},
Expand All @@ -52,14 +53,14 @@ func newKubernetesEnvironmentFromConfig(config *TestConfig) *kubernetesEnvironme
return kenv
}

func (k *kubernetesEnvironment) Context(t *testing.T, name string) TestContext {
func (k *KubernetesEnvironment) Context(t *testing.T, name string) TestContext {
ctx, ok := k.contexts[name]
require.Truef(t, ok, fmt.Sprintf("requested context %s not found", name))

return ctx
}

func (k *kubernetesEnvironment) DefaultContext(t *testing.T) TestContext {
func (k *KubernetesEnvironment) DefaultContext(t *testing.T) TestContext {
ctx, ok := k.contexts[DefaultContextName]
require.Truef(t, ok, "default context not found")

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package framework
package flags

import (
"errors"
"flag"
"sync"

"github.com/hashicorp/consul-helm/test/acceptance/framework/config"
)

type TestFlags struct {
Expand Down Expand Up @@ -77,7 +79,7 @@ func (t *TestFlags) init() {
"such as logs and pod definitions. If not provided, a temporary directory will be created by the tests.")
}

func (t *TestFlags) validate() error {
func (t *TestFlags) Validate() error {
if t.flagEnableMultiCluster {
if t.flagSecondaryKubecontext == "" && t.flagSecondaryKubeconfig == "" {
return errors.New("at least one of -secondary-kubecontext or -secondary-kubeconfig flags must be provided if -enable-multi-cluster is set")
Expand All @@ -93,10 +95,10 @@ func (t *TestFlags) validate() error {
return nil
}

func (t *TestFlags) testConfigFromFlags() *TestConfig {
func (t *TestFlags) TestConfigFromFlags() *config.TestConfig {
tempDir := t.flagDebugDirectory

return &TestConfig{
return &config.TestConfig{
Kubeconfig: t.flagKubeconfig,
KubeContext: t.flagKubecontext,
KubeNamespace: t.flagNamespace,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package framework
package flags

import (
"testing"
Expand Down Expand Up @@ -115,7 +115,7 @@ func TestFlags_validate(t *testing.T) {
flagEnterpriseLicenseSecretName: tt.fields.flagEntLicenseSecretName,
flagEnterpriseLicenseSecretKey: tt.fields.flagEntLicenseSecretKey,
}
err := tf.validate()
err := tf.Validate()
if tt.wantErr {
require.EqualError(t, err, tt.errMessage)
} else {
Expand Down
Loading

0 comments on commit 208ee40

Please sign in to comment.