Skip to content

Commit 697668d

Browse files
committed
wip: add test for https and ws reconnect
1 parent 25b1340 commit 697668d

File tree

4 files changed

+68
-7
lines changed

4 files changed

+68
-7
lines changed

src/node/main.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { field, logger } from "@coder/logger"
22
import http from "http"
3+
import https from "https"
34
import * as os from "os"
45
import path from "path"
56
import { Disposable } from "../common/emitter"
@@ -89,7 +90,7 @@ export const openInExistingInstance = async (args: DefaultedArgs, socketPath: st
8990

9091
export const runCodeServer = async (
9192
args: DefaultedArgs,
92-
): Promise<{ dispose: Disposable["dispose"]; server: http.Server }> => {
93+
): Promise<{ dispose: Disposable["dispose"]; server: http.Server | https.Server }> => {
9394
logger.info(`code-server ${version} ${commit}`)
9495

9596
logger.info(`Using user-data-dir ${humanPath(os.homedir(), args["user-data-dir"])}`)

test/unit/node/routes/health.test.ts

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import * as httpserver from "../../../utils/httpserver"
22
import * as integration from "../../../utils/integration"
33

4-
describe("health", () => {
5-
let codeServer: httpserver.HttpServer | undefined
4+
describe("health (http)", () => {
5+
let codeServer: httpserver.HttpServer | httpserver.HttpsServer | undefined
66

77
afterEach(async () => {
88
if (codeServer) {
@@ -38,3 +38,47 @@ describe("health", () => {
3838
expect(message).toStrictEqual({ event: "health", status: "expired", lastHeartbeat: 0 })
3939
})
4040
})
41+
42+
describe("health (https)", () => {
43+
let codeServer: httpserver.HttpServer | httpserver.HttpsServer | undefined
44+
45+
afterEach(async () => {
46+
if (codeServer) {
47+
await codeServer.dispose()
48+
codeServer = undefined
49+
}
50+
})
51+
52+
it("/healthz (websocket) with --cert", async () => {
53+
// NOTES@jsjoeio
54+
// We connect to /healthz via a websocket
55+
// and send a message and then we expect it to work
56+
// with our HTTPS server
57+
// and the cert arg passed in as well.
58+
// Notes from Slack
59+
// Ahser said "we could connect it to /vscode
60+
// Add the appropriate query variables (it expects connectionType and some other things, probably easiest to look at the browser and see)
61+
// Then it might be enough to just see if that connection errors or not
62+
// If it does not error then you probably have to try actually sending some data on it"
63+
// Not sure what do do there. Guess I need to spin up code-server
64+
// and look at the network tab.
65+
// Also confused on the /healthz vs /vscode part
66+
// The websocket runs on /healthz. Is that it?
67+
codeServer = await integration.setup(["--auth=none", "--cert"], "")
68+
const ws = codeServer.ws("/healthz")
69+
const message = await new Promise((resolve, reject) => {
70+
ws.on("error", console.error)
71+
ws.on("message", (message) => {
72+
try {
73+
const j = JSON.parse(message.toString())
74+
resolve(j)
75+
} catch (error) {
76+
reject(error)
77+
}
78+
})
79+
ws.on("open", () => ws.send(JSON.stringify({ event: "health" })))
80+
})
81+
ws.terminate()
82+
expect(message).toStrictEqual({ event: "health", status: "expired", lastHeartbeat: 0 })
83+
})
84+
})

test/utils/httpserver.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { logger } from "@coder/logger"
22
import * as express from "express"
33
import * as http from "http"
4+
import * as https from "https"
45
import nodeFetch, { RequestInit, Response } from "node-fetch"
56
import Websocket from "ws"
67
import { Disposable } from "../../src/common/emitter"
@@ -10,9 +11,11 @@ import { disposer } from "../../src/node/http"
1011

1112
import { handleUpgrade } from "../../src/node/wsRouter"
1213

14+
export type HttpOrHttpsServer = http.Server | https.Server
15+
1316
// Perhaps an abstraction similar to this should be used in app.ts as well.
1417
export class HttpServer {
15-
private hs: http.Server
18+
protected hs: HttpOrHttpsServer
1619
public dispose: Disposable["dispose"]
1720

1821
/**
@@ -21,7 +24,7 @@ export class HttpServer {
2124
*
2225
* Otherwise a new server is created.
2326
*/
24-
public constructor(server?: { server: http.Server; dispose: Disposable["dispose"] }) {
27+
public constructor(server?: { server: HttpOrHttpsServer; dispose: Disposable["dispose"] }) {
2528
this.hs = server?.server || http.createServer()
2629
this.dispose = server?.dispose || disposer(this.hs)
2730
}
@@ -94,3 +97,13 @@ export class HttpServer {
9497
throw new Error("server not listening or listening on unix socket")
9598
}
9699
}
100+
101+
export class HttpsServer extends HttpServer {
102+
protected hs: HttpOrHttpsServer
103+
104+
public constructor(server?: { server: HttpOrHttpsServer; dispose: Disposable["dispose"] }) {
105+
super()
106+
this.hs = server?.server || https.createServer()
107+
this.dispose = server?.dispose || disposer(this.hs)
108+
}
109+
}

test/utils/integration.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import { workspaceDir } from "./constants"
66
import { tmpdir } from "./helpers"
77
import * as httpserver from "./httpserver"
88

9-
export async function setup(argv: string[], configFile?: string): Promise<httpserver.HttpServer> {
9+
export async function setup(
10+
argv: string[],
11+
configFile?: string,
12+
): Promise<httpserver.HttpServer | httpserver.HttpsServer> {
1013
// This will be used as the data directory to ensure instances do not bleed
1114
// into each other.
1215
const dir = await tmpdir(workspaceDir)
@@ -27,5 +30,5 @@ export async function setup(argv: string[], configFile?: string): Promise<httpse
2730

2831
const server = await runCodeServer(args)
2932

30-
return new httpserver.HttpServer(server)
33+
return args.cert ? new httpserver.HttpsServer(server) : new httpserver.HttpServer(server)
3134
}

0 commit comments

Comments
 (0)