okami.mom/albedo

git clone https://git.nkp.pet/okami.mom/albedo

Aly Raffaufrefactor(gleam): clean up code and enforce focused lint checksb585313

main
3.1 KiB97 linesraw
1//// The built-in daemon cannot install arbitrary test extensions. Probe the
2//// cross-extension contract here: schema-before-use, deferred data, order,
3//// backup propagation, disabled-but-installed owners, and failure short-circuit.
4
5import albedo/daemon/store
6import albedo/harness/extension
7import gleam/dynamic/decode
8import gleam/result
9import gleeunit/should
10import sqlight
11
12pub fn contributed_migrations_keep_their_phases_and_stop_on_failure_test() -> Nil {
13  let assert Ok(ledger) = store.start(":memory:", "")
14  let installed = [
15    extension.Extension(
16      "owner",
17      "",
18      [],
19      [
20        extension.MigrationPlugin(
21          extension.SchemaMigration(fn(db) {
22            store.add_columns(db, "owner", [#("revision", "INTEGER DEFAULT 1")])
23          }),
24        ),
25        extension.MigrationPlugin(
26          extension.DataMigration("owner-data", fn(ledger, backup) {
27            use _ <- result.try(store.read(
28              ledger,
29              "SELECT 1 FROM core_ready",
30              [],
31              decode.dynamic,
32            ))
33            store.write(
34              ledger,
35              "INSERT INTO applied(name,backup) VALUES('owner',?)",
36              [sqlight.text(backup)],
37            )
38            |> result.replace(1)
39          }),
40        ),
41      ],
42      fn(ledger) {
43        store.query(ledger, store.exec(
44          _,
45          "CREATE TABLE owner(id INTEGER); CREATE TABLE applied(name TEXT,backup TEXT)",
46        ))
47      },
48    ),
49    extension.Extension(
50      "sibling",
51      "",
52      [],
53      [
54        extension.MigrationPlugin(
55          extension.DataMigration("sibling-data", fn(ledger, backup) {
56            store.write(
57              ledger,
58              "INSERT INTO applied(name,backup) VALUES('sibling',?)",
59              [sqlight.text(backup)],
60            )
61            |> result.replace(1)
62          }),
63        ),
64      ],
65      fn(ledger) {
66        // This initialiser depends on the previous owner's schema upgrade.
67        store.write(ledger, "INSERT INTO owner(revision) VALUES(2)", [])
68      },
69    ),
70  ]
71  // Neither extension is enabled for sessions, but both own durable tables.
72  let assert Ok(#(_, [])) = extension.install(installed, [], ledger)
73  let assert Ok([2]) =
74    store.read(
75      ledger,
76      "SELECT revision FROM owner",
77      [],
78      decode.field(0, decode.int, decode.success),
79    )
80  let assert Ok([]) =
81    store.read(ledger, "SELECT * FROM applied", [], decode.dynamic)
82  let assert Error(_) = extension.migrate(installed, ledger, "/backup")
83  let assert Ok([]) =
84    store.read(ledger, "SELECT * FROM applied", [], decode.dynamic)
85  let assert Ok(_) =
86    store.query(ledger, store.exec(_, "CREATE TABLE core_ready(id INTEGER)"))
87  extension.migrate(installed, ledger, "/backup")
88  |> should.equal(Ok([#("owner-data", 1), #("sibling-data", 1)]))
89  let assert Ok(rows) =
90    store.read(ledger, "SELECT name,backup FROM applied ORDER BY rowid", [], {
91      use name <- decode.field(0, decode.string)
92      use backup <- decode.field(1, decode.string)
93      decode.success(#(name, backup))
94    })
95  rows |> should.equal([#("owner", "/backup"), #("sibling", "/backup")])
96  store.close(ledger)
97}