Skip to content

Commit

Permalink
[receiver/mysqlreceiver] Add integration test (#6916)
Browse files Browse the repository at this point in the history
* Add integration test

* Update Changelog

* Add to test modules
  • Loading branch information
Mrod1598 authored Dec 21, 2021
1 parent 6e055ca commit 36a284a
Show file tree
Hide file tree
Showing 8 changed files with 693 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
## 💡 Enhancements 💡

- `prometheusremotewriteexporter`: Handling Staleness flag from OTLP (#6679)
- `mysqlreceiver`: Add Integration test (#6916)
- `datadogexporter`: Add compatibility with ECS Fargate semantic conventions (#6670)

## 🛑 Breaking changes 🛑
Expand Down
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ INTEGRATION_TEST_MODULES := \
receiver/kafkametricsreceiver \
receiver/nginxreceiver \
receiver/memcachedreceiver \
receiver/mysqlreceiver \
internal/common \
extension/observer/dockerobserver

Expand Down
32 changes: 32 additions & 0 deletions receiver/mysqlreceiver/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.6.1 // indirect
github.com/spf13/cast v1.4.1 // indirect
github.com/testcontainers/testcontainers-go v0.12.0
go.opencensus.io v0.23.0 // indirect
go.opentelemetry.io/otel v1.3.0 // indirect
go.opentelemetry.io/otel/metric v0.26.0 // indirect
Expand All @@ -33,4 +34,35 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)

require (
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 // indirect
github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3 // indirect
github.com/Microsoft/hcsshim v0.8.16 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68 // indirect
github.com/containerd/containerd v1.5.0-beta.4 // indirect
github.com/docker/distribution v2.7.1+incompatible // indirect
github.com/docker/docker v20.10.11+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/magiconair/properties v1.8.5 // indirect
github.com/moby/sys/mount v0.2.0 // indirect
github.com/moby/sys/mountinfo v0.5.0 // indirect
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.1 // indirect
github.com/opencontainers/runc v1.0.2 // indirect
github.com/sirupsen/logrus v1.8.1 // indirect
golang.org/x/net v0.0.0-20211108170745-6635138e15ea // indirect
golang.org/x/sys v0.0.0-20211109184856-51b60fd695b3 // indirect
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08 // indirect
google.golang.org/grpc v1.43.0 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

replace github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest => ../../internal/scrapertest
455 changes: 455 additions & 0 deletions receiver/mysqlreceiver/go.sum

Large diffs are not rendered by default.

149 changes: 149 additions & 0 deletions receiver/mysqlreceiver/integration_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
// Copyright The OpenTelemetry Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build integration
// +build integration

package mysqlreceiver

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

"github.com/stretchr/testify/require"
"github.com/testcontainers/testcontainers-go"
"github.com/testcontainers/testcontainers-go/wait"
"go.opentelemetry.io/collector/component/componenttest"
"go.opentelemetry.io/collector/consumer/consumertest"

"github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest"
"github.com/open-telemetry/opentelemetry-collector-contrib/internal/scrapertest/golden"
"github.com/open-telemetry/opentelemetry-collector-contrib/receiver/mysqlreceiver/internal/metadata"
)

func TestMySqlIntegration(t *testing.T) {
t.Run("Running mysql version 8.0", func(t *testing.T) {
t.Parallel()
container := getContainer(t, containerRequest8_0)
defer func() {
require.NoError(t, container.Terminate(context.Background()))
}()
hostname, err := container.Host(context.Background())
require.NoError(t, err)

f := NewFactory()
cfg := f.CreateDefaultConfig().(*Config)
cfg.Endpoint = net.JoinHostPort(hostname, "3306")
cfg.Username = "otel"
cfg.Password = "otel"

consumer := new(consumertest.MetricsSink)
settings := componenttest.NewNopReceiverCreateSettings()
rcvr, err := f.CreateMetricsReceiver(context.Background(), settings, cfg, consumer)
require.NoError(t, err, "failed creating metrics receiver")
require.NoError(t, rcvr.Start(context.Background(), componenttest.NewNopHost()))
require.Eventuallyf(t, func() bool {
return len(consumer.AllMetrics()) > 0
}, 2*time.Minute, 1*time.Second, "failed to receive more than 0 metrics")

md := consumer.AllMetrics()[0]
require.Equal(t, 1, md.ResourceMetrics().Len())
ilms := md.ResourceMetrics().At(0).InstrumentationLibraryMetrics()
require.Equal(t, 1, ilms.Len())
metrics := ilms.At(0).Metrics()
require.NoError(t, rcvr.Shutdown(context.Background()))

require.Equal(t, len(metadata.M.Names()), metrics.Len())
})

t.Run("Running mysql version 5.7", func(t *testing.T) {
t.Parallel()
container := getContainer(t, containerRequest5_7)
defer func() {
require.NoError(t, container.Terminate(context.Background()))
}()
hostname, err := container.Host(context.Background())
require.NoError(t, err)

f := NewFactory()
cfg := f.CreateDefaultConfig().(*Config)
cfg.Endpoint = net.JoinHostPort(hostname, "3307")
cfg.Username = "otel"
cfg.Password = "otel"

consumer := new(consumertest.MetricsSink)
settings := componenttest.NewNopReceiverCreateSettings()
rcvr, err := f.CreateMetricsReceiver(context.Background(), settings, cfg, consumer)
require.NoError(t, err, "failed creating metrics receiver")
require.NoError(t, rcvr.Start(context.Background(), componenttest.NewNopHost()))
require.Eventuallyf(t, func() bool {
return len(consumer.AllMetrics()) > 0
}, 2*time.Minute, 1*time.Second, "failed to receive more than 0 metrics")

md := consumer.AllMetrics()[0]
require.Equal(t, 1, md.ResourceMetrics().Len())
ilms := md.ResourceMetrics().At(0).InstrumentationLibraryMetrics()
require.Equal(t, 1, ilms.Len())
aMetricSlice := ilms.At(0).Metrics()
require.NoError(t, rcvr.Shutdown(context.Background()))

expectedFile := filepath.Join("testdata", "scraper", "expected.json")
expectedMetrics, err := golden.ReadMetrics(expectedFile)
require.NoError(t, err)
eMetricSlice := expectedMetrics.ResourceMetrics().At(0).InstrumentationLibraryMetrics().At(0).Metrics()

scrapertest.CompareMetricSlices(eMetricSlice, aMetricSlice, scrapertest.IgnoreValues())
})
}

var (
containerRequest5_7 = testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: path.Join(".", "testdata", "integration"),
Dockerfile: "Dockerfile.mysql.5_7",
},
ExposedPorts: []string{"3307:3306"},
WaitingFor: wait.ForListeningPort("3306").
WithStartupTimeout(2 * time.Minute),
}
containerRequest8_0 = testcontainers.ContainerRequest{
FromDockerfile: testcontainers.FromDockerfile{
Context: path.Join(".", "testdata", "integration"),
Dockerfile: "Dockerfile.mysql.8_0",
},
ExposedPorts: []string{"3306:3306"},
WaitingFor: wait.ForListeningPort("3306").
WithStartupTimeout(2 * time.Minute),
}
)

func getContainer(t *testing.T, req testcontainers.ContainerRequest) testcontainers.Container {
require.NoError(t, req.Validate())
container, err := testcontainers.GenericContainer(
context.Background(),
testcontainers.GenericContainerRequest{
ContainerRequest: req,
Started: true,
})
require.NoError(t, err)

code, err := container.Exec(context.Background(), []string{"/setup.sh"})
require.NoError(t, err)
require.Equal(t, 0, code)
return container
}
13 changes: 13 additions & 0 deletions receiver/mysqlreceiver/testdata/integration/Dockerfile.mysql.5_7
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM mysql:5.7

RUN \
apt-get update && \
apt-get install -y libmariadb3

COPY scripts/setup.sh /setup.sh
RUN chmod +x /setup.sh

ENV MYSQL_DATABASE=otel
ENV MYSQL_USER=otel
ENV MYSQL_PASSWORD=otel
ENV MYSQL_ROOT_PASSWORD=otel
13 changes: 13 additions & 0 deletions receiver/mysqlreceiver/testdata/integration/Dockerfile.mysql.8_0
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM mysql:8.0

RUN \
apt-get update && \
apt-get install -y libmariadb3

COPY scripts/setup.sh /setup.sh
RUN chmod +x /setup.sh

ENV MYSQL_DATABASE=otel
ENV MYSQL_USER=otel
ENV MYSQL_PASSWORD=otel
ENV MYSQL_ROOT_PASSWORD=otel
29 changes: 29 additions & 0 deletions receiver/mysqlreceiver/testdata/integration/scripts/setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#!/usr/bin/env bash

set -e

USER="otel"
ROOT_PASS="otel"
CODE=1


setup_permissions() {
# NOTE: -pPASSWORD is missing a space on purpose
mysql -u root -p"${ROOT_PASS}" -e "GRANT PROCESS ON *.* TO ${USER}" > /dev/null
mysql -u root -p"${ROOT_PASS}" -e "GRANT SELECT ON INFORMATION_SCHEMA.INNODB_METRICS TO ${USER}" > /dev/null
mysql -u root -p"${ROOT_PASS}" -e "FLUSH PRIVILEGES" > /dev/null
}

echo "Configuring ${USER} permissions. . ."
end=$((SECONDS+60))
while [ $SECONDS -lt $end ]; do
result="$?"
if setup_permissions; then
echo "Permissions configured!"
exit 0
fi
echo "Trying again in 5 seconds. . ."
sleep 5
done

echo "Failed to configure permissions"

0 comments on commit 36a284a

Please sign in to comment.