python.pkgs.pyqt5: 5.14.2 -> 5.15.0
[NixPkgs.git] / nixos / tests / prometheus.nix
blobaf2aa66a5526631af3b3b06f2a800e43d47366ef
1 let
2   grpcPort   = 19090;
3   queryPort  =  9090;
4   minioPort  =  9000;
5   pushgwPort =  9091;
7   s3 = {
8     accessKey = "BKIKJAA5BMMU2RHO6IBB";
9     secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12";
10   };
12   objstore.config = {
13     type = "S3";
14     config = {
15       bucket = "thanos-bucket";
16       endpoint = "s3:${toString minioPort}";
17       region =  "us-east-1";
18       access_key = s3.accessKey;
19       secret_key = s3.secretKey;
20       insecure = true;
21       signature_version2 = false;
22       encrypt_sse =  false;
23       put_user_metadata = {};
24       http_config = {
25         idle_conn_timeout = "0s";
26         insecure_skip_verify = false;
27       };
28       trace = {
29         enable = false;
30       };
31     };
32   };
34 in import ./make-test-python.nix {
35   name = "prometheus";
37   nodes = {
38     prometheus = { pkgs, ... }: {
39       virtualisation.diskSize = 2 * 1024;
40       environment.systemPackages = [ pkgs.jq ];
41       networking.firewall.allowedTCPPorts = [ grpcPort ];
42       services.prometheus = {
43         enable = true;
44         scrapeConfigs = [
45           {
46             job_name = "prometheus";
47             static_configs = [
48               {
49                 targets = [ "127.0.0.1:${toString queryPort}" ];
50                 labels = { instance = "localhost"; };
51               }
52             ];
53           }
54           {
55             job_name = "pushgateway";
56             scrape_interval = "1s";
57             static_configs = [
58               {
59                 targets = [ "127.0.0.1:${toString pushgwPort}" ];
60               }
61             ];
62           }
63         ];
64         rules = [
65           ''
66             groups:
67               - name: test
68                 rules:
69                   - record: testrule
70                     expr: count(up{job="prometheus"})
71           ''
72         ];
73         globalConfig = {
74           external_labels = {
75             some_label = "required by thanos";
76           };
77         };
78         extraFlags = [
79           # Required by thanos
80           "--storage.tsdb.min-block-duration=5s"
81           "--storage.tsdb.max-block-duration=5s"
82         ];
83       };
84       services.prometheus.pushgateway = {
85         enable = true;
86         web.listen-address = ":${toString pushgwPort}";
87         persistMetrics = true;
88         persistence.interval = "1s";
89         stateDir = "prometheus-pushgateway";
90       };
91       services.thanos = {
92         sidecar = {
93           enable = true;
94           grpc-address = "0.0.0.0:${toString grpcPort}";
95           inherit objstore;
96         };
98         # TODO: Add some tests for these services:
99         #rule = {
100         #  enable = true;
101         #  http-address = "0.0.0.0:19194";
102         #  grpc-address = "0.0.0.0:19193";
103         #  query.addresses = [
104         #    "localhost:19191"
105         #  ];
106         #  labels = {
107         #    just = "some";
108         #    nice = "labels";
109         #  };
110         #};
111         #
112         #receive = {
113         #  http-address = "0.0.0.0:19195";
114         #  enable = true;
115         #  labels = {
116         #    just = "some";
117         #    nice = "labels";
118         #  };
119         #};
120       };
121     };
123     query = { pkgs, ... }: {
124       environment.systemPackages = [ pkgs.jq ];
125       services.thanos.query = {
126         enable = true;
127         http-address = "0.0.0.0:${toString queryPort}";
128         store.addresses = [
129           "prometheus:${toString grpcPort}"
130         ];
131       };
132     };
134     store = { pkgs, ... }: {
135       virtualisation.diskSize = 2 * 1024;
136       environment.systemPackages = with pkgs; [ jq thanos ];
137       services.thanos.store = {
138         enable = true;
139         http-address = "0.0.0.0:10902";
140         grpc-address = "0.0.0.0:${toString grpcPort}";
141         inherit objstore;
142         sync-block-duration = "1s";
143       };
144       services.thanos.compact = {
145         enable = true;
146         http-address = "0.0.0.0:10903";
147         inherit objstore;
148         consistency-delay = "5s";
149       };
150       services.thanos.query = {
151         enable = true;
152         http-address = "0.0.0.0:${toString queryPort}";
153         store.addresses = [
154           "localhost:${toString grpcPort}"
155         ];
156       };
157     };
159     s3 = { pkgs, ... } : {
160       # Minio requires at least 1GiB of free disk space to run.
161       virtualisation = {
162         diskSize = 2 * 1024;
163         memorySize = 1024;
164       };
165       networking.firewall.allowedTCPPorts = [ minioPort ];
167       services.minio = {
168         enable = true;
169         inherit (s3) accessKey secretKey;
170       };
172       environment.systemPackages = [ pkgs.minio-client ];
173     };
174   };
176   testScript = { nodes, ... } : ''
177     # Before starting the other machines we first make sure that our S3 service is online
178     # and has a bucket added for thanos:
179     s3.start()
180     s3.wait_for_unit("minio.service")
181     s3.wait_for_open_port(${toString minioPort})
182     s3.succeed(
183         "mc config host add minio "
184         + "http://localhost:${toString minioPort} "
185         + "${s3.accessKey} ${s3.secretKey} --api s3v4",
186         "mc mb minio/thanos-bucket",
187     )
189     # Now that s3 has started we can start the other machines:
190     for machine in prometheus, query, store:
191         machine.start()
193     # Check if prometheus responds to requests:
194     prometheus.wait_for_unit("prometheus.service")
195     prometheus.wait_for_open_port(${toString queryPort})
196     prometheus.succeed("curl -s http://127.0.0.1:${toString queryPort}/metrics")
198     # Let's test if pushing a metric to the pushgateway succeeds:
199     prometheus.wait_for_unit("pushgateway.service")
200     prometheus.succeed(
201         "echo 'some_metric 3.14' | "
202         + "curl --data-binary \@- "
203         + "http://127.0.0.1:${toString pushgwPort}/metrics/job/some_job"
204     )
206     # Now check whether that metric gets ingested by prometheus.
207     # Since we'll check for the metric several times on different machines
208     # we abstract the test using the following function:
210     # Function to check if the metric "some_metric" has been received and returns the correct value.
211     def wait_for_metric(machine):
212         return machine.wait_until_succeeds(
213             "curl -sf 'http://127.0.0.1:${toString queryPort}/api/v1/query?query=some_metric' | "
214             + "jq '.data.result[0].value[1]' | grep '\"3.14\"'"
215         )
218     wait_for_metric(prometheus)
220     # Let's test if the pushgateway persists metrics to the configured location.
221     prometheus.wait_until_succeeds("test -e /var/lib/prometheus-pushgateway/metrics")
223     # Test thanos
224     prometheus.wait_for_unit("thanos-sidecar.service")
226     # Test if the Thanos query service can correctly retrieve the metric that was send above.
227     query.wait_for_unit("thanos-query.service")
228     wait_for_metric(query)
230     # Test if the Thanos sidecar has correctly uploaded its TSDB to S3, if the
231     # Thanos storage service has correctly downloaded it from S3 and if the Thanos
232     # query service running on $store can correctly retrieve the metric:
233     store.wait_for_unit("thanos-store.service")
234     wait_for_metric(store)
236     store.wait_for_unit("thanos-compact.service")
238     # Test if the Thanos bucket command is able to retrieve blocks from the S3 bucket
239     # and check if the blocks have the correct labels:
240     store.succeed(
241         "thanos tools bucket ls "
242         + "--objstore.config-file=${nodes.store.config.services.thanos.store.objstore.config-file} "
243         + "--output=json | "
244         + "jq .thanos.labels.some_label | "
245         + "grep 'required by thanos'"
246     )
247   '';