Skip to content

Commit

Permalink
PR feedback; adjust test suites to start up / spin down webhook serve…
Browse files Browse the repository at this point in the history
…r so that defaulting works as expected.

TODO for another time to extract much of the duplicated logic across the varying suite_test.go TestMain funcs
  • Loading branch information
adriankostrubiak-tomtom committed Dec 9, 2021
1 parent 5946700 commit 913738d
Show file tree
Hide file tree
Showing 7 changed files with 336 additions and 23 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,13 @@ By configuring a resource's `.Spec.UpgradeStrategy` to `none`, the operator will
The default and only other acceptable value for `.Spec.UpgradeStrategy` is `automatic`.


### `opentelemetry-operator` vs `OpenTelemetryCollector` Versioning

By default, the operator ensures consistent versioning between itself and the managed `OpenTelemetryCollector` resources. That is, if the operator is based on version `0.40.0`, it will create resources with an underlying core `opentelemetry-collector` at version `0.40.0`.

When a custom `Spec.Image` is used, the operator will not manage this versioning and upgrading. In this scenario, it is best practice that the operator version should match the underlying core version. Given a `OpenTelemetryCollector` resource with a `Spec.Image` configured to a custom image based on underlying core `opentelemetry-collector` at version `0.40.0`, it is recommended that the operator is kept at version `0.40.0`.


### Deployment modes

The `CustomResource` for the `OpenTelemetryCollector` exposes a property named `.Spec.Mode`, which can be used to specify whether the collector should run as a `DaemonSet`, `Sidecar`, or `Deployment` (default). Look at [this sample](https://github.com/open-telemetry/opentelemetry-operator/blob/main/tests/e2e/daemonset-features/00-install.yaml) for reference.
Expand Down
4 changes: 2 additions & 2 deletions apis/v1alpha1/upgrade_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ type (
)

const (
// UpgradeStrategyAutomatic specifies that the operator will automatically apply upgrades to the CR
// UpgradeStrategyAutomatic specifies that the operator will automatically apply upgrades to the CR.
UpgradeStrategyAutomatic UpgradeStrategy = "automatic"

// UpgradeStrategyNone specifies that the operator will not apply any upgrades to the CR
// UpgradeStrategyNone specifies that the operator will not apply any upgrades to the CR.
UpgradeStrategyNone UpgradeStrategy = "none"
)
84 changes: 80 additions & 4 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,46 @@
package controllers_test

import (
"context"
"crypto/tls"
"fmt"
"net"
"os"
"path/filepath"
"sync"
"testing"
"time"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/util/retry"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"

"github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
// +kubebuilder:scaffold:imports
)

var k8sClient client.Client
var testEnv *envtest.Environment
var testScheme *runtime.Scheme = scheme.Scheme
var (
k8sClient client.Client
testEnv *envtest.Environment
testScheme *runtime.Scheme = scheme.Scheme
ctx context.Context
cancel context.CancelFunc
)

func TestMain(m *testing.M) {
ctx, cancel = context.WithCancel(context.TODO())
defer cancel()

testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
WebhookInstallOptions: envtest.WebhookInstallOptions{
Paths: []string{filepath.Join("..", "config", "webhook")},
},
}

cfg, err := testEnv.Start()
if err != nil {
fmt.Printf("failed to start testEnv: %v", err)
Expand All @@ -56,6 +73,65 @@ func TestMain(m *testing.M) {
os.Exit(1)
}

// start webhook server using Manager
webhookInstallOptions := &testEnv.WebhookInstallOptions
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: testScheme,
Host: webhookInstallOptions.LocalServingHost,
Port: webhookInstallOptions.LocalServingPort,
CertDir: webhookInstallOptions.LocalServingCertDir,
LeaderElection: false,
MetricsBindAddress: "0",
})
if err != nil {
fmt.Printf("failed to start webhook server: %v", err)
os.Exit(1)
}

if err := (&v1alpha1.OpenTelemetryCollector{}).SetupWebhookWithManager(mgr); err != nil {
fmt.Printf("failed to SetupWebhookWithManager: %v", err)
os.Exit(1)
}

ctx, cancel = context.WithCancel(context.TODO())
defer cancel()
go func() {
if err = mgr.Start(ctx); err != nil {
fmt.Printf("failed to start manager: %v", err)
os.Exit(1)
}
}()

// wait for the webhook server to get ready
wg := &sync.WaitGroup{}
wg.Add(1)
dialer := &net.Dialer{Timeout: time.Second}
addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort)
go func(wg *sync.WaitGroup) {
defer wg.Done()
if err = retry.OnError(wait.Backoff{
Steps: 20,
Duration: 10 * time.Millisecond,
Factor: 1.5,
Jitter: 0.1,
Cap: time.Second * 30,
}, func(error) bool {
return true
}, func() error {
// #nosec G402
conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return err
}
_ = conn.Close()
return nil
}); err != nil {
fmt.Printf("failed to wait for webhook server to be ready: %v", err)
os.Exit(1)
}
}(wg)
wg.Wait()

code := m.Run()

err = testEnv.Stop()
Expand Down
84 changes: 80 additions & 4 deletions internal/webhookhandler/webhookhandler_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,29 +15,46 @@
package webhookhandler_test

import (
"context"
"crypto/tls"
"fmt"
"net"
"os"
"path/filepath"
"sync"
"testing"
"time"

"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/util/retry"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"

"github.com/open-telemetry/opentelemetry-operator/apis/v1alpha1"
// +kubebuilder:scaffold:imports
)

var k8sClient client.Client
var testEnv *envtest.Environment
var testScheme *runtime.Scheme = scheme.Scheme
var (
k8sClient client.Client
testEnv *envtest.Environment
testScheme *runtime.Scheme = scheme.Scheme
ctx context.Context
cancel context.CancelFunc
)

func TestMain(m *testing.M) {
ctx, cancel = context.WithCancel(context.TODO())
defer cancel()

testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "..", "config", "crd", "bases")},
WebhookInstallOptions: envtest.WebhookInstallOptions{
Paths: []string{filepath.Join("..", "..", "config", "webhook")},
},
}

cfg, err := testEnv.Start()
if err != nil {
fmt.Printf("failed to start testEnv: %v", err)
Expand All @@ -56,6 +73,65 @@ func TestMain(m *testing.M) {
os.Exit(1)
}

// start webhook server using Manager
webhookInstallOptions := &testEnv.WebhookInstallOptions
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: testScheme,
Host: webhookInstallOptions.LocalServingHost,
Port: webhookInstallOptions.LocalServingPort,
CertDir: webhookInstallOptions.LocalServingCertDir,
LeaderElection: false,
MetricsBindAddress: "0",
})
if err != nil {
fmt.Printf("failed to start webhook server: %v", err)
os.Exit(1)
}

if err := (&v1alpha1.OpenTelemetryCollector{}).SetupWebhookWithManager(mgr); err != nil {
fmt.Printf("failed to SetupWebhookWithManager: %v", err)
os.Exit(1)
}

ctx, cancel = context.WithCancel(context.TODO())
defer cancel()
go func() {
if err = mgr.Start(ctx); err != nil {
fmt.Printf("failed to start manager: %v", err)
os.Exit(1)
}
}()

// wait for the webhook server to get ready
wg := &sync.WaitGroup{}
wg.Add(1)
dialer := &net.Dialer{Timeout: time.Second}
addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort)
go func(wg *sync.WaitGroup) {
defer wg.Done()
if err = retry.OnError(wait.Backoff{
Steps: 20,
Duration: 10 * time.Millisecond,
Factor: 1.5,
Jitter: 0.1,
Cap: time.Second * 30,
}, func(error) bool {
return true
}, func() error {
// #nosec G402
conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return err
}
_ = conn.Close()
return nil
}); err != nil {
fmt.Printf("failed to wait for webhook server to be ready: %v", err)
os.Exit(1)
}
}(wg)
wg.Wait()

code := m.Run()

err = testEnv.Stop()
Expand Down
88 changes: 82 additions & 6 deletions pkg/collector/reconcile/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ package reconcile

import (
"context"
"crypto/tls"
"fmt"
"io/ioutil"
"net"
"os"
"path/filepath"
"sync"
"testing"
"time"

"github.com/stretchr/testify/assert"
v1 "k8s.io/api/core/v1"
Expand All @@ -30,8 +34,11 @@ import (
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/util/retry"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"
logf "sigs.k8s.io/controller-runtime/pkg/log"
Expand All @@ -40,23 +47,33 @@ import (
"github.com/open-telemetry/opentelemetry-operator/internal/config"
)

var k8sClient client.Client
var testEnv *envtest.Environment
var testScheme *runtime.Scheme = scheme.Scheme
var logger = logf.Log.WithName("unit-tests")
var (
k8sClient client.Client
testEnv *envtest.Environment
testScheme *runtime.Scheme = scheme.Scheme
ctx context.Context
cancel context.CancelFunc

var instanceUID = uuid.NewUUID()
logger = logf.Log.WithName("unit-tests")

instanceUID = uuid.NewUUID()
)

const (
defaultCollectorImage = "default-collector"
defaultTaAllocationImage = "default-ta-allocator"
)

func TestMain(m *testing.M) {
ctx, cancel = context.WithCancel(context.TODO())
defer cancel()

testEnv = &envtest.Environment{
CRDDirectoryPaths: []string{filepath.Join("..", "..", "..", "config", "crd", "bases")},
WebhookInstallOptions: envtest.WebhookInstallOptions{
Paths: []string{filepath.Join("..", "..", "..", "config", "webhook")},
},
}

cfg, err := testEnv.Start()
if err != nil {
fmt.Printf("failed to start testEnv: %v", err)
Expand All @@ -75,6 +92,65 @@ func TestMain(m *testing.M) {
os.Exit(1)
}

// start webhook server using Manager
webhookInstallOptions := &testEnv.WebhookInstallOptions
mgr, err := ctrl.NewManager(cfg, ctrl.Options{
Scheme: testScheme,
Host: webhookInstallOptions.LocalServingHost,
Port: webhookInstallOptions.LocalServingPort,
CertDir: webhookInstallOptions.LocalServingCertDir,
LeaderElection: false,
MetricsBindAddress: "0",
})
if err != nil {
fmt.Printf("failed to start webhook server: %v", err)
os.Exit(1)
}

if err := (&v1alpha1.OpenTelemetryCollector{}).SetupWebhookWithManager(mgr); err != nil {
fmt.Printf("failed to SetupWebhookWithManager: %v", err)
os.Exit(1)
}

ctx, cancel = context.WithCancel(context.TODO())
defer cancel()
go func() {
if err = mgr.Start(ctx); err != nil {
fmt.Printf("failed to start manager: %v", err)
os.Exit(1)
}
}()

// wait for the webhook server to get ready
wg := &sync.WaitGroup{}
wg.Add(1)
dialer := &net.Dialer{Timeout: time.Second}
addrPort := fmt.Sprintf("%s:%d", webhookInstallOptions.LocalServingHost, webhookInstallOptions.LocalServingPort)
go func(wg *sync.WaitGroup) {
defer wg.Done()
if err = retry.OnError(wait.Backoff{
Steps: 20,
Duration: 10 * time.Millisecond,
Factor: 1.5,
Jitter: 0.1,
Cap: time.Second * 30,
}, func(error) bool {
return true
}, func() error {
// #nosec G402
conn, err := tls.DialWithDialer(dialer, "tcp", addrPort, &tls.Config{InsecureSkipVerify: true})
if err != nil {
return err
}
_ = conn.Close()
return nil
}); err != nil {
fmt.Printf("failed to wait for webhook server to be ready: %v", err)
os.Exit(1)
}
}(wg)
wg.Wait()

code := m.Run()

err = testEnv.Stop()
Expand Down
Loading

0 comments on commit 913738d

Please sign in to comment.