Skip to content

Commit 7657cc3

Browse files
committed
Add test for state db migration
1 parent fbf2e19 commit 7657cc3

File tree

2 files changed

+90
-15
lines changed

2 files changed

+90
-15
lines changed

test/e2e/codeServer.test.ts

+79-15
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,45 @@
1+
import * as cp from "child_process"
12
import { promises as fs } from "fs"
3+
import * as os from "os"
24
import * as path from "path"
5+
import * as util from "util"
36
import { describe, test, expect } from "./baseFixture"
7+
import { CodeServer } from "./models/CodeServer"
8+
9+
describe("code-server", true, [], {}, () => {
10+
// TODO@asher: Generalize this? Could be nice if we were to ever need
11+
// multiple migration tests in other suites.
12+
const instances = new Map<string, CodeServer>()
13+
test.afterAll(async () => {
14+
const procs = Array.from(instances.values())
15+
instances.clear()
16+
await Promise.all(procs.map((cs) => cs.close()))
17+
})
18+
19+
/**
20+
* Spawn a specific version of code-server using the install script.
21+
*/
22+
const spawn = async (version: string, dir?: string): Promise<CodeServer> => {
23+
let instance = instances.get(version)
24+
if (!instance) {
25+
await util.promisify(cp.exec)(`./install.sh --method standalone --version ${version}`, {
26+
cwd: path.join(__dirname, "../.."),
27+
})
28+
29+
instance = new CodeServer(
30+
"code-server@" + version,
31+
["--auth=none"],
32+
{ VSCODE_DEV: "" },
33+
dir,
34+
`${os.homedir()}/.local/lib/code-server-${version}`,
35+
)
36+
37+
instances.set(version, instance)
38+
}
39+
40+
return instance
41+
}
442

5-
describe("CodeServer", true, [], {}, () => {
643
test("should navigate to home page", async ({ codeServerPage }) => {
744
// We navigate codeServer before each test
845
// and we start the test with a storage state
@@ -34,24 +71,51 @@ describe("CodeServer", true, [], {}, () => {
3471
await codeServerPage.openFile(file)
3572
})
3673

37-
test("should not share state with other paths", async ({ codeServerPage }) => {
74+
test("should migrate state to avoid collisions", async ({ codeServerPage }) => {
75+
// This can take a very long time in development because of how long pages
76+
// take to load and we are doing a lot of that here.
77+
test.slow()
78+
3879
const dir = await codeServerPage.workspaceDir
39-
const file = path.join(dir, "foo")
40-
await fs.writeFile(file, "bar")
80+
const files = [
81+
path.join(dir, "foo"),
82+
path.join(dir, "bar"),
83+
]
84+
await Promise.all(files.map((file) => {
85+
return fs.writeFile(file, path.basename(file))
86+
}))
4187

42-
await codeServerPage.openFile(file)
88+
// Open a file in the latest instance.
89+
await codeServerPage.openFile(files[0])
90+
await codeServerPage.stateFlush()
4391

44-
// If we reload now VS Code will be unable to save the state changes so wait
45-
// until those have been written to the database. It flushes every five
46-
// seconds so we need to wait at least that long.
47-
await codeServerPage.page.waitForTimeout(5500)
92+
// Open a file in an older version of code-server. It should not see the
93+
// file opened in the new instance since the database has a different
94+
// name. This must be accessed through the proxy so it shares the same
95+
// domain and can write to the same database.
96+
const cs = await spawn("4.0.2", dir)
97+
const address = new URL(await cs.address())
98+
await codeServerPage.navigate("/proxy/" + address.port + "/")
99+
await codeServerPage.openFile(files[1])
100+
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
101+
await codeServerPage.stateFlush()
48102

49-
// The tab should re-open on refresh.
50-
await codeServerPage.page.reload()
51-
await codeServerPage.waitForTab(file)
103+
// Move back to latest code-server. We should see the file we previously
104+
// opened with it but not the old code-server file because the new instance
105+
// already created its own database on this path and will avoid migrating.
106+
await codeServerPage.navigate()
107+
await codeServerPage.waitForTab(files[0])
108+
expect(await codeServerPage.tabIsVisible(files[1])).toBe(false)
52109

53-
// The tab should not re-open on a different path.
54-
await codeServerPage.setup(true, "/vscode")
55-
expect(await codeServerPage.tabIsVisible(file)).toBe(false)
110+
// Open a new path in latest code-server. This one should migrate the
111+
// database from old code-server but see nothing from the new database
112+
// created on the root.
113+
await codeServerPage.navigate("/vscode")
114+
await codeServerPage.waitForTab(files[1])
115+
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
116+
// Should still be open after a reload.
117+
await codeServerPage.navigate("/vscode")
118+
await codeServerPage.waitForTab(files[1])
119+
expect(await codeServerPage.tabIsVisible(files[0])).toBe(false)
56120
})
57121
})

test/e2e/models/CodeServer.ts

+11
Original file line numberDiff line numberDiff line change
@@ -483,4 +483,15 @@ export class CodeServerPage {
483483
cwd: path.join(__dirname, "../../.."),
484484
})
485485
}
486+
487+
/**
488+
* Wait for state to be flushed to the database.
489+
*/
490+
async stateFlush(): Promise<void> {
491+
// If we reload too quickly VS Code will be unable to save the state changes
492+
// so wait until those have been written to the database. It flushes every
493+
// five seconds so we need to wait at least that long.
494+
// TODO@asher: There must be a better way.
495+
await this.page.waitForTimeout(5500)
496+
}
486497
}

0 commit comments

Comments
 (0)