1 import ./make-test-python.nix ({ lib, ... }@args: let
2 pkgs = args.pkgs.extend (self: super: {
3 stdenv = super.stdenv.override {
4 config = super.config // {
5 allowUnfreePredicate = pkg: builtins.elem (lib.getName pkg) [
6 "vscode" "vscode-with-extensions" "vscode-extension-ms-vscode-remote-remote-ssh"
12 inherit (import ./ssh-keys.nix pkgs) snakeOilPrivateKey snakeOilPublicKey;
14 inherit (pkgs.vscode.passthru) rev vscodeServer;
16 name = "vscode-remote-ssh";
24 serverAddress = "192.168.0.2";
25 clientAddress = "192.168.0.1";
28 networking.interfaces.eth1.ipv4.addresses = [ { address = serverAddress; prefixLength = 24; } ];
29 services.openssh.enable = true;
30 users.users.root.openssh.authorizedKeys.keys = [ snakeOilPublicKey ];
31 virtualisation.additionalPaths = with pkgs; [ patchelf bintools stdenv.cc.cc.lib ];
34 imports = [ ./common/x11.nix ./common/user-account.nix ];
35 networking.interfaces.eth1.ipv4.addresses = [ { address = clientAddress; prefixLength = 24; } ];
36 networking.hosts.${serverAddress} = [ "server" ];
37 test-support.displayManager.auto.user = "alice";
38 environment.systemPackages = [
39 (pkgs.vscode-with-extensions.override {
41 pkgs.vscode-extensions.ms-vscode-remote.remote-ssh
51 jq = "${pkgs.jq}/bin/jq";
53 sshConfig = builtins.toFile "ssh.conf" ''
54 UserKnownHostsFile=/dev/null
55 StrictHostKeyChecking=no
58 vscodeConfig = builtins.toFile "settings.json" ''
60 "window.zoomLevel": 1,
61 "security.workspace.trust.startupPrompt": "always"
65 def connect_with_remote_ssh(screenshot, should_succeed):
66 print(f"connect_with_remote_ssh({screenshot=}, {should_succeed=})")
68 if server.execute("test -d ~/.vscode-server")[0] == 0:
69 server.succeed("rm -r ~/.vscode-server")
71 server.succeed("mkdir -p ~/.vscode-server/bin")
72 server.succeed("cp -r ${vscodeServer} ~/.vscode-server/bin/${rev}")
74 client.succeed("sudo -u alice code --remote=ssh-remote+root@server /root")
75 client.wait_for_window("Visual Studio Code")
78 ocr_text = "Do you trust"
80 ocr_text = "Could not establish connection"
81 client.wait_for_text(ocr_text)
82 client.screenshot(screenshot)
85 # Press the Don't Trust button
86 client.send_key("tab")
87 client.send_key("tab")
88 client.send_key("tab")
91 # Close the error dialog
92 client.send_key("esc")
94 # Don't send Ctrl-q too quickly otherwise it might not get sent to VS Code
96 client.send_key("ctrl-q")
97 client.wait_until_fails("pidof code")
101 server.wait_for_open_port(22)
103 VSCODE_COMMIT = server.execute("${jq} -r .commit ${pkgs.vscode}/lib/vscode/resources/app/product.json")[1].rstrip()
104 SERVER_COMMIT = server.execute("${jq} -r .commit ${vscodeServer}/product.json")[1].rstrip()
106 print(f"{VSCODE_COMMIT=} {SERVER_COMMIT=}")
107 assert VSCODE_COMMIT == SERVER_COMMIT, "VSCODE_COMMIT and SERVER_COMMIT do not match"
109 client.wait_until_succeeds("ping -c1 server")
110 client.succeed("sudo -u alice mkdir ~alice/.ssh")
111 client.succeed("sudo -u alice install -Dm 600 ${snakeOilPrivateKey} ~alice/.ssh/id_ecdsa")
112 client.succeed("sudo -u alice install ${sshConfig} ~alice/.ssh/config")
113 client.succeed("sudo -u alice install -Dm 644 ${vscodeConfig} ~alice/.config/Code/User/settings.json")
116 client.wait_for_file("~alice/.Xauthority")
117 client.succeed("xauth merge ~alice/.Xauthority")
118 # Move the mouse out of the way
119 client.succeed("${pkgs.xdotool}/bin/xdotool mousemove 0 0")
121 with subtest("fails to connect when nixpkgs isn't available"):
122 server.fail("nix-build '<nixpkgs>' -A hello")
123 connect_with_remote_ssh(screenshot="no_node_installed", should_succeed=False)
124 server.succeed("test -e ~/.vscode-server/bin/${rev}/node")
125 server.fail("~/.vscode-server/bin/${rev}/node -v")
127 with subtest("connects when server can patch Node"):
128 server.succeed("mkdir -p /nix/var/nix/profiles/per-user/root/channels")
129 server.succeed("ln -s ${pkgs.path} /nix/var/nix/profiles/per-user/root/channels/nixos")
130 connect_with_remote_ssh(screenshot="build_node_with_nix", should_succeed=True)