File size: 2,353 Bytes
307c245
2dae031
 
31daf3d
3dd1fa4
2dae031
d5636c9
 
 
 
 
 
307c245
3dd1fa4
307c245
 
 
 
 
 
 
d5636c9
 
 
 
 
2dae031
d5636c9
31daf3d
 
 
d5636c9
2dae031
d5636c9
2dae031
d5636c9
 
 
31daf3d
d5636c9
2dae031
d5636c9
31daf3d
d5636c9
31daf3d
 
 
 
d5636c9
2dae031
d5636c9
31daf3d
dae4e82
d5636c9
2dae031
d5636c9
2dae031
d5636c9
2dae031
31daf3d
2dae031
d5636c9
2dae031
d5636c9
 
 
 
307c245
 
 
 
 
d5636c9
 
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
import { afterEach, assert, beforeAll, describe, expect, it } from "vitest";
import { migrations } from "./routines";
import { acquireLock, isDBLocked, refreshLock, releaseLock } from "./lock";
import { Semaphores } from "$lib/types/Semaphore";
import { collections, ready } from "$lib/server/database";

describe(
	"migrations",
	{
		retry: 3,
	},
	() => {
		beforeAll(async () => {
			await ready;
			try {
				await collections.semaphores.createIndex({ key: 1 }, { unique: true });
			} catch (e) {
				// Index might already exist, ignore error
			}
		});

		it("should not have duplicates guid", async () => {
			const guids = migrations.map((m) => m._id.toString());
			const uniqueGuids = [...new Set(guids)];
			expect(uniqueGuids.length).toBe(guids.length);
		});

		it("should acquire only one lock on DB", async () => {
			const results = await Promise.all(
				new Array(1000).fill(0).map(() => acquireLock(Semaphores.TEST_MIGRATION))
			);
			const locks = results.filter((r) => r);

			const semaphores = await collections.semaphores.find({}).toArray();

			expect(locks.length).toBe(1);
			expect(semaphores).toBeDefined();
			expect(semaphores.length).toBe(1);
			expect(semaphores?.[0].key).toBe(Semaphores.TEST_MIGRATION);
		});

		it("should read the lock correctly", async () => {
			const lockId = await acquireLock(Semaphores.TEST_MIGRATION);
			assert(lockId);
			expect(await isDBLocked(Semaphores.TEST_MIGRATION)).toBe(true);
			expect(!!(await acquireLock(Semaphores.TEST_MIGRATION))).toBe(false);
			await releaseLock(Semaphores.TEST_MIGRATION, lockId);
			expect(await isDBLocked(Semaphores.TEST_MIGRATION)).toBe(false);
		});

		it("should refresh the lock", async () => {
			const lockId = await acquireLock(Semaphores.TEST_MIGRATION);

			assert(lockId);

			// get the updatedAt time

			const updatedAtInitially = (await collections.semaphores.findOne({}))?.updatedAt;

			await refreshLock(Semaphores.TEST_MIGRATION, lockId);

			const updatedAtAfterRefresh = (await collections.semaphores.findOne({}))?.updatedAt;

			expect(updatedAtInitially).toBeDefined();
			expect(updatedAtAfterRefresh).toBeDefined();
			expect(updatedAtInitially).not.toBe(updatedAtAfterRefresh);
		});

		afterEach(async () => {
			await collections.semaphores.deleteMany({});
			await collections.migrationResults.deleteMany({});
		});
	}
);