diff --git a/.github/workflows/compliance-tests.yml b/.github/workflows/compliance-tests.yml index f0aa74f..a24a830 100644 --- a/.github/workflows/compliance-tests.yml +++ b/.github/workflows/compliance-tests.yml @@ -1,21 +1,21 @@ -name: Compliance Tests - +--- +name: Compliance on: pull_request: + push: + branches: [main] + +permissions: + contents: read jobs: - remotewrite-compliance: + remotewrite-sender: + name: Remote Write Sender runs-on: ubuntu-latest - + container: + image: quay.io/prometheus/golang-builder:1.25-base steps: - - uses: actions/checkout@v4 - - - name: Set up Go - uses: actions/setup-go@v4 - with: - go-version: '1.22' - - - name: Run Remote Write Prometheus Compliance Tests - run: | - cd remotewrite/sender - go test --tags=compliance -run "TestRemoteWrite/prometheus/.+" -v ./ \ No newline at end of file + - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 + with: + persist-credentials: false + - run: cd remotewrite && make sender \ No newline at end of file diff --git a/remotewrite/.gitignore b/remotewrite/.gitignore new file mode 100644 index 0000000..ab96d8c --- /dev/null +++ b/remotewrite/.gitignore @@ -0,0 +1,4 @@ +results.json +config.yml +index.preloaded.html +bin/ \ No newline at end of file diff --git a/remotewrite/Makefile b/remotewrite/Makefile new file mode 100644 index 0000000..3066664 --- /dev/null +++ b/remotewrite/Makefile @@ -0,0 +1,57 @@ +# Set the default target to 'help' so it runs when you just type 'make' +.DEFAULT_GOAL := help + +mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) +current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) +ROOT_DIR := $(dir $(mkfile_path)) + +SED=$(shell which gsed 2>/dev/null || which sed) + +# Shared variables +DEBUG="" +TIMEOUT="10m" +PROMETHEUS_RW_COMPLIANCE_TEST_RE="" +PROMETHEUS_RW_COMPLIANCE_SKIP_TEST_RE="" +RESULT_FILE="$(ROOT_DIR)/results.json" + +# Go test arguments and the base execution command. +BASE_TEST_ARGS = -run $(PROMETHEUS_RW_COMPLIANCE_TEST_RE) -skip $(PROMETHEUS_RW_COMPLIANCE_SKIP_TEST_RE) +RUN_TEST = cd ./$(COMPONENT) && DEBUG=$(DEBUG) $(COMPONENT_ENV) go test $(BASE_TEST_ARGS) + +# Use target-specific variables to dynamically inject directories and environment variables. +sender sender-%: PROMETHEUS_COMPLIANCE_RW_SENDERS="prometheus" +sender sender-%: COMPONENT = sender +sender sender-%: COMPONENT_ENV = PROMETHEUS_COMPLIANCE_RW_SENDERS=$(PROMETHEUS_COMPLIANCE_RW_SENDERS) + +receiver receiver-%: COMPONENT = receiver +receiver receiver-%: COMPONENT_ENV = PROMETHEUS_RW2_COMPLIANCE_RECEIVERS=$(PROMETHEUS_RW2_COMPLIANCE_RECEIVERS) + +.PHONY: help +help: ## Show this help message + @echo "Usage: make [target]" + @echo "" + @echo "Available commands:" + @awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST) + +.PHONY: sender +sender: ## Run sender compliance tests for a given senders suitable for humans and CI. + $(RUN_TEST) -v -timeout=$(TIMEOUT) + +.PHONY: sender-web +sender-web: ## Run sender compliance tests for a given senders with a HTML results view. + @$(RUN_TEST) -json | tee $(RESULT_FILE) + @$(MAKE) results-web + +.PHONY: receiver +receiver: ## Run receiver compliance tests for a given receivers suitable for humans and CI. + $(RUN_TEST) -v -timeout=$(TIMEOUT) + +.PHONY: receiver-web +receiver-web: ## Run receiver compliance tests for a given receivers with a HTML results view. + @$(RUN_TEST) -json | tee $(RESULT_FILE) + @$(MAKE) results-web + +.PHONY: results-web +results-web: ## Generate HTML view with ./results.json from the index.html file and open in your browser. We re-generate HTML file to avoid CORS issue on secure browsers. + @cat index.html | perl -pe 'BEGIN{local $$/; open(F,"; close F} s/const PRELOADED_RESULT_DATA = ``;/const PRELOADED_RESULT_DATA = `$$c`;/' > index.preloaded.html + @open index.preloaded.html \ No newline at end of file diff --git a/remotewrite/README.md b/remotewrite/README.md index 6fd589b..59d1632 100644 --- a/remotewrite/README.md +++ b/remotewrite/README.md @@ -2,24 +2,90 @@ This repository contains compliance test suites for both **senders** and **receivers** of the Prometheus Remote-Write Protocol 2.0. It validates implementation of the Remote-Write v2 specification according to the [official protocol requirements](https://prometheus.io/docs/specs/prw/remote_write_spec_2_0/) as well as some more strict Prometheus implementation aspects. -## Overview +Both [sender](#sender-compliance-sender) and [receiver](#receiver-compliance-receiver) test suites uses a shared [`./index.html`](./index.html) file that enables viewing compliance test results after they complete. -The test suites validate protocol compliance for both sides of Remote-Write communication: +To generate and view results, add `-json` flag to `go test` command and `tee` the results to a file called `results.json`. -### Sender Compliance (`/sender`) -Tests that Remote-Write senders properly implement the protocol by forking sender instances (e.g., Prometheus), examining generated requests, and validating them against the specification. +Tests are marked with compliance levels according to RFC specifications: +- **MUST**: Required by Remote Write specification +- **SHOULD**: Recommended by Remote Write specification +- **MAY**: Could have by Remote Write specification +- **RECOMMENDED**: Not in Remote Write specification, but recommended for performance or Prometheus compatibility reasons + +## Sender Compliance (`/sender`) + +Tests that Remote-Write senders implement the RW2 protocol by running tests cases with: + +1. Scraper exposing OpenMetrics 1.0 +2. Target sender to test (e.g., Prometheus), +3. Special receiver that tests various elements of the request(s). Tests cover: +- Series encoding - Float samples encoding - Native Histograms encoding - Exemplars encoding -- Protocol headers and content negotiation -- Error handling and retry logic -- Backoff and batching behavior -- Metadata and symbol table management +- Metadata encoding +- Protocol headers +- Error handling, basic batching and retry logic - Request formatting and compression +- Various Prometheus / OpenMetrics 1.0 semantics as "RECOMMENDED" (staleness, upness). Because this test depends on scraping behaviour we +are testing some elements of the exposition format support too. + +### Prerequisites + +- Go 1.23 or later +- The sender binary you want to test (e.g., Prometheus) + - Requires OpenMetrics 1.0 scrape capability. + - Required Remote Write sending capability. + +The test suite automatically downloads and runs Prometheus as the reference sender implementation. + +### Configuration + +The test suite uses environment variables: + +**Sender Selection:** + +```bash +PROMETHEUS_COMPLIANCE_RW_SENDERS="prometheus" +``` + +Currently supported senders: +- `prometheus` - The reference Prometheus implementation (automatically downloaded). +- `process` - For custom sender that is a local binary. + +For testing custom senders: + +* Add target running code and register it the `sender/main_test.go`. + +TODO: Implement that. +* Use custom process target via `PROMETHEUS_COMPLIANCE_RW_SENDERS="process"` and `PROMETHEUS_COMPLIANCE_RW_PROCESS_BINARY=` envvars. + +**Debug output:** + +Debug variable controls if the tested process suppresses output (empty DEBUG) or not. + +```bash +DEBUG="1" +``` + +### Running Tests + +```bash +make sender +``` + +To use visualization HTML page: + +```bash +make sender-web +``` + +See Makefile for detailed invocation. + +## Receiver Compliance (`/receiver`) -### Receiver Compliance (`/receiver`) Tests that Remote-Write endpoints properly handle incoming requests by sending various Remote-Write v2 requests and validating responses. Tests cover: @@ -31,51 +97,24 @@ Tests cover: - Content-Type validation - Response headers (`X-Prometheus-Remote-Write-*-Written`) -## Limitations - -### Sender Tests -The test suite validates the format and structure of requests sent by the sender but does not verify end-to-end data flow or persistence. Because senders may have different configuration options and capabilities, passing all tests does not guarantee a sender supports every Remote-Write feature (such as Native Histograms). Some senders may not expose certain features or may require specific configuration. +### Limitations -### Receiver Tests This test suite does not verify data ingestion by reading data back from the receiver. Some requests that are valid for one backend might be rejected by another. The suite tolerates both 200 and 400 series HTTP responses since actual data validation is up to the receiver. Therefore, passing all tests does not guarantee that a receiver supports every Remote-Write feature. **Important**: You should review the detailed test output to judge compliance for your implementation. A successful `go test` run alone is not sufficient. -## Prerequisites - -### For Sender Tests -- Go 1.23 or later -- The sender binary to test (e.g., Prometheus) - -The test suite automatically downloads and runs Prometheus as the reference sender implementation. For testing custom senders, place the binary in the `bin/` directory. - -### For Receiver Tests -A Prometheus server with Remote-Write Receiver enabled, as baseline: -```bash -prometheus --web.enable-remote-write-receiver --enable-feature=native-histograms -``` - -Or any other Remote-Write Receiver endpoint. +### Prerequisites -## Configuration +You need a receiving endpoint you want to test. -### Sender Configuration -The test suite uses environment variables: +For example, a Prometheus server with Remote-Write Receiver enabled could be used as a baseline: -**Sender Selection:** ```bash -export PROMETHEUS_RW2_COMPLIANCE_SENDERS="prometheus" +prometheus --web.enable-remote-write-receiver --enable-feature=native-histograms # Add config file. ``` -Currently supported senders: -- `prometheus` - The reference Prometheus implementation (automatically downloaded) +### Configuration -**Test Timeout:** -```bash -export PROMETHEUS_RW2_COMPLIANCE_TEST_TIMEOUT="10m" -``` - -### Receiver Configuration The main configuration file `config.yml` in the `/remotewrite/receiver/` directory controls which receiver endpoints to test. It follows the Prometheus [`remote_write`](https://prometheus.io/docs/prometheus/latest/configuration/configuration/#remote_write) structure: ```yaml @@ -94,48 +133,24 @@ If no `config.yml` exists, the test suite will fall back to `config_example.yml` Alternatively, use the `PROMETHEUS_RW2_COMPLIANCE_CONFIG_FILE` environment variable. **Receiver Filtering:** -```bash -export PROMETHEUS_RW2_COMPLIANCE_RECEIVERS="local-prometheus,mimir" -``` -## Running Tests +You can configure which remote write endpoints to test from the provided `PROMETHEUS_RW2_COMPLIANCE_CONFIG_FILE` file +via the `PROMETHEUS_RW2_COMPLIANCE_RECEIVERS` environment variable: -### Sender Tests ```bash -PROMETHEUS_RW2_COMPLIANCE_SENDERS="prometheus" go test -v -# Or other sender if you want -``` - -### Receiver Tests -```bash -PROMETHEUS_RW2_COMPLIANCE_RECEIVERS="local-prometheus" go test -v -# Or other receiver if you want +export PROMETHEUS_RW2_COMPLIANCE_RECEIVERS="local-prometheus,mimir" ``` -## HTML Visualization - -Both sender and receiver test suites include an `index.html` file that enables viewing compliance test results. - -To generate and view results: +### Running Tests -**For Sender Tests:** ```bash -cd sender -go test -json | tee results.json -# Open index.html in your browser +make receiver ``` -**For Receiver Tests:** +To use visualization HTML page: + ```bash -cd receiver -go test -json | tee results.json -# Open index.html in your browser +make receiver-web ``` -## Protocol Compliance Levels - -Tests are marked with compliance levels according to RFC specifications: -- **MUST**: Required by specification -- **SHOULD**: Recommended by specification -- **MAY**: Could have by specification -- **RECOMMENDED**: Not in specification but recommended for performance +See Makefile for detailed invocation. diff --git a/remotewrite/index.html b/remotewrite/index.html index 64a0063..675844c 100644 --- a/remotewrite/index.html +++ b/remotewrite/index.html @@ -1,3 +1,18 @@ + @@ -35,11 +50,6 @@

Remote-Write v2 — Test Matrix

- - Receiver - Sender - -