From 11cc6b8ff00ede1667f813af1b74b82462229811 Mon Sep 17 00:00:00 2001 From: Rahul Reddy Date: Thu, 16 Jan 2025 19:20:29 +0530 Subject: [PATCH] Revert "Integration testing" --- Makefile | 14 +- tests/docker-compose-performance.yml | 70 --- tests/docker-compose.yml | 15 +- tests/perf-testing/integration/Dockerfile | 9 - .../latest_supported/01-init-extensions.sql | 5 - .../latest_supported/02-create-database.sql | 1 - .../latest_supported/03-import-data.sql | 11 - .../perf-testing/latest_supported/Dockerfile | 40 -- .../oldest_supported/01-init-extensions.sql | 5 - .../oldest_supported/02-create-database.sql | 1 - .../oldest_supported/03-import-data.sql | 11 - .../perf-testing/oldest_supported/Dockerfile | 42 -- tests/postgresql_test.go | 156 +++--- tests/postgresqlperf_test.go | 480 ------------------ tests/simulation/sim_queries.go | 164 ------ tests/testdata/blocking-sessions-schema.json | 98 ---- tests/testdata/execution-plan-schema.json | 176 ------- tests/testdata/individual-queries-schema.json | 105 ---- tests/testdata/slow-queries-schema.json | 121 ----- tests/testdata/wait-events-schema.json | 95 ---- 20 files changed, 71 insertions(+), 1548 deletions(-) delete mode 100644 tests/docker-compose-performance.yml delete mode 100644 tests/perf-testing/integration/Dockerfile delete mode 100644 tests/perf-testing/latest_supported/01-init-extensions.sql delete mode 100644 tests/perf-testing/latest_supported/02-create-database.sql delete mode 100644 tests/perf-testing/latest_supported/03-import-data.sql delete mode 100644 tests/perf-testing/latest_supported/Dockerfile delete mode 100644 tests/perf-testing/oldest_supported/01-init-extensions.sql delete mode 100644 tests/perf-testing/oldest_supported/02-create-database.sql delete mode 100644 tests/perf-testing/oldest_supported/03-import-data.sql delete mode 100644 tests/perf-testing/oldest_supported/Dockerfile delete mode 100644 tests/postgresqlperf_test.go delete mode 100644 tests/simulation/sim_queries.go delete mode 100644 tests/testdata/blocking-sessions-schema.json delete mode 100644 tests/testdata/execution-plan-schema.json delete mode 100644 tests/testdata/individual-queries-schema.json delete mode 100644 tests/testdata/slow-queries-schema.json delete mode 100644 tests/testdata/wait-events-schema.json diff --git a/Makefile b/Makefile index fdd9058b..813b69e6 100644 --- a/Makefile +++ b/Makefile @@ -30,17 +30,9 @@ test: integration-test: @echo "=== $(INTEGRATION) === [ test ]: running integration tests..." - @docker compose -f tests/docker-compose.yml up -d - @sleep 10 - @go test -v -tags=integration -count 1 ./tests/postgresql_test.go -timeout 300s || (ret=$$?; docker compose -f tests/docker-compose.yml down -v && exit $$ret) - @docker compose -f tests/docker-compose.yml down -v - @echo "=== $(INTEGRATION) === [ test ]: running integration tests for query performance monitoring..." - @echo "Starting containers for performance tests..." - @docker compose -f tests/docker-compose-performance.yml up -d - @sleep 30 - @go test -v -tags=query_performance ./tests/postgresqlperf_test.go -timeout 600s || (ret=$$?; docker compose -f tests/docker-compose-performance.yml down -v && exit $$ret) - @echo "Stopping performance test containers..." - @docker compose -f tests/docker-compose-performance.yml down -v + @docker compose -f tests/docker-compose.yml pull + @go test -v -tags=integration -count 1 ./tests/. || (ret=$$?; docker compose -f tests/docker-compose.yml down && exit $$ret) + @docker compose -f tests/docker-compose.yml down install: compile @echo "=== $(INTEGRATION) === [ install ]: installing bin/$(BINARY_NAME)..." diff --git a/tests/docker-compose-performance.yml b/tests/docker-compose-performance.yml deleted file mode 100644 index c4d0433a..00000000 --- a/tests/docker-compose-performance.yml +++ /dev/null @@ -1,70 +0,0 @@ -services: - - postgres12: - build: - context: ./perf-testing/oldest_supported/ - dockerfile: Dockerfile - container_name: "postgresql-perf-oldest" - restart: always - environment: - - POSTGRES_USER=dbuser - - POSTGRES_PASSWORD=dbpassword - - POSTGRES_DB=demo - volumes: - - postgres12:/var/lib/postgresql/data - ports: - - "6432:5432" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 10s - timeout: 5s - retries: 5 - - postgresql-latest: - build: - context: ./perf-testing/oldest_supported/ - dockerfile: Dockerfile - restart: always - container_name: "postgresql-perf-latest" - environment: - - POSTGRES_USER=dbuser - - POSTGRES_PASSWORD=dbpassword - - POSTGRES_DB=demo - volumes: - - pgdata_latest:/var/lib/postgresql/data - ports: - - "5432:5432" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 10s - timeout: 5s - retries: 5 - - postgres-without-extensions: - image: postgres:17.0 - restart: always - container_name: "postgresql-noext" - environment: - - POSTGRES_USER=dbuser - - POSTGRES_PASSWORD=dbpassword - - POSTGRES_DB=demo - volumes: - - pgdata_noext:/var/lib/postgresql/data - ports: - - "7432:5432" - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 10s - timeout: 5s - retries: 5 - - nri-postgresql: - container_name: nri_postgresql - build: - context: ../ - dockerfile: tests/perf-testing/integration/Dockerfile - -volumes: - pgdata_latest: - postgres12: - pgdata_noext: diff --git a/tests/docker-compose.yml b/tests/docker-compose.yml index 34de26f0..64f39d91 100644 --- a/tests/docker-compose.yml +++ b/tests/docker-compose.yml @@ -2,7 +2,6 @@ services: postgres-9-6: image: postgres:9.6 restart: always - container_name: postgres-9-6 environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: example @@ -11,14 +10,18 @@ services: postgres-latest-supported: image: postgres:17.0 restart: always - container_name: postgres-latest-supported environment: POSTGRES_USER: postgres POSTGRES_PASSWORD: example POSTGRES_DB: demo nri-postgresql: - container_name: nri-postgresql - build: - context: ../ - dockerfile: tests/perf-testing/integration/Dockerfile \ No newline at end of file + image: golang:1.23.4-bookworm + container_name: nri_postgresql + working_dir: /code + depends_on: + - postgres-9-6 + - postgres-latest-supported + volumes: + - ../:/code + entrypoint: go run /code/src/main.go diff --git a/tests/perf-testing/integration/Dockerfile b/tests/perf-testing/integration/Dockerfile deleted file mode 100644 index 9ee00f4b..00000000 --- a/tests/perf-testing/integration/Dockerfile +++ /dev/null @@ -1,9 +0,0 @@ -FROM golang:1.23.4-bookworm as builder -ARG CGO_ENABLED=0 -WORKDIR /go/src/github.com/newrelic/nri-postgresql -COPY . . -RUN make clean compile - -FROM alpine:latest -COPY --from=builder /go/src/github.com/newrelic/nri-postgresql/bin / -CMD ["sleep", "1h"] \ No newline at end of file diff --git a/tests/perf-testing/latest_supported/01-init-extensions.sql b/tests/perf-testing/latest_supported/01-init-extensions.sql deleted file mode 100644 index 66210525..00000000 --- a/tests/perf-testing/latest_supported/01-init-extensions.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE EXTENSION IF NOT EXISTS pg_stat_statements; - -CREATE EXTENSION IF NOT EXISTS pg_wait_sampling; - -CREATE EXTENSION IF NOT EXISTS pg_stat_monitor; \ No newline at end of file diff --git a/tests/perf-testing/latest_supported/02-create-database.sql b/tests/perf-testing/latest_supported/02-create-database.sql deleted file mode 100644 index e053c036..00000000 --- a/tests/perf-testing/latest_supported/02-create-database.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE DATABASE titanic; \ No newline at end of file diff --git a/tests/perf-testing/latest_supported/03-import-data.sql b/tests/perf-testing/latest_supported/03-import-data.sql deleted file mode 100644 index 28cc43b2..00000000 --- a/tests/perf-testing/latest_supported/03-import-data.sql +++ /dev/null @@ -1,11 +0,0 @@ --- Connect to titanic database -\c titanic; - --- Import the titanic.sql file that was downloaded during Docker build -\i /docker-entrypoint-initdb.d/titanic.sql; - -GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO dbuser; -GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO dbuser; - --- Analyze tables for better query planning -ANALYZE VERBOSE; diff --git a/tests/perf-testing/latest_supported/Dockerfile b/tests/perf-testing/latest_supported/Dockerfile deleted file mode 100644 index ffc0530f..00000000 --- a/tests/perf-testing/latest_supported/Dockerfile +++ /dev/null @@ -1,40 +0,0 @@ -FROM postgres:17.0 - -# Dependencies -RUN apt-get update && apt-get install -y \ - build-essential \ - git \ - wget \ - postgresql-server-dev-17 \ - && rm -rf /var/lib/apt/lists/* - -# Postgres Docker Images copy contents of postgresql.conf.sample to postgresql.conf during initialization -# COPY custom.conf /usr/share/postgresql/postgresql.conf.sample -- DO NOT USE -RUN echo "shared_preload_libraries = 'pg_stat_statements,pg_wait_sampling,pg_stat_monitor'" >> /usr/share/postgresql/postgresql.conf.sample -RUN echo "pg_stat_statements.track = all" >> /usr/share/postgresql/postgresql.conf.sample -RUN echo "pg_stat_statements.save = on" >> /usr/share/postgresql/postgresql.conf.sample -RUN echo "pg_stat_monitor.pgsm_enable_query_plan = on" >> /usr/share/postgresql/postgresql.conf.sample - -# Install pg_wait_sampling -RUN git clone https://github.com/postgrespro/pg_wait_sampling.git \ - && cd pg_wait_sampling \ - && make USE_PGXS=1 \ - && make USE_PGXS=1 install \ - && cd .. \ - && rm -rf pg_wait_sampling - -# Install pg_stat_monitor -RUN git clone https://github.com/percona/pg_stat_monitor.git \ - && cd pg_stat_monitor \ - && make USE_PGXS=1 \ - && make USE_PGXS=1 install \ - && cd .. \ - && rm -rf pg_stat_monitor - -# Download the titanic database -RUN wget https://raw.githubusercontent.com/neondatabase/postgres-sample-dbs/main/titanic.sql -P /docker-entrypoint-initdb.d/ - -# Enable the extensions and setup the titanic database -COPY 01-init-extensions.sql /docker-entrypoint-initdb.d/01-init-extensions.sql -COPY 02-create-database.sql /docker-entrypoint-initdb.d/02-create-database.sql -COPY 03-import-data.sql /docker-entrypoint-initdb.d/03-import-data.sql \ No newline at end of file diff --git a/tests/perf-testing/oldest_supported/01-init-extensions.sql b/tests/perf-testing/oldest_supported/01-init-extensions.sql deleted file mode 100644 index 66210525..00000000 --- a/tests/perf-testing/oldest_supported/01-init-extensions.sql +++ /dev/null @@ -1,5 +0,0 @@ -CREATE EXTENSION IF NOT EXISTS pg_stat_statements; - -CREATE EXTENSION IF NOT EXISTS pg_wait_sampling; - -CREATE EXTENSION IF NOT EXISTS pg_stat_monitor; \ No newline at end of file diff --git a/tests/perf-testing/oldest_supported/02-create-database.sql b/tests/perf-testing/oldest_supported/02-create-database.sql deleted file mode 100644 index e053c036..00000000 --- a/tests/perf-testing/oldest_supported/02-create-database.sql +++ /dev/null @@ -1 +0,0 @@ -CREATE DATABASE titanic; \ No newline at end of file diff --git a/tests/perf-testing/oldest_supported/03-import-data.sql b/tests/perf-testing/oldest_supported/03-import-data.sql deleted file mode 100644 index 28cc43b2..00000000 --- a/tests/perf-testing/oldest_supported/03-import-data.sql +++ /dev/null @@ -1,11 +0,0 @@ --- Connect to titanic database -\c titanic; - --- Import the titanic.sql file that was downloaded during Docker build -\i /docker-entrypoint-initdb.d/titanic.sql; - -GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO dbuser; -GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO dbuser; - --- Analyze tables for better query planning -ANALYZE VERBOSE; diff --git a/tests/perf-testing/oldest_supported/Dockerfile b/tests/perf-testing/oldest_supported/Dockerfile deleted file mode 100644 index f211082a..00000000 --- a/tests/perf-testing/oldest_supported/Dockerfile +++ /dev/null @@ -1,42 +0,0 @@ -FROM postgres:12 - -# Dependencies -RUN apt-get update && apt-get install -y \ - build-essential \ - git \ - wget \ - postgresql-server-dev-12 \ - && rm -rf /var/lib/apt/lists/* - -# Postgres Docker Images copy contents of postgresql.conf.sample to postgresql.conf during initialization -# COPY custom.conf /usr/share/postgresql/postgresql.conf.sample -- DO NOT USE -RUN echo "shared_preload_libraries = 'pg_stat_statements,pg_wait_sampling,pg_stat_monitor'" >> /usr/share/postgresql/postgresql.conf.sample -RUN echo "pg_stat_statements.track = all" >> /usr/share/postgresql/postgresql.conf.sample -RUN echo "pg_stat_statements.save = on" >> /usr/share/postgresql/postgresql.conf.sample -RUN echo "pg_stat_monitor.pgsm_enable_query_plan = on" >> /usr/share/postgresql/postgresql.conf.sample - -# Install pg_wait_sampling -RUN git clone https://github.com/postgrespro/pg_wait_sampling.git \ - && cd pg_wait_sampling \ - && make USE_PGXS=1 \ - && make USE_PGXS=1 install \ - && cd .. \ - && rm -rf pg_wait_sampling - -# Install pg_stat_monitor -RUN git clone https://github.com/percona/pg_stat_monitor.git \ - && cd pg_stat_monitor \ - && make USE_PGXS=1 \ - && make USE_PGXS=1 install \ - && cd .. \ - && rm -rf pg_stat_monitor - -# Download the titanic database -RUN wget https://raw.githubusercontent.com/neondatabase/postgres-sample-dbs/main/titanic.sql -P /docker-entrypoint-initdb.d/ - -RUN echo ${PWD} && ls -lR - -# Enable the extensions and setup the titanic database -COPY 01-init-extensions.sql /docker-entrypoint-initdb.d/01-init-extensions.sql -COPY 02-create-database.sql /docker-entrypoint-initdb.d/02-create-database.sql -COPY 03-import-data.sql /docker-entrypoint-initdb.d/03-import-data.sql \ No newline at end of file diff --git a/tests/postgresql_test.go b/tests/postgresql_test.go index 1140f1ed..93d91af1 100644 --- a/tests/postgresql_test.go +++ b/tests/postgresql_test.go @@ -17,19 +17,32 @@ import ( "github.com/xeipuuv/gojsonschema" ) -var ( - defaultPassword = flag.String("password", "example", "Default password for postgres") - defaultUser = flag.String("username", "postgres", "Default username for postgres") - defaultDB = flag.String("database", "demo", "Default database name") - container = flag.String("container", "nri-postgresql", "Container name for the integration") -) - const ( // docker compose service names + serviceNameNRI = "nri-postgresql" serviceNamePostgres96 = "postgres-9-6" serviceNamePostgresLatest = "postgres-latest-supported" ) +func executeDockerCompose(serviceName string, envVars []string) (string, string, error) { + cmdLine := []string{"compose", "run"} + for i := range envVars { + cmdLine = append(cmdLine, "-e") + cmdLine = append(cmdLine, envVars[i]) + } + cmdLine = append(cmdLine, serviceName) + fmt.Printf("executing: docker %s\n", strings.Join(cmdLine, " ")) + cmd := exec.Command("docker", cmdLine...) + var outbuf, errbuf bytes.Buffer + cmd.Stdout = &outbuf + cmd.Stderr = &errbuf + err := cmd.Run() + + stdout := outbuf.String() + stderr := errbuf.String() + return stdout, stderr, err +} + func TestMain(m *testing.M) { flag.Parse() result := m.Run() @@ -38,27 +51,35 @@ func TestMain(m *testing.M) { func TestSuccessConnection(t *testing.T) { t.Parallel() + defaultEnvVars := []string{ + "USERNAME=postgres", + "PASSWORD=example", + "DATABASE=demo", + "COLLECTION_LIST=ALL", + } testCases := []struct { - Name string - Hostname string - Schema string - ExtraFlags []string + Name string + Hostname string + Schema string + EnvVars []string }{ { Name: "Testing Metrics and inventory for Postgres v9.6.x", Hostname: serviceNamePostgres96, Schema: "jsonschema-latest.json", + EnvVars: []string{}, }, { Name: "Testing Metrics and inventory for latest Postgres supported version", Hostname: serviceNamePostgresLatest, Schema: "jsonschema-latest.json", + EnvVars: []string{}, }, { - Name: "Inventory only for latest Postgres supported version", - Hostname: serviceNamePostgresLatest, - Schema: "jsonschema-inventory-latest.json", - ExtraFlags: []string{`-inventory=true`}, + Name: "Inventory only for latest Postgres supported version", + Hostname: serviceNamePostgresLatest, + Schema: "jsonschema-inventory-latest.json", + EnvVars: []string{"INVENTORY=true"}, }, } @@ -66,38 +87,41 @@ func TestSuccessConnection(t *testing.T) { tc := tc t.Run(tc.Name, func(t *testing.T) { t.Parallel() - args := append([]string{`-collection_list=all`}, tc.ExtraFlags...) - stdout, stderr, err := runIntegration(t, tc.Hostname, args...) - assert.Empty(t, stderr) - assert.NoError(t, err) + envVars := []string{ + fmt.Sprintf("HOSTNAME=%s", tc.Hostname), + } + envVars = append(envVars, defaultEnvVars...) + envVars = append(envVars, tc.EnvVars...) + stdout, _, err := executeDockerCompose(serviceNameNRI, envVars) + assert.Nil(t, err) assert.NotEmpty(t, stdout) err = validateJSONSchema(tc.Schema, stdout) - assert.NoError(t, err) + assert.Nil(t, err) }) } } func TestMissingRequiredVars(t *testing.T) { - // Temporarily set username and password to nil to test missing credentials - origUser, origPsw := defaultUser, defaultPassword - defaultUser, defaultPassword = nil, nil - defer func() { - defaultUser, defaultPassword = origUser, origPsw - }() - - _, stderr, err := runIntegration(t, serviceNamePostgresLatest) - assert.Error(t, err) + envVars := []string{ + "HOSTNAME=" + serviceNamePostgresLatest, + "DATABASE=demo", + } + _, stderr, err := executeDockerCompose(serviceNameNRI, envVars) + assert.NotNil(t, err) assert.Contains(t, stderr, "invalid configuration: must specify a username and password") } func TestIgnoringDB(t *testing.T) { - args := []string{ - `-collection_list=all`, - `-collection_ignore_database_list=["demo"]`, + envVars := []string{ + "HOSTNAME=" + serviceNamePostgresLatest, + "USERNAME=postgres", + "PASSWORD=example", + "DATABASE=demo", + "COLLECTION_LIST=ALL", // The instance has 2 DB: 'demo' and 'postgres' + `COLLECTION_IGNORE_DATABASE_LIST=["demo"]`, } - stdout, stderr, err := runIntegration(t, serviceNamePostgresLatest, args...) - assert.NoError(t, err) - assert.Empty(t, stderr) + stdout, _, err := executeDockerCompose(serviceNameNRI, envVars) + assert.Nil(t, err) assert.Contains(t, stdout, `"database:postgres"`) assert.NotContains(t, stdout, `"database:demo"`) } @@ -128,65 +152,3 @@ func validateJSONSchema(fileName string, input string) error { fmt.Printf("\n") return fmt.Errorf("The output of the integration doesn't have expected JSON format") } - -func ExecInContainer(container string, command []string, envVars ...string) (string, string, error) { - cmdLine := make([]string, 0, 3+len(command)) - cmdLine = append(cmdLine, "exec", "-i") - - for _, envVar := range envVars { - cmdLine = append(cmdLine, "-e", envVar) - } - - cmdLine = append(cmdLine, container) - cmdLine = append(cmdLine, command...) - - log.Debug("executing: docker %s", strings.Join(cmdLine, " ")) - - cmd := exec.Command("docker", cmdLine...) - - var outbuf, errbuf bytes.Buffer - cmd.Stdout = &outbuf - cmd.Stderr = &errbuf - - err := cmd.Run() - stdout := outbuf.String() - stderr := errbuf.String() - - if err != nil { - return stdout, stderr, err - } - - return stdout, stderr, nil -} - -func runIntegration(t *testing.T, targetContainer string, args ...string) (string, string, error) { - t.Helper() - - command := []string{"/nri-postgresql"} - - if defaultUser != nil { - command = append(command, "-username", *defaultUser) - } - if defaultPassword != nil { - command = append(command, "-password", *defaultPassword) - } - - // Always use port 5432 for integration runs - command = append(command, "-port", "5432") - - if defaultDB != nil { - command = append(command, "-database", *defaultDB) - } - if targetContainer != "" { - command = append(command, "-hostname", targetContainer) - } - - command = append(command, args...) - - stdout, stderr, err := ExecInContainer(*container, command) - if stderr != "" { - log.Debug("Integration command Standard Error: ", stderr) - } - - return stdout, stderr, err -} diff --git a/tests/postgresqlperf_test.go b/tests/postgresqlperf_test.go deleted file mode 100644 index 2dc0571a..00000000 --- a/tests/postgresqlperf_test.go +++ /dev/null @@ -1,480 +0,0 @@ -//go:build integration - -package tests - -import ( - "bytes" - "encoding/json" - "flag" - "fmt" - "net/url" - "os" - "os/exec" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/jmoiron/sqlx" - _ "github.com/lib/pq" - - "github.com/newrelic/infra-integrations-sdk/v3/log" - "github.com/newrelic/nri-postgresql/tests/simulation" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/xeipuuv/gojsonschema" -) - -var ( - oldestSupportedPerf = "postgresql-perf-oldest" - latestSupportedPerf = "postgresql-perf-latest" - unsupportedPerf = "postgresql-noext" - perfContainers = []string{oldestSupportedPerf, latestSupportedPerf} - nonPerfContainers = []string{unsupportedPerf} - integrationContainer = "nri_postgresql" - - defaultBinPath = "/nri-postgresql" - defaultUser = "dbuser" - defaultPass = "dbpassword" - defaultPort = 5432 - defaultDB = "demo" - testDB = "titanic" - - // cli flags - container = flag.String("container", integrationContainer, "container where the integration is installed") - binaryPath = flag.String("bin", defaultBinPath, "Integration binary path") - user = flag.String("user", defaultUser, "Postgresql user name") - psw = flag.String("psw", defaultPass, "Postgresql user password") - port = flag.Int("port", defaultPort, "Postgresql port") - database = flag.String("database", defaultDB, "Postgresql database") -) - -func TestMain(m *testing.M) { - flag.Parse() - result := m.Run() - os.Exit(result) -} - -func TestIntegrationWithDatabaseLoadPerfEnabled(t *testing.T) { - tests := []struct { - name string - expectedOrder []string - containers []string - args []string - }{ - { - name: "Performance metrics collection test", - expectedOrder: []string{ - "PostgresqlInstanceSample", - "PostgresSlowQueries", - "PostgresWaitEvents", - "PostgresBlockingSessions", - "PostgresIndividualQueries", - "PostgresExecutionPlanMetrics", - }, - containers: perfContainers, - args: []string{`-collection_list=all`, `-enable_query_monitoring=true`}, - }, - { - name: "Performance metrics collection test without collection list", - expectedOrder: []string{ - "PostgresqlInstanceSample", - }, - containers: perfContainers, - args: []string{`-enable_query_monitoring=true`}, - }, - { - name: "Performance metrics collection test without query monitoring enabled", - expectedOrder: []string{ - "PostgresqlInstanceSample", - }, - containers: perfContainers, - args: []string{`-collection_list=all`}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - for _, container := range tt.containers { - t.Run(container, func(t *testing.T) { - // Create simulation controller - controller := NewSimulationController(container) - // Start all simulations - done := controller.StartAllSimulations(t) - - time.Sleep(30 * time.Second) - - stdout := runIntegration(t, container, tt.args...) - // fmt.Println(stdout) - samples := strings.Split(stdout, "\n") - count := 0 - - for idx, sample := range samples { - sample = strings.TrimSpace(sample) - if sample == "" { - continue - } - - // Validate sample type - t.Run(fmt.Sprintf("Validating JSON schema for: %s", tt.expectedOrder[count]), func(t *testing.T) { - // Validate JSON - var j map[string]interface{} - err := json.Unmarshal([]byte(sample), &j) - assert.NoError(t, err, "Sample %d - Integration Output Is An Invalid JSONs", idx) - - sampleType := tt.expectedOrder[count] - if !strings.Contains(sample, sampleType) { - t.Errorf("Integration output does not contain: %s", tt.expectedOrder[count]) - } - - // Validate against schema - schemaFileName := getSchemaFileName(sampleType) - err = validateJSONSchema(schemaFileName, sample) - assert.NoError(t, err, "Sample %d (%s) failed schema validation", idx, sampleType) - }) - - count++ - } - fmt.Println(count) - - // Wait for all simulations to complete - <-done - }) - } - }) - } -} - -func TestIntegrationUnsupportedDatabase(t *testing.T) { - tests := []struct { - name string - containers []string - args []string - }{ - { - name: "Performance metrics collection with unsupported database - perf enabled", - containers: nonPerfContainers, - args: []string{`-collection_list=all`, `-enable_query_monitoring=true`}, - }, - { - name: "Performance metrics collection with unsupported database - perf disabled", - containers: nonPerfContainers, - args: []string{`-collection_list=all`, `-enable_query_monitoring=false`}, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - for _, container := range tt.containers { - t.Run(container, func(t *testing.T) { - stdout := runIntegration(t, container, tt.args...) - - // Validate JSON format - var j map[string]interface{} - err := json.Unmarshal([]byte(stdout), &j) - assert.NoError(t, err, "Integration Output Is An Invalid JSON") - - // Verify it's a PostgresqlInstanceSample - assert.Contains(t, stdout, "PostgresqlInstanceSample", - "Integration output does not contain PostgresqlInstanceSample") - - // Validate against schema - err = validateJSONSchema("jsonschema-latest.json", stdout) - assert.NoError(t, err, "Output failed schema validation") - }) - } - }) - } -} - -// ---------------- HELPER FUNCTIONS ---------------- - -func openDB(targetContainer string) (*sqlx.DB, error) { - // Use the container-specific port for database connections - dbPort := getPortForContainer(targetContainer) - - connectionURL := &url.URL{ - Scheme: "postgres", - User: url.UserPassword(*user, *psw), - Host: fmt.Sprintf("%s:%d", "localhost", dbPort), - Path: testDB, - } - - query := url.Values{} - query.Add("connect_timeout", "10") - query.Add("sslmode", "disable") - - connectionURL.RawQuery = query.Encode() - dsn := connectionURL.String() - db, err := sqlx.Open("postgres", dsn) - if err != nil { - return nil, fmt.Errorf("Cannot connect to db: %s", err) //nolint:all - } - return db, nil -} - -func getPortForContainer(container string) int { - switch container { - case "postgresql-perf-latest": - return 5432 - case "postgresql-perf-oldest": - return 6432 - case "postgresql-noext": - return 7432 - default: - return 5432 - } -} - -func ExecInContainer(container string, command []string, envVars ...string) (string, string, error) { - cmdLine := make([]string, 0, 3+len(command)) - cmdLine = append(cmdLine, "exec", "-i") - - for _, envVar := range envVars { - cmdLine = append(cmdLine, "-e", envVar) - } - - cmdLine = append(cmdLine, container) - cmdLine = append(cmdLine, command...) - - log.Debug("executing: docker %s", strings.Join(cmdLine, " ")) - // fmt.Printf("executing: docker %s", strings.Join(cmdLine, " ")) - - cmd := exec.Command("docker", cmdLine...) - - var outbuf, errbuf bytes.Buffer - cmd.Stdout = &outbuf - cmd.Stderr = &errbuf - - err := cmd.Run() - stdout := outbuf.String() - stderr := errbuf.String() - - if err != nil { - return stdout, stderr, err - } - // fmt.Println(stdout) - - return stdout, stderr, nil -} - -func runIntegration(t *testing.T, targetContainer string, integration_args ...string) string { - t.Helper() - - command := make([]string, 0) - command = append(command, *binaryPath) - - if user != nil { - command = append(command, "-username", *user) - } - if psw != nil { - command = append(command, "-password", *psw) - } - - // Always use port 5432 for integration runs - command = append(command, "-port", "5432") - - if database != nil { - command = append(command, "-database", *database) - } - if targetContainer != "" { - command = append(command, "-hostname", targetContainer) - } - - for _, arg := range integration_args { - command = append(command, arg) //nolint:all - } - - stdout, stderr, err := ExecInContainer(*container, command) - if stderr != "" { - log.Debug("Integration command Standard Error: ", stderr) - } - fmt.Println(stderr) - require.NoError(t, err) - - return stdout -} - -func validateJSONSchema(fileName string, input string) error { - pwd, err := os.Getwd() - if err != nil { - log.Error(err.Error()) - return err - } - schemaURI := fmt.Sprintf("file://%s", filepath.Join(pwd, "testdata", fileName)) - log.Info("loading schema from %s", schemaURI) - schemaLoader := gojsonschema.NewReferenceLoader(schemaURI) - documentLoader := gojsonschema.NewStringLoader(input) - - result, err := gojsonschema.Validate(schemaLoader, documentLoader) - if err != nil { - return fmt.Errorf("Error loading JSON schema, error: %v", err) //nolint:all - } - - if result.Valid() { - return nil - } - fmt.Printf("Errors for JSON schema: '%s'\n", schemaURI) - for _, desc := range result.Errors() { - fmt.Printf("\t- %s\n", desc) - } - fmt.Printf("\n") - return fmt.Errorf("The output of the integration doesn't have expected JSON format") //nolint:all -} - -func getSchemaFileName(sampleType string) string { - schemaMap := map[string]string{ - "PostgresqlInstanceSample": "jsonschema-latest.json", - "PostgresSlowQueries": "slow-queries-schema.json", - "PostgresWaitEvents": "wait-events-schema.json", - "PostgresBlockingSessions": "blocking-sessions-schema.json", - "PostgresIndividualQueries": "individual-queries-schema.json", - "PostgresExecutionPlanMetrics": "execution-plan-schema.json", - } - return schemaMap[sampleType] -} - -// ---------------- DB SIMULATION FUNCTIONS ---------------- - -// SimulationController handles coordinating multiple database simulations -type SimulationController struct { - targetContainer string - envVars []string -} - -// NewSimulationController creates a new controller for database simulations -func NewSimulationController(targetContainer string, envVars ...string) *SimulationController { - return &SimulationController{ - targetContainer: targetContainer, - envVars: envVars, - } -} - -// StartAllSimulations starts all simulation routines concurrently -func (sc *SimulationController) StartAllSimulations(t *testing.T) chan struct{} { - done := make(chan struct{}) - - go func() { - defer close(done) - - // Create error channel to collect errors from goroutines - errChan := make(chan error, 6) - - // Start all simulations in separate goroutines - go func() { - SimulateQueries(t, sc.targetContainer) - errChan <- nil - }() - - go func() { - SimulateSlowQueries(t, sc.targetContainer) - errChan <- nil - }() - - for pclass := 1; pclass <= 3; pclass++ { - go func() { - SimulateWaitEvents(t, sc.targetContainer, pclass) - errChan <- nil - }() - } - - go func() { - SimulateBlockingSessions(t, sc.targetContainer) - errChan <- nil - }() - - // Wait for all goroutines to complete - for i := 0; i < 6; i++ { - if err := <-errChan; err != nil { - log.Error("Error in simulation routine: %v", err) - t.Error(err) - } - } - }() - - return done -} - -func ExecuteQuery(t *testing.T, query string, targetContainer string, delay int) { - - db, err := openDB(targetContainer) - require.NoError(t, err) - defer db.Close() - - _, err = db.Exec(query) - // fmt.Println(stderr) - require.NoError(t, err) - time.Sleep(time.Duration(delay) * time.Millisecond) -} - -func SimulateQueries(t *testing.T, targetContainer string) { - t.Helper() - for _, query := range simulation.SimpleQueries() { - ExecuteQuery(t, query, targetContainer, 100) - } -} - -func SimulateSlowQueries(t *testing.T, targetContainer string) { - t.Helper() - for _, query := range simulation.SlowQueries() { - ExecuteQuery(t, query, targetContainer, 500) - } -} - -func SimulateWaitEvents(t *testing.T, targetContainer string, pclass int) { - t.Helper() - - queries := simulation.WaitEventQueries(pclass) - - // Start the locking transaction in a goroutine - go func() { - ExecuteQuery(t, queries.LockingQuery, targetContainer, 100) - }() - - // Wait for first transaction started - time.Sleep(2 * time.Second) - - // Run the blocked transaction - ExecuteQuery(t, queries.BlockedQuery, targetContainer, 100) - - time.Sleep(30 * time.Second) -} - -func SimulateBlockingSessions(t *testing.T, targetContainer string) { - t.Helper() - - queries := simulation.BlockingQueries() - - db, err := openDB(targetContainer) - require.NoError(t, err) - defer db.Close() - - // Start the first transaction that will hold the lock - tx1, err := db.Begin() - require.NoError(t, err) - defer tx1.Rollback() //nolint:all - - // Execute the locking query - _, err = tx1.Exec(queries.HoldLockQuery) - require.NoError(t, err) - - // Start the blocking query in a separate goroutine - go func() { - time.Sleep(2 * time.Second) // Wait for a bit before trying to acquire lock - - tx2, err := db.Begin() - if err != nil { - t.Error(err) - return - } - defer tx2.Rollback() //nolint:all - - // This query will block waiting for tx1's lock - tx2.Exec(queries.BlockedQuery) //nolint:all - // We don't check for errors here since this might timeout - }() - - // Hold the lock for a few seconds, then release it - time.Sleep(5 * time.Second) - tx1.Commit() //nolint:all -} diff --git a/tests/simulation/sim_queries.go b/tests/simulation/sim_queries.go deleted file mode 100644 index 6d160910..00000000 --- a/tests/simulation/sim_queries.go +++ /dev/null @@ -1,164 +0,0 @@ -package simulation - -import "fmt" - -func SimpleQueries() []string { - return []string{ - // Basic queries that will generate typical workload - "SELECT COUNT(*) FROM passenger WHERE survived = 1", - "SELECT class, COUNT(*) FROM passenger GROUP BY class", - "SELECT * FROM passenger WHERE fare > 100 ORDER BY fare DESC LIMIT 10", - "SELECT sex, AVG(age) as avg_age FROM passenger GROUP BY sex", - "SELECT * FROM passenger WHERE name LIKE '%John%'", - } -} - -func SlowQueries() []string { - return []string{ - // Age-based survival analysis - `WITH age_groups AS ( - SELECT - CASE - WHEN age < 18 THEN 'child' - WHEN age < 50 THEN 'adult' - ELSE 'elderly' - END as age_group, - survived - FROM passenger - ) - SELECT - age_group, - COUNT(*) as total, - SUM(survived::int) as survived_count, - ROUND(AVG(survived::int) * 100, 2) as survival_rate - FROM age_groups - GROUP BY age_group - ORDER BY survival_rate DESC`, - - // Multiple self-joins analysis - `SELECT DISTINCT p1.name, p1.class, p1.fare - FROM passenger p1 - JOIN passenger p2 ON p1.fare = p2.fare AND p1.passengerid != p2.passengerid - JOIN passenger p3 ON p2.class = p3.class AND p2.passengerid != p3.passengerid - WHERE p1.survived = 1 - ORDER BY p1.fare DESC`, - - // Subquery with expensive sort - `SELECT *, - (SELECT COUNT(*) - FROM passenger p2 - WHERE p2.fare > p1.fare) as more_expensive_tickets - FROM passenger p1 - ORDER BY more_expensive_tickets DESC`, - - // Complex aggregation with JSON - `SELECT - p1.class, - p1.survived, - COUNT(*) as group_size, - AVG(p1.age) as avg_age, - STRING_AGG(DISTINCT p1.name, ', ' ORDER BY p1.name) as passenger_names, - ( - SELECT JSON_AGG( - JSON_BUILD_OBJECT( - 'name', p2.name, - 'fare', p2.fare - ) - ) - FROM passenger p2 - WHERE p2.class = p1.class - AND p2.survived = p1.survived - ) as similar_fare_passengers - FROM passenger p1 - GROUP BY p1.class, p1.survived - ORDER BY p1.class, p1.survived`, - - // Statistical analysis with percentiles - `SELECT - p1.class, - p1.sex, - PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY p1.age) as median_age, - PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY p1.fare) as median_fare, - COUNT(*) FILTER (WHERE p1.survived = 1)::float / COUNT(*) as survival_rate, - ( - SELECT array_agg(DISTINCT p2.embarked) - FROM passenger p2 - WHERE p2.class = p1.class AND p2.sex = p1.sex - ) as embarkation_points - FROM passenger p1 - GROUP BY p1.class, p1.sex - HAVING COUNT(*) > 10 - ORDER BY p1.class, p1.sex`, - - // Decile analysis with window functions - `WITH fare_ranks AS ( - SELECT - *, - NTILE(10) OVER (ORDER BY fare) as fare_decile - FROM passenger - ), - age_ranks AS ( - SELECT - *, - NTILE(10) OVER (ORDER BY age) as age_decile - FROM passenger - WHERE age IS NOT NULL - ) - SELECT - fr.fare_decile, - ar.age_decile, - COUNT(*) as passenger_count, - SUM(fr.survived::int) as survivors, - AVG(fr.fare) as avg_fare, - AVG(ar.age) as avg_age, - array_agg(DISTINCT fr.class) as class_distribution - FROM fare_ranks fr - JOIN age_ranks ar ON fr.passengerid = ar.passengerid - GROUP BY fr.fare_decile, ar.age_decile - ORDER BY fr.fare_decile, ar.age_decile`, - } -} - -func BlockingQueries() struct { - HoldLockQuery string - BlockedQuery string -} { - return struct { - HoldLockQuery string - BlockedQuery string - }{ - HoldLockQuery: ` -BEGIN; -SELECT * FROM passenger WHERE passengerid = 100 FOR UPDATE; -`, - BlockedQuery: ` -BEGIN; -SELECT * FROM passenger WHERE passengerid = 100 FOR UPDATE; -`, - } -} - -func WaitEventQueries(pclass int) struct { - LockingQuery string - BlockedQuery string -} { - return struct { - LockingQuery string - BlockedQuery string - }{ - LockingQuery: fmt.Sprintf(` -BEGIN; -UPDATE passenger -SET fare = fare * 1.01 -WHERE pclass = %d; -SELECT pg_sleep(30); -COMMIT;`, pclass), - - BlockedQuery: fmt.Sprintf(` -BEGIN; -UPDATE passenger -SET fare = fare * 0.99 -WHERE pclass = %d; -COMMIT;`, pclass), - } -} diff --git a/tests/testdata/blocking-sessions-schema.json b/tests/testdata/blocking-sessions-schema.json deleted file mode 100644 index 677db04e..00000000 --- a/tests/testdata/blocking-sessions-schema.json +++ /dev/null @@ -1,98 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": ["name", "protocol_version", "integration_version", "data"], - "properties": { - "name": { - "type": "string", - "const": "com.newrelic.postgresql" - }, - "protocol_version": { - "type": "string" - }, - "integration_version": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "object", - "required": ["entity", "metrics", "inventory", "events"], - "properties": { - "entity": { - "type": "object", - "required": ["name", "type", "id_attributes"], - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "const": "pg-instance" - }, - "id_attributes": { - "type": "array" - } - } - }, - "metrics": { - "type": "array", - "items": { - "type": "object", - "required": [ - "blocked_pid", - "blocked_query", - "blocked_query_start", - "blocking_pid", - "blocking_query", - "blocking_query_start", - "database_name", - "event_type" - ], - "properties": { - "blocked_pid": { - "type": "integer", - "minimum": 0 - }, - "blocked_query": { - "type": "string" - }, - "blocked_query_start": { - "type": "string", - "format": "date-time" - }, - "blocking_pid": { - "type": "integer", - "minimum": 0 - }, - "blocking_query": { - "type": "string" - }, - "blocking_query_start": { - "type": "string", - "format": "date-time" - }, - "database_name": { - "type": "string" - }, - "event_type": { - "type": "string", - "const": "PostgresBlockingSessions" - } - }, - "additionalProperties": false - } - }, - "inventory": { - "type": "object" - }, - "events": { - "type": "array" - } - }, - "additionalProperties": false - } - } - }, - "additionalProperties": false - } \ No newline at end of file diff --git a/tests/testdata/execution-plan-schema.json b/tests/testdata/execution-plan-schema.json deleted file mode 100644 index aa3a97dd..00000000 --- a/tests/testdata/execution-plan-schema.json +++ /dev/null @@ -1,176 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": ["name", "protocol_version", "integration_version", "data"], - "properties": { - "name": { - "type": "string", - "const": "com.newrelic.postgresql" - }, - "protocol_version": { - "type": "string" - }, - "integration_version": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "object", - "required": ["entity", "metrics", "inventory", "events"], - "properties": { - "entity": { - "type": "object", - "required": ["name", "type", "id_attributes"], - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "const": "pg-instance" - }, - "id_attributes": { - "type": "array" - } - } - }, - "metrics": { - "type": "array", - "items": { - "type": "object", - "required": [ - "actual_loops", - "actual_rows", - "actual_startup_time", - "actual_total_time", - "database_name", - "event_type", - "level_id", - "local_dirtied_blocks", - "local_hit_blocks", - "local_read_blocks", - "local_written_blocks", - "node_type", - "plan_id", - "plan_rows", - "query_id", - "query_text", - "shared_dirtied_blocks", - "shared_hit_blocks", - "shared_read_blocks", - "shared_written_blocks", - "startup_cost", - "temp_read_blocks", - "temp_written_blocks", - "total_cost" - ], - "properties": { - "actual_loops": { - "type": "integer", - "minimum": 0 - }, - "actual_rows": { - "type": "integer", - "minimum": 0 - }, - "actual_startup_time": { - "type": "integer", - "minimum": 0 - }, - "actual_total_time": { - "type": "integer", - "minimum": 0 - }, - "database_name": { - "type": "string" - }, - "event_type": { - "type": "string", - "const": "PostgresExecutionPlanMetrics" - }, - "level_id": { - "type": "integer", - "minimum": 0 - }, - "local_dirtied_blocks": { - "type": "integer", - "minimum": 0 - }, - "local_hit_blocks": { - "type": "integer", - "minimum": 0 - }, - "local_read_blocks": { - "type": "integer", - "minimum": 0 - }, - "local_written_blocks": { - "type": "integer", - "minimum": 0 - }, - "node_type": { - "type": "string" - }, - "plan_id": { - "type": "string" - }, - "plan_rows": { - "type": "integer", - "minimum": 0 - }, - "query_id": { - "type": "string" - }, - "query_text": { - "type": "string" - }, - "shared_dirtied_blocks": { - "type": "integer", - "minimum": 0 - }, - "shared_hit_blocks": { - "type": "integer", - "minimum": 0 - }, - "shared_read_blocks": { - "type": "integer", - "minimum": 0 - }, - "shared_written_blocks": { - "type": "integer", - "minimum": 0 - }, - "startup_cost": { - "type": "number", - "minimum": 0 - }, - "temp_read_blocks": { - "type": "integer", - "minimum": 0 - }, - "temp_written_blocks": { - "type": "integer", - "minimum": 0 - }, - "total_cost": { - "type": "number", - "minimum": 0 - } - }, - "additionalProperties": false - } - }, - "inventory": { - "type": "object" - }, - "events": { - "type": "array" - } - }, - "additionalProperties": false - } - } - }, - "additionalProperties": false - } \ No newline at end of file diff --git a/tests/testdata/individual-queries-schema.json b/tests/testdata/individual-queries-schema.json deleted file mode 100644 index ca4a2d75..00000000 --- a/tests/testdata/individual-queries-schema.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [ - "name", - "protocol_version", - "integration_version", - "data" - ], - "properties": { - "name": { - "type": "string", - "const": "com.newrelic.postgresql" - }, - "protocol_version": { - "type": "string" - }, - "integration_version": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "object", - "required": [ - "entity", - "metrics", - "inventory", - "events" - ], - "properties": { - "entity": { - "type": "object", - "required": [ - "name", - "type", - "id_attributes" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "const": "pg-instance" - }, - "id_attributes": { - "type": "array" - } - } - }, - "metrics": { - "type": "array", - "items": { - "type": "object", - "required": [ - "event_type", - "query_id", - "query_text", - "database_name", - "plan_id", - "avg_exec_time_ms" - ], - "properties": { - "avg_cpu_time_ms": { - "type": "number", - "minimum": 0 - }, - "avg_exec_time_ms": { - "type": "number", - "minimum": 0 - }, - "database_name": { - "type": "string" - }, - "event_type": { - "type": "string", - "const": "PostgresIndividualQueries" - }, - "plan_id": { - "type": "string" - }, - "query_id": { - "type": "string" - }, - "query_text": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "inventory": { - "type": "object" - }, - "events": { - "type": "array" - } - }, - "additionalProperties": false - } - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/tests/testdata/slow-queries-schema.json b/tests/testdata/slow-queries-schema.json deleted file mode 100644 index cc3427fd..00000000 --- a/tests/testdata/slow-queries-schema.json +++ /dev/null @@ -1,121 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": [ - "name", - "protocol_version", - "integration_version", - "data" - ], - "properties": { - "name": { - "type": "string", - "const": "com.newrelic.postgresql" - }, - "protocol_version": { - "type": "string" - }, - "integration_version": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "object", - "required": [ - "entity", - "metrics", - "inventory", - "events" - ], - "properties": { - "entity": { - "type": "object", - "required": [ - "name", - "type", - "id_attributes" - ], - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "const": "pg-instance" - }, - "id_attributes": { - "type": "array" - } - } - }, - "metrics": { - "type": "array", - "items": { - "type": "object", - "required": [ - "event_type", - "query_id", - "query_text", - "database_name", - "avg_elapsed_time_ms", - "execution_count", - "collection_timestamp" - ], - "properties": { - "avg_disk_reads": { - "type": "integer", - "minimum": 0 - }, - "avg_disk_writes": { - "type": "integer", - "minimum": 0 - }, - "avg_elapsed_time_ms": { - "type": "number", - "minimum": 0 - }, - "collection_timestamp": { - "type": "string", - "format": "date-time" - }, - "database_name": { - "type": "string" - }, - "event_type": { - "type": "string", - "const": "PostgresSlowQueries" - }, - "execution_count": { - "type": "integer", - "minimum": 0 - }, - "query_id": { - "type": "string" - }, - "query_text": { - "type": "string" - }, - "schema_name": { - "type": "string" - }, - "statement_type": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "inventory": { - "type": "object" - }, - "events": { - "type": "array" - } - }, - "additionalProperties": false - } - } - }, - "additionalProperties": false -} \ No newline at end of file diff --git a/tests/testdata/wait-events-schema.json b/tests/testdata/wait-events-schema.json deleted file mode 100644 index 44a39904..00000000 --- a/tests/testdata/wait-events-schema.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "$schema": "http://json-schema.org/draft-07/schema#", - "type": "object", - "required": ["name", "protocol_version", "integration_version", "data"], - "properties": { - "name": { - "type": "string", - "const": "com.newrelic.postgresql" - }, - "protocol_version": { - "type": "string" - }, - "integration_version": { - "type": "string" - }, - "data": { - "type": "array", - "items": { - "type": "object", - "required": ["entity", "metrics", "inventory", "events"], - "properties": { - "entity": { - "type": "object", - "required": ["name", "type", "id_attributes"], - "properties": { - "name": { - "type": "string" - }, - "type": { - "type": "string", - "const": "pg-instance" - }, - "id_attributes": { - "type": "array" - } - } - }, - "metrics": { - "type": "array", - "items": { - "type": "object", - "required": [ - "collection_timestamp", - "database_name", - "event_type", - "query_id", - "query_text", - "wait_category", - "wait_event_name" - ], - "properties": { - "collection_timestamp": { - "type": "string", - "format": "date-time" - }, - "database_name": { - "type": "string" - }, - "event_type": { - "type": "string", - "const": "PostgresWaitEvents" - }, - "query_id": { - "type": "string" - }, - "query_text": { - "type": "string" - }, - "total_wait_time_ms": { - "type": "number", - "minimum": 0 - }, - "wait_category": { - "type": "string" - }, - "wait_event_name": { - "type": "string" - } - }, - "additionalProperties": false - } - }, - "inventory": { - "type": "object" - }, - "events": { - "type": "array" - } - }, - "additionalProperties": false - } - } - }, - "additionalProperties": false - } \ No newline at end of file