1import ./make-test-python.nix (
2 { lib, ... }@args:
3 let
4 pkgs = args.pkgs.extend (
5 self: super: {
6 stdenv = super.stdenv.override {
7 config = super.config // {
8 allowUnfreePredicate =
9 pkg:
10 builtins.elem (lib.getName pkg) [
11 "vscode"
12 "vscode-with-extensions"
13 "vscode-extension-ms-vscode-remote-remote-ssh"
14 ];
15 };
16 };
17 }
18 );
19
20 inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey;
21
22 inherit (pkgs.vscode.passthru) rev vscodeServer;
23 in
24 {
25 name = "vscode-remote-ssh";
26
27 meta = {
28 maintainers = [ ];
29 timeout = 600;
30 };
31
32 nodes =
33 let
34 serverAddress = "192.168.0.2";
35 clientAddress = "192.168.0.1";
36 in
37 {
38 server =
39 { ... }:
40 {
41 networking.interfaces.eth1.ipv4.addresses = [
42 {
43 address = serverAddress;
44 prefixLength = 24;
45 }
46 ];
47 services.openssh.enable = true;
48 users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
49 virtualisation.additionalPaths = with pkgs; [
50 patchelf
51 bintools
52 (lib.getLib stdenv.cc.cc)
53 ];
54 };
55 client =
56 { ... }:
57 {
58 imports = [
59 ./common/x11.nix
60 ./common/user-account.nix
61 ];
62 networking.interfaces.eth1.ipv4.addresses = [
63 {
64 address = clientAddress;
65 prefixLength = 24;
66 }
67 ];
68 networking.hosts.${serverAddress} = [ "server" ];
69 test-support.displayManager.auto.user = "alice";
70 environment.systemPackages = [
71 (pkgs.vscode-with-extensions.override {
72 vscodeExtensions = [
73 pkgs.vscode-extensions.ms-vscode-remote.remote-ssh
74 ];
75 })
76 ];
77 };
78 };
79
80 enableOCR = true;
81
82 testScript =
83 let
84 jq = "${pkgs.jq}/bin/jq";
85
86 sshConfig = builtins.toFile "ssh.conf" ''
87 UserKnownHostsFile=/dev/null
88 StrictHostKeyChecking=no
89 '';
90
91 vscodeConfig = builtins.toFile "settings.json" ''
92 {
93 "window.zoomLevel": 1,
94 "security.workspace.trust.startupPrompt": "always"
95 }
96 '';
97 in
98 ''
99 def connect_with_remote_ssh(screenshot, should_succeed):
100 print(f"connect_with_remote_ssh({screenshot=}, {should_succeed=})")
101
102 if server.execute("test -d ~/.vscode-server")[0] == 0:
103 server.succeed("rm -r ~/.vscode-server")
104
105 server.succeed("mkdir -p ~/.vscode-server/bin")
106 server.succeed("cp -r ${vscodeServer} ~/.vscode-server/bin/${rev}")
107
108 client.succeed("sudo -u alice code --remote=ssh-remote+root@server /root")
109 client.wait_for_window("Visual Studio Code")
110
111 if should_succeed:
112 ocr_text = "Do you trust"
113 else:
114 ocr_text = "Could not establish connection"
115 client.wait_for_text(ocr_text)
116 client.screenshot(screenshot)
117
118 if should_succeed:
119 # Press the Don't Trust button
120 client.send_key("tab")
121 client.send_key("tab")
122 client.send_key("tab")
123 client.send_key("\n")
124 else:
125 # Close the error dialog
126 client.send_key("esc")
127
128 # Don't send Ctrl-q too quickly otherwise it might not get sent to VS Code
129 client.sleep(1)
130 client.send_key("ctrl-q")
131 client.wait_until_fails("pidof code")
132
133
134 start_all()
135 server.wait_for_open_port(22)
136
137 VSCODE_COMMIT = server.execute("${jq} -r .commit ${pkgs.vscode}/lib/vscode/resources/app/product.json")[1].rstrip()
138 SERVER_COMMIT = server.execute("${jq} -r .commit ${vscodeServer}/product.json")[1].rstrip()
139
140 print(f"{VSCODE_COMMIT=} {SERVER_COMMIT=}")
141 assert VSCODE_COMMIT == SERVER_COMMIT, "VSCODE_COMMIT and SERVER_COMMIT do not match"
142
143 client.wait_until_succeeds("ping -c1 server")
144 client.succeed("sudo -u alice mkdir ~alice/.ssh")
145 client.succeed("sudo -u alice install -Dm 600 ${snakeOilPrivateKey} ~alice/.ssh/id_ecdsa")
146 client.succeed("sudo -u alice install ${sshConfig} ~alice/.ssh/config")
147 client.succeed("sudo -u alice install -Dm 644 ${vscodeConfig} ~alice/.config/Code/User/settings.json")
148
149 client.wait_for_x()
150 client.wait_for_file("~alice/.Xauthority")
151 client.succeed("xauth merge ~alice/.Xauthority")
152 # Move the mouse out of the way
153 client.succeed("${pkgs.xdotool}/bin/xdotool mousemove 0 0")
154
155 with subtest("fails to connect when nixpkgs isn't available"):
156 server.fail("nix-build '<nixpkgs>' -A hello")
157 connect_with_remote_ssh(screenshot="no_node_installed", should_succeed=False)
158 server.succeed("test -e ~/.vscode-server/bin/${rev}/node")
159 server.fail("~/.vscode-server/bin/${rev}/node -v")
160
161 with subtest("connects when server can patch Node"):
162 server.succeed("mkdir -p /nix/var/nix/profiles/per-user/root/channels")
163 server.succeed("ln -s ${pkgs.path} /nix/var/nix/profiles/per-user/root/channels/nixos")
164 connect_with_remote_ssh(screenshot="build_node_with_nix", should_succeed=True)
165 '';
166 }
167)