Skip to content

Commit

Permalink
etcd_docker 1: Refactor resources/docker package into resources/docke…
Browse files Browse the repository at this point in the history
…rexternal, resources/dockerm3, x/dockertest (#4145) (#4153)

PR 1 of etcd test refactor

I am introducing a docker based etcd test framework. Overall structure I'm going for:

resources/dockerm3 -- m3 docker containers
resources/dockerexternal -- dependencies (prometheus, etcd)

The reason I need this refactor: I'm going to pull the dockerexternal package into a bunch of internal tests. This introduces circular dependencies with the M3 resources, thus splitting out here.

commit-id:f922a2aa
  • Loading branch information
andrewmains12 authored Mar 24, 2023
1 parent b1f9424 commit c46a4c6
Show file tree
Hide file tree
Showing 15 changed files with 318 additions and 201 deletions.
12 changes: 6 additions & 6 deletions src/integration/prometheus/prometheus.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import (
"github.com/m3db/m3/src/dbnode/generated/thrift/rpc"
"github.com/m3db/m3/src/dbnode/kvconfig"
"github.com/m3db/m3/src/integration/resources"
"github.com/m3db/m3/src/integration/resources/docker"
"github.com/m3db/m3/src/integration/resources/docker/dockerexternal"
"github.com/m3db/m3/src/query/api/v1/handler/database"
"github.com/m3db/m3/src/query/api/v1/options"
"github.com/m3db/m3/src/query/generated/proto/prompb"
Expand Down Expand Up @@ -89,7 +89,7 @@ func RunTest(t *testing.T, m3 resources.M3Resources, prom resources.ExternalReso

logger.Info("running prometheus tests")

p := prom.(*docker.Prometheus)
p := prom.(*dockerexternal.Prometheus)

testPrometheusRemoteRead(t, p, logger)
testPrometheusRemoteWriteMultiNamespaces(t, p, logger)
Expand Down Expand Up @@ -118,15 +118,15 @@ func RunTest(t *testing.T, m3 resources.M3Resources, prom resources.ExternalReso
testDebugPromReturnsDuplicates(t, m3, logger)
}

func testPrometheusRemoteRead(t *testing.T, p *docker.Prometheus, logger *zap.Logger) {
func testPrometheusRemoteRead(t *testing.T, p *dockerexternal.Prometheus, logger *zap.Logger) {
// Ensure Prometheus can proxy a Prometheus query
logger.Info("testing prometheus remote read")
verifyPrometheusQuery(t, p, "prometheus_remote_storage_samples_total", 100)
}

func testPrometheusRemoteWriteMultiNamespaces(
t *testing.T,
p *docker.Prometheus,
p *dockerexternal.Prometheus,
logger *zap.Logger,
) {
logger.Info("testing remote write to multiple namespaces")
Expand Down Expand Up @@ -1839,9 +1839,9 @@ func requireSeriesSuccess(
}))
}

func verifyPrometheusQuery(t *testing.T, p *docker.Prometheus, query string, threshold float64) {
func verifyPrometheusQuery(t *testing.T, p *dockerexternal.Prometheus, query string, threshold float64) {
require.NoError(t, resources.Retry(func() error {
res, err := p.Query(docker.PrometheusQueryRequest{
res, err := p.Query(dockerexternal.PrometheusQueryRequest{
Query: query,
})
if err != nil {
Expand Down
13 changes: 8 additions & 5 deletions src/integration/prometheus/prometheus_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
//go:build cluster_integration
// +build cluster_integration

//
// Copyright (c) 2021 Uber Technologies, Inc.
//
Expand All @@ -23,12 +25,13 @@
package prometheus

import (
"context"
"path"
"runtime"
"testing"

"github.com/m3db/m3/src/integration/resources"
"github.com/m3db/m3/src/integration/resources/docker"
"github.com/m3db/m3/src/integration/resources/docker/dockerexternal"
"github.com/m3db/m3/src/integration/resources/inprocess"

"github.com/ory/dockertest/v3"
Expand Down Expand Up @@ -60,14 +63,14 @@ func testSetup(t *testing.T) (resources.M3Resources, resources.ExternalResources
require.NoError(t, err)

_, filename, _, _ := runtime.Caller(0)
prom := docker.NewPrometheus(docker.PrometheusOptions{
prom := dockerexternal.NewPrometheus(dockerexternal.PrometheusOptions{
Pool: pool,
PathToCfg: path.Join(path.Dir(filename), "../resources/docker/config/prometheus.yml"),
PathToCfg: path.Join(path.Dir(filename), "../resources/docker/dockerexternal/config/prometheus.yml"),
})
require.NoError(t, prom.Setup())
require.NoError(t, prom.Setup(context.TODO()))

return m3, prom, func() {
assert.NoError(t, prom.Close())
assert.NoError(t, prom.Close(context.TODO()))
assert.NoError(t, m3.Cleanup())
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) 2021 Uber Technologies, Inc.
// Copyright (c) 2021 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
Expand All @@ -18,7 +18,7 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package docker
package dockerexternal

import (
"context"
Expand All @@ -29,9 +29,10 @@ import (
"net/http"
"time"

"github.com/m3db/m3/src/integration/resources"
xdockertest "github.com/m3db/m3/src/x/dockertest"
"github.com/m3db/m3/src/x/instrument"

"github.com/cenkalti/backoff/v3"
"github.com/ory/dockertest/v3"
"github.com/prometheus/common/model"
)
Expand All @@ -42,7 +43,7 @@ type Prometheus struct {
pathToCfg string
iOpts instrument.Options

resource *Resource
resource *xdockertest.Resource
}

// PrometheusOptions contains the options for
Expand All @@ -60,7 +61,7 @@ type PrometheusOptions struct {

// NewPrometheus creates a new docker-backed Prometheus
// that implements the resources.ExternalResources interface.
func NewPrometheus(opts PrometheusOptions) resources.ExternalResources {
func NewPrometheus(opts PrometheusOptions) *Prometheus {
if opts.InstrumentOptions == nil {
opts.InstrumentOptions = instrument.NewOptions()
}
Expand All @@ -72,19 +73,19 @@ func NewPrometheus(opts PrometheusOptions) resources.ExternalResources {
}

// Setup is a method that setups up the prometheus instance.
func (p *Prometheus) Setup() error {
func (p *Prometheus) Setup(ctx context.Context) error {
if p.resource != nil {
return errors.New("prometheus already setup. must close resource " +
"before attempting to setup again")
}

if err := SetupNetwork(p.pool); err != nil {
if err := xdockertest.SetupNetwork(p.pool, true); err != nil {
return err
}

res, err := NewDockerResource(p.pool, ResourceOptions{
res, err := xdockertest.NewDockerResource(p.pool, xdockertest.ResourceOptions{
ContainerName: "prometheus",
Image: Image{
Image: xdockertest.Image{
Name: "prom/prometheus",
Tag: "latest",
},
Expand All @@ -100,11 +101,12 @@ func (p *Prometheus) Setup() error {

p.resource = res

return p.waitForHealthy()
return p.waitForHealthy(ctx)
}

func (p *Prometheus) waitForHealthy() error {
return resources.Retry(func() error {
func (p *Prometheus) waitForHealthy(ctx context.Context) error {
retrier := backoff.WithContext(backoff.NewExponentialBackOff(), ctx)
return backoff.Retry(func() error {
req, err := http.NewRequestWithContext(
context.Background(),
http.MethodGet,
Expand All @@ -126,7 +128,7 @@ func (p *Prometheus) waitForHealthy() error {
}

return errors.New("prometheus not ready")
})
}, retrier)
}

// PrometheusQueryRequest contains the parameters for making a query request.
Expand All @@ -152,7 +154,7 @@ func (p *PrometheusQueryRequest) String() string {
// Query executes a query request against the prometheus resource.
func (p *Prometheus) Query(req PrometheusQueryRequest) (model.Vector, error) {
if p.resource.Closed() {
return nil, errClosed
return nil, xdockertest.ErrClosed
}

r, err := http.NewRequestWithContext(
Expand Down Expand Up @@ -201,9 +203,9 @@ type vectorResult struct {
}

// Close cleans up the prometheus instance.
func (p *Prometheus) Close() error {
func (p *Prometheus) Close(context.Context) error {
if p.resource.Closed() {
return errClosed
return xdockertest.ErrClosed
}

if err := p.resource.Close(); err != nil {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// +build integration_v2
// Copyright (c) 2021 Uber Technologies, Inc.
// Copyright (c) 2021 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
Expand All @@ -19,9 +18,12 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package docker
//go:build integration_v2

package dockerexternal

import (
"context"
"path"
"runtime"
"testing"
Expand All @@ -39,6 +41,6 @@ func TestNewPrometheus(t *testing.T) {
Pool: pool,
PathToCfg: path.Join(path.Dir(filename), "config/prometheus.yml"),
})
require.NoError(t, prom.Setup())
require.NoError(t, prom.Close())
require.NoError(t, prom.Setup(context.TODO()))
require.NoError(t, prom.Close(context.TODO()))
}
29 changes: 29 additions & 0 deletions src/integration/resources/docker/dockerm3/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) 2022 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package dockerm3

import (
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

// zapMethod appends the method as a log field.
func zapMethod(s string) zapcore.Field { return zap.String("method", s) }
Loading

0 comments on commit c46a4c6

Please sign in to comment.