summaryrefslogtreecommitdiffstats
path: root/nixos/tests/prometheus/ui.nix
blob: b46766ffd2535990f9c48f81e356b00bc7535dbd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
{ lib, pkgs, ... }:

{
  name = "prometheus-ui";

  nodes = {
    browser =
      { config, pkgs, ... }:
      {
        virtualisation.memorySize = 1024 * 2;

        environment.systemPackages =
          let
            prometheusSeleniumScript =
              pkgs.writers.writePython3Bin "prometheus-selenium-script"
                {
                  libraries = with pkgs.python3Packages; [ selenium ];
                }
                ''
                  from selenium import webdriver
                  from selenium.webdriver.common.by import By
                  from selenium.webdriver.firefox.options import Options
                  from selenium.webdriver.support import expected_conditions as EC
                  from selenium.webdriver.support.ui import WebDriverWait

                  options = Options()
                  options.add_argument("--headless")
                  service = webdriver.FirefoxService(
                    executable_path="${lib.getExe pkgs.geckodriver}")  # noqa: E501

                  driver = webdriver.Firefox(options=options, service=service)
                  driver.implicitly_wait(10)

                  driver.get("http://prometheus:9090/")
                  wait = WebDriverWait(driver, 60)

                  # There should have been a redirect
                  wait.until(EC.url_to_be("http://prometheus:9090/query"))

                  wait.until(EC.presence_of_element_located(
                    (By.CLASS_NAME, "mantine-AppShell-header")))
                  wait.until(EC.presence_of_element_located(
                    (By.CLASS_NAME, "mantine-AppShell-main")))

                  # Do a Prometheus query
                  query_box = driver.find_element(
                    By.XPATH, "//div[@role='textbox']")
                  query_box.click()
                  query_box.send_keys("up")

                  # Run query with execute button
                  driver.find_element(
                    By.XPATH, "//span[contains(text(),'Execute')]").click()

                  # Wait for query result table
                  wait.until(EC.presence_of_element_located(
                    (By.CLASS_NAME, "mantine-Table-tr")))

                  # Navigate to target health page
                  driver.find_element(
                    By.XPATH, "//span[text()='Status']").click()

                  driver.find_element(
                    By.LINK_TEXT, "Target health").click()

                  wait.until(EC.url_to_be("http://prometheus:9090/targets"))

                  # Click on the prometheus job dropdown button
                  driver.find_element(
                    By.CLASS_NAME, "mantine-Accordion-chevron").click()

                  wait.until(EC.presence_of_element_located(
                    (By.CSS_SELECTOR, "div[class^='_healthOk']")))

                  targets_errored = len(driver.find_elements(
                    By.CSS_SELECTOR, "div[class^='_healthErr']"))
                  assert targets_errored == 0

                  # Go back to homepage
                  driver.find_element(
                    By.XPATH, "//span[text()='Query']").click()

                  # Navigate to build info section and verify correct version
                  # number shown
                  driver.find_element(
                    By.XPATH, "//span[text()='Status']").click()

                  driver.find_element(
                    By.LINK_TEXT, "Runtime & build information").click()

                  wait.until(EC.url_to_be("http://prometheus:9090/status"))

                  # Find table and verify version
                  wait.until(EC.text_to_be_present_in_element(
                    (By.XPATH,
                     "//tr[th[text()='version']]/td"),
                    "${pkgs.prometheus.version}"))

                  driver.close()
                '';
          in
          with pkgs;
          [
            curl
            firefox-unwrapped
            geckodriver
            prometheusSeleniumScript
          ];
      };

    prometheus =
      { config, pkgs, ... }:
      {
        networking.firewall.allowedTCPPorts = [ config.services.prometheus.port ];

        services.prometheus = {
          enable = true;
          globalConfig.scrape_interval = "2s";
          scrapeConfigs = [
            {
              job_name = "prometheus";
              static_configs = [
                {
                  targets = [
                    "prometheus:${toString config.services.prometheus.port}"
                  ];
                }
              ];
            }
          ];
        };
      };
  };

  testScript = ''
    prometheus.wait_for_unit("prometheus")
    prometheus.wait_for_open_port(9090)
    prometheus.wait_until_succeeds("curl -sSf http://localhost:9090/-/healthy")

    browser.systemctl("start network-online.target")
    browser.wait_for_unit("network-online.target")

    browser.succeed("curl -kLs http://prometheus:9090/query | grep 'Prometheus Time Series Collection and Processing Server'")

    # Ensure the application is actually rendered by the Javascript
    browser.succeed("PYTHONUNBUFFERED=1 prometheus-selenium-script")
  '';
}