summaryrefslogtreecommitdiffstats
path: root/nixos/tests/invidious.nix
blob: 822f884d9a49f85f81dc0cb5354f3105c731b42a (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
149
150
151
152
{ ... }:
{
  name = "invidious";

  meta = {
    maintainers = [ ];
  };

  nodes = {
    postgres-tcp =
      { config, pkgs, ... }:
      {
        services.postgresql = {
          enable = true;
          initialScript = pkgs.writeText "init-postgres-with-password" ''
            CREATE USER invidious WITH PASSWORD 'correct horse battery staple';
            CREATE DATABASE invidious WITH OWNER invidious;
          '';
          enableTCPIP = true;
          authentication = ''
            host invidious invidious samenet scram-sha-256
          '';
        };
        networking.firewall.allowedTCPPorts = [ config.services.postgresql.settings.port ];
      };
    machine =
      { pkgs, ... }:
      {
        services.invidious = {
          enable = true;
        };

        specialisation = {
          nginx.configuration = {
            services.invidious = {
              nginx.enable = true;
              domain = "invidious.example.com";
            };
            services.nginx.virtualHosts."invidious.example.com" = {
              forceSSL = false;
              enableACME = false;
            };
            networking.hosts."127.0.0.1" = [ "invidious.example.com" ];
          };
          nginx-sig-helper.configuration = {
            services.invidious = {
              nginx.enable = true;
              domain = "invidious.example.com";
              sig-helper.enable = true;
              settings.log_level = "Trace";
            };
            services.nginx.virtualHosts."invidious.example.com" = {
              forceSSL = false;
              enableACME = false;
            };
            networking.hosts."127.0.0.1" = [ "invidious.example.com" ];
          };
          nginx-scale.configuration = {
            services.invidious = {
              nginx.enable = true;
              domain = "invidious.example.com";
              serviceScale = 3;
            };
            services.nginx.virtualHosts."invidious.example.com" = {
              forceSSL = false;
              enableACME = false;
            };
            networking.hosts."127.0.0.1" = [ "invidious.example.com" ];
          };
          nginx-scale-ytproxy.configuration = {
            services.invidious = {
              nginx.enable = true;
              http3-ytproxy.enable = true;
              domain = "invidious.example.com";
              serviceScale = 3;
            };
            services.nginx.virtualHosts."invidious.example.com" = {
              forceSSL = false;
              enableACME = false;
            };
            networking.hosts."127.0.0.1" = [ "invidious.example.com" ];
          };
          postgres-tcp.configuration = {
            services.invidious = {
              database = {
                createLocally = false;
                host = "postgres-tcp";
                passwordFile = toString (pkgs.writeText "database-password" "correct horse battery staple");
              };
            };
          };
        };
      };
  };

  testScript =
    { nodes, ... }:
    ''
      def curl_assert_status_code(url, code, form=None):
          assert int(machine.succeed(f"curl -s -o /dev/null -w %{{http_code}} {'-F ' + form + ' ' if form else '''}{url}")) == code


      def activate_specialisation(name: str):
          machine.succeed(f"${nodes.machine.system.build.toplevel}/specialisation/{name}/bin/switch-to-configuration test >&2")


      url = "http://localhost:${toString nodes.machine.services.invidious.port}"
      port = ${toString nodes.machine.services.invidious.port}

      # start postgres vm now
      postgres_tcp.start()

      machine.wait_for_open_port(port)
      curl_assert_status_code(f"{url}/search", 200)

      activate_specialisation("nginx")
      machine.wait_for_open_port(80)
      curl_assert_status_code("http://invidious.example.com/search", 200)

      activate_specialisation("nginx-scale")
      machine.wait_for_open_port(80)
      # this depends on nginx round-robin behaviour for the upstream servers
      curl_assert_status_code("http://invidious.example.com/search", 200)
      curl_assert_status_code("http://invidious.example.com/search", 200)
      curl_assert_status_code("http://invidious.example.com/search", 200)
      machine.succeed("journalctl -eu invidious.service | grep -o '200 GET /search'")
      machine.succeed("journalctl -eu invidious-1.service | grep -o '200 GET /search'")
      machine.succeed("journalctl -eu invidious-2.service | grep -o '200 GET /search'")

      activate_specialisation("nginx-scale-ytproxy")
      machine.wait_for_unit("http3-ytproxy.service")
      machine.wait_for_open_port(80)
      machine.wait_until_succeeds("ls /run/http3-ytproxy/socket/http-proxy.sock")
      curl_assert_status_code("http://invidious.example.com/search", 200)
      # this should error out as no internet connectivity is available in the test
      curl_assert_status_code("http://invidious.example.com/vi/dQw4w9WgXcQ/mqdefault.jpg", 502)
      machine.succeed("journalctl -eu http3-ytproxy.service | grep -o 'dQw4w9WgXcQ'")

      activate_specialisation("nginx-sig-helper")
      machine.wait_for_unit("invidious-sig-helper.service")
      # we can't really test the sig helper that well without internet connection...
      # invidious does connect to the sig helper though and crashes when the sig helper is not available
      machine.wait_for_open_port(80)
      curl_assert_status_code("http://invidious.example.com/search", 200)
      machine.succeed("journalctl -eu invidious.service | grep -o \"WARNING: Invidious companion is required to view and playback videos\"")

      postgres_tcp.wait_for_unit("postgresql.target")
      activate_specialisation("postgres-tcp")
      machine.wait_for_open_port(port)
      curl_assert_status_code(f"{url}/search", 200)
    '';
}