8 accessKey = "BKIKJAA5BMMU2RHO6IBB";
9 secretKey = "V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12";
15 bucket = "thanos-bucket";
16 endpoint = "s3:${toString minioPort}";
18 access_key = s3.accessKey;
19 secret_key = s3.secretKey;
21 signature_version2 = false;
23 put_user_metadata = {};
25 idle_conn_timeout = "0s";
26 insecure_skip_verify = false;
34 in import ./make-test-python.nix {
38 prometheus = { pkgs, ... }: {
39 virtualisation.diskSize = 2 * 1024;
40 environment.systemPackages = [ pkgs.jq ];
41 networking.firewall.allowedTCPPorts = [ grpcPort ];
42 services.prometheus = {
46 job_name = "prometheus";
49 targets = [ "127.0.0.1:${toString queryPort}" ];
50 labels = { instance = "localhost"; };
55 job_name = "pushgateway";
56 scrape_interval = "1s";
59 targets = [ "127.0.0.1:${toString pushgwPort}" ];
70 expr: count(up{job="prometheus"})
75 some_label = "required by thanos";
80 "--storage.tsdb.min-block-duration=5s"
81 "--storage.tsdb.max-block-duration=5s"
84 services.prometheus.pushgateway = {
86 web.listen-address = ":${toString pushgwPort}";
87 persistMetrics = true;
88 persistence.interval = "1s";
89 stateDir = "prometheus-pushgateway";
94 grpc-address = "0.0.0.0:${toString grpcPort}";
98 # TODO: Add some tests for these services:
101 # http-address = "0.0.0.0:19194";
102 # grpc-address = "0.0.0.0:19193";
103 # query.addresses = [
113 # http-address = "0.0.0.0:19195";
123 query = { pkgs, ... }: {
124 environment.systemPackages = [ pkgs.jq ];
125 services.thanos.query = {
127 http-address = "0.0.0.0:${toString queryPort}";
129 "prometheus:${toString grpcPort}"
134 store = { pkgs, ... }: {
135 virtualisation.diskSize = 2 * 1024;
136 environment.systemPackages = with pkgs; [ jq thanos ];
137 services.thanos.store = {
139 http-address = "0.0.0.0:10902";
140 grpc-address = "0.0.0.0:${toString grpcPort}";
142 sync-block-duration = "1s";
144 services.thanos.compact = {
146 http-address = "0.0.0.0:10903";
148 consistency-delay = "5s";
150 services.thanos.query = {
152 http-address = "0.0.0.0:${toString queryPort}";
154 "localhost:${toString grpcPort}"
159 s3 = { pkgs, ... } : {
160 # Minio requires at least 1GiB of free disk space to run.
165 networking.firewall.allowedTCPPorts = [ minioPort ];
169 inherit (s3) accessKey secretKey;
172 environment.systemPackages = [ pkgs.minio-client ];
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:
180 s3.wait_for_unit("minio.service")
181 s3.wait_for_open_port(${toString minioPort})
183 "mc config host add minio "
184 + "http://localhost:${toString minioPort} "
185 + "${s3.accessKey} ${s3.secretKey} --api s3v4",
186 "mc mb minio/thanos-bucket",
189 # Now that s3 has started we can start the other machines:
190 for machine in prometheus, query, store:
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")
201 "echo 'some_metric 3.14' | "
202 + "curl --data-binary \@- "
203 + "http://127.0.0.1:${toString pushgwPort}/metrics/job/some_job"
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\"'"
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")
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:
241 "thanos tools bucket ls "
242 + "--objstore.config-file=${nodes.store.config.services.thanos.store.objstore.config-file} "
244 + "jq .thanos.labels.some_label | "
245 + "grep 'required by thanos'"