aboutsummaryrefslogtreecommitdiff
path: root/nixpkgs/nixos/tests/prometheus.nix
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/nixos/tests/prometheus.nix')
-rw-r--r--nixpkgs/nixos/tests/prometheus.nix239
1 files changed, 239 insertions, 0 deletions
diff --git a/nixpkgs/nixos/tests/prometheus.nix b/nixpkgs/nixos/tests/prometheus.nix
new file mode 100644
index 00000000000..52f61046be3
--- /dev/null
+++ b/nixpkgs/nixos/tests/prometheus.nix
@@ -0,0 +1,239 @@
+let
+ grpcPort = 19090;
+ queryPort = 9090;
+ minioPort = 9000;
+ pushgwPort = 9091;
+
+ s3 = {
+ accessKey = "BKIKJAA5BMMU2RHO6IBB";
+ secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12";
+ };
+
+ objstore.config = {
+ type = "S3";
+ config = {
+ bucket = "thanos-bucket";
+ endpoint = "s3:${toString minioPort}";
+ region = "us-east-1";
+ access_key = s3.accessKey;
+ secret_key = s3.secretKey;
+ insecure = true;
+ signature_version2 = false;
+ encrypt_sse = false;
+ put_user_metadata = {};
+ http_config = {
+ idle_conn_timeout = "0s";
+ insecure_skip_verify = false;
+ };
+ trace = {
+ enable = false;
+ };
+ };
+ };
+
+in import ./make-test.nix {
+ name = "prometheus";
+
+ nodes = {
+ prometheus = { pkgs, ... }: {
+ virtualisation.diskSize = 2 * 1024;
+ environment.systemPackages = [ pkgs.jq ];
+ networking.firewall.allowedTCPPorts = [ grpcPort ];
+ services.prometheus = {
+ enable = true;
+ scrapeConfigs = [
+ {
+ job_name = "prometheus";
+ static_configs = [
+ {
+ targets = [ "127.0.0.1:${toString queryPort}" ];
+ labels = { instance = "localhost"; };
+ }
+ ];
+ }
+ {
+ job_name = "pushgateway";
+ scrape_interval = "1s";
+ static_configs = [
+ {
+ targets = [ "127.0.0.1:${toString pushgwPort}" ];
+ }
+ ];
+ }
+ ];
+ rules = [
+ ''
+ groups:
+ - name: test
+ rules:
+ - record: testrule
+ expr: count(up{job="prometheus"})
+ ''
+ ];
+ globalConfig = {
+ external_labels = {
+ some_label = "required by thanos";
+ };
+ };
+ extraFlags = [
+ # Required by thanos
+ "--storage.tsdb.min-block-duration=5s"
+ "--storage.tsdb.max-block-duration=5s"
+ ];
+ };
+ services.prometheus.pushgateway = {
+ enable = true;
+ web.listen-address = ":${toString pushgwPort}";
+ persistMetrics = true;
+ persistence.interval = "1s";
+ stateDir = "prometheus-pushgateway";
+ };
+ services.thanos = {
+ sidecar = {
+ enable = true;
+ grpc-address = "0.0.0.0:${toString grpcPort}";
+ inherit objstore;
+ };
+
+ # TODO: Add some tests for these services:
+ #rule = {
+ # enable = true;
+ # http-address = "0.0.0.0:19194";
+ # grpc-address = "0.0.0.0:19193";
+ # query.addresses = [
+ # "localhost:19191"
+ # ];
+ # labels = {
+ # just = "some";
+ # nice = "labels";
+ # };
+ #};
+ #
+ #receive = {
+ # http-address = "0.0.0.0:19195";
+ # enable = true;
+ # labels = {
+ # just = "some";
+ # nice = "labels";
+ # };
+ #};
+ };
+ };
+
+ query = { pkgs, ... }: {
+ environment.systemPackages = [ pkgs.jq ];
+ services.thanos.query = {
+ enable = true;
+ http-address = "0.0.0.0:${toString queryPort}";
+ store.addresses = [
+ "prometheus:${toString grpcPort}"
+ ];
+ };
+ };
+
+ store = { pkgs, ... }: {
+ virtualisation.diskSize = 2 * 1024;
+ environment.systemPackages = with pkgs; [ jq thanos ];
+ services.thanos.store = {
+ enable = true;
+ http-address = "0.0.0.0:10902";
+ grpc-address = "0.0.0.0:${toString grpcPort}";
+ inherit objstore;
+ sync-block-duration = "1s";
+ };
+ services.thanos.compact = {
+ enable = true;
+ http-address = "0.0.0.0:10903";
+ inherit objstore;
+ consistency-delay = "5s";
+ };
+ services.thanos.query = {
+ enable = true;
+ http-address = "0.0.0.0:${toString queryPort}";
+ store.addresses = [
+ "localhost:${toString grpcPort}"
+ ];
+ };
+ };
+
+ s3 = { pkgs, ... } : {
+ # Minio requires at least 1GiB of free disk space to run.
+ virtualisation.diskSize = 2 * 1024;
+ networking.firewall.allowedTCPPorts = [ minioPort ];
+
+ services.minio = {
+ enable = true;
+ inherit (s3) accessKey secretKey;
+ };
+
+ environment.systemPackages = [ pkgs.minio-client ];
+ };
+ };
+
+ testScript = { nodes, ... } : ''
+ # Before starting the other machines we first make sure that our S3 service is online
+ # and has a bucket added for thanos:
+ $s3->start;
+ $s3->waitForUnit("minio.service");
+ $s3->waitForOpenPort(${toString minioPort});
+ $s3->succeed(
+ "mc config host add minio " .
+ "http://localhost:${toString minioPort} ${s3.accessKey} ${s3.secretKey} S3v4");
+ $s3->succeed("mc mb minio/thanos-bucket");
+
+ # Now that s3 has started we can start the other machines:
+ $prometheus->start;
+ $query->start;
+ $store->start;
+
+ # Check if prometheus responds to requests:
+ $prometheus->waitForUnit("prometheus.service");
+ $prometheus->waitForOpenPort(${toString queryPort});
+ $prometheus->succeed("curl -s http://127.0.0.1:${toString queryPort}/metrics");
+
+ # Let's test if pushing a metric to the pushgateway succeeds:
+ $prometheus->waitForUnit("pushgateway.service");
+ $prometheus->succeed(
+ "echo 'some_metric 3.14' | " .
+ "curl --data-binary \@- http://127.0.0.1:${toString pushgwPort}/metrics/job/some_job");
+
+ # Now check whether that metric gets ingested by prometheus.
+ # Since we'll check for the metric several times on different machines
+ # we abstract the test using the following function:
+
+ # Function to check if the metric "some_metric" has been received and returns the correct value.
+ local *Machine::waitForMetric = sub {
+ my ($self) = @_;
+ $self->waitUntilSucceeds(
+ "curl -sf 'http://127.0.0.1:${toString queryPort}/api/v1/query?query=some_metric' " .
+ "| jq '.data.result[0].value[1]' | grep '\"3.14\"'");
+ };
+
+ $prometheus->waitForMetric;
+
+ # Let's test if the pushgateway persists metrics to the configured location.
+ $prometheus->waitUntilSucceeds("test -e /var/lib/prometheus-pushgateway/metrics");
+
+ # Test thanos
+ $prometheus->waitForUnit("thanos-sidecar.service");
+
+ # Test if the Thanos query service can correctly retrieve the metric that was send above.
+ $query->waitForUnit("thanos-query.service");
+ $query->waitForMetric;
+
+ # Test if the Thanos sidecar has correctly uploaded its TSDB to S3, if the
+ # Thanos storage service has correctly downloaded it from S3 and if the Thanos
+ # query service running on $store can correctly retrieve the metric:
+ $store->waitForUnit("thanos-store.service");
+ $store->waitForMetric;
+
+ $store->waitForUnit("thanos-compact.service");
+
+ # Test if the Thanos bucket command is able to retrieve blocks from the S3 bucket
+ # and check if the blocks have the correct labels:
+ $store->succeed(
+ "thanos bucket ls" .
+ " --objstore.config-file=${nodes.store.config.services.thanos.store.objstore.config-file}" .
+ " --output=json | jq .thanos.labels.some_label | grep 'required by thanos'");
+ '';
+}