File size: 2,330 Bytes
0576898
b488195
 
48059af
b488195
 
991f8ec
 
 
 
 
 
0576898
 
 
 
 
 
 
 
991f8ec
 
 
 
 
b488195
991f8ec
48059af
 
 
991f8ec
b488195
991f8ec
b488195
991f8ec
 
 
48059af
991f8ec
b488195
991f8ec
48059af
991f8ec
48059af
 
 
 
991f8ec
b488195
991f8ec
48059af
1b76365
991f8ec
b488195
991f8ec
b488195
991f8ec
b488195
48059af
b488195
991f8ec
b488195
991f8ec
 
 
 
0576898
 
 
 
 
991f8ec
 
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
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 } from "$lib/server/database";

describe(
	"migrations",
	{
		retry: 3,
	},
	() => {
		beforeAll(async () => {
			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({});
		});
	}
);