Skip to content

Commit

Permalink
Add elixir based test (#938)
Browse files Browse the repository at this point in the history
  • Loading branch information
grcevski authored Jun 17, 2024
1 parent c04a1e7 commit e9581d0
Show file tree
Hide file tree
Showing 4 changed files with 162 additions and 0 deletions.
6 changes: 6 additions & 0 deletions test/integration/configs/instrumenter-config-elixir.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
routes:
patterns:
- /test/:test_id
unmatched: path
otel_metrics_export:
endpoint: http://otelcol:4318
81 changes: 81 additions & 0 deletions test/integration/docker-compose-elixir.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
version: '3.8'

services:
testserver:
build:
context: ../..
dockerfile: test/integration/components/elixir/Dockerfile
image: hatest-testserver-elixir
ports:
- "4000:4000"
depends_on:
otelcol:
condition: service_started

autoinstrumenter:
build:
context: ../..
dockerfile: ./test/integration/components/beyla/Dockerfile
command:
- --config=/configs/instrumenter-config-elixir.yml
volumes:
- ./configs/:/configs
- ./system/sys/kernel/security:/sys/kernel/security
- ../../testoutput:/coverage
- ../../testoutput/run:/var/run/beyla
image: hatest-autoinstrumenter
privileged: true # in some environments (not GH Pull Requests) you can set it to false and then cap_add: [ SYS_ADMIN ]
network_mode: "service:testserver"
pid: "service:testserver"
environment:
GOCOVERDIR: "/coverage"
BEYLA_PRINT_TRACES: "true"
BEYLA_OPEN_PORT: "4000"
BEYLA_DISCOVERY_POLL_INTERVAL: 500ms
BEYLA_SERVICE_NAMESPACE: "integration-test"
BEYLA_METRICS_INTERVAL: "10ms"
BEYLA_BPF_BATCH_TIMEOUT: "10ms"
BEYLA_LOG_LEVEL: "DEBUG"
BEYLA_BPF_DEBUG: "TRUE"
BEYLA_METRICS_REPORT_TARGET: "true"
BEYLA_METRICS_REPORT_PEER: "true"
BEYLA_HOSTNAME: "beyla"
depends_on:
testserver:
condition: service_started

# OpenTelemetry Collector
otelcol:
image: otel/opentelemetry-collector-contrib:0.85.0
container_name: otel-col
deploy:
resources:
limits:
memory: 125M
restart: unless-stopped
command: [ "--config=/etc/otelcol-config/otelcol-config.yml" ]
volumes:
- ./configs/:/etc/otelcol-config
ports:
- "4317" # OTLP over gRPC receiver
- "4318:4318" # OTLP over HTTP receiver
- "9464" # Prometheus exporter
- "8888" # metrics endpoint
depends_on:
prometheus:
condition: service_started

# Prometheus
prometheus:
image: quay.io/prometheus/prometheus:v2.46.0
container_name: prometheus
command:
- --storage.tsdb.retention.time=1m
- --config.file=/etc/prometheus/prometheus-config.yml
- --storage.tsdb.path=/prometheus
- --web.enable-lifecycle
- --web.route-prefix=/
volumes:
- ./configs/:/etc/prometheus
ports:
- "9090:9090"
65 changes: 65 additions & 0 deletions test/integration/red_test_elixir.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
//go:build integration

package integration

import (
"fmt"
"testing"

"github.com/mariomac/guara/pkg/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/grafana/beyla/test/integration/components/prom"
)

// does a smoke test to verify that all the components that started
// asynchronously for the Elixir test are up and communicating properly
func waitForElixirTestComponents(t *testing.T, url string) {
waitForTestComponentsSub(t, url, "/smoke")
}

func testREDMetricsForElixirHTTPLibrary(t *testing.T, url string, comm string) {
path := "/test"

pq := prom.Client{HostPort: prometheusHostPort}
var results []prom.Result

// Call 4 times the instrumented service, forcing it to:
// - process multiple calls in a row with, one more than we might need
// - returning a 200 code
for i := 0; i < 4; i++ {
doHTTPGet(t, fmt.Sprintf("%s%s/%d", url, path, i), 200)
}

// Eventually, Prometheus would make this query visible
test.Eventually(t, testTimeout, func(t require.TestingT) {
var err error
results, err = pq.Query(`http_server_request_duration_seconds_count{` +
`http_request_method="GET",` +
`http_response_status_code="200",` +
`service_namespace="integration-test",` +
`service_name="` + comm + `",` +
`http_route="/test/:test_id"}`)
require.NoError(t, err)
enoughPromResults(t, results)
val := totalPromCount(t, results)
assert.LessOrEqual(t, 3, val)
if len(results) > 0 {
res := results[0]
addr := res.Metric["client_address"]
assert.NotNil(t, addr)
}
})
}

func testREDMetricsElixirHTTP(t *testing.T) {
for _, testCaseURL := range []string{
"http://localhost:4000",
} {
t.Run(testCaseURL, func(t *testing.T) {
waitForElixirTestComponents(t, testCaseURL)
testREDMetricsForElixirHTTPLibrary(t, testCaseURL, "beam.smp")
})
}
}
10 changes: 10 additions & 0 deletions test/integration/suites_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,16 @@ func TestSuiteNoRoutes(t *testing.T) {
t.Run("BPF pinning folder unmounted", testBPFPinningUnmounted)
}

func TestSuite_Elixir(t *testing.T) {
compose, err := docker.ComposeSuite("docker-compose-elixir.yml", path.Join(pathOutput, "test-suite-elixir.log"))
require.NoError(t, err)
require.NoError(t, compose.Up())
t.Run("Elixir RED metrics", testREDMetricsElixirHTTP)
t.Run("BPF pinning folder mounted", testBPFPinningMounted)
require.NoError(t, compose.Close())
t.Run("BPF pinning folder unmounted", testBPFPinningUnmounted)
}

// Helpers

var lockdownPath = "/sys/kernel/security/lockdown"
Expand Down

0 comments on commit e9581d0

Please sign in to comment.