Pre-launch — Gluecron is in final validation. Public signups and git hosting for non-owner users open after launch review.
CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
Blame · Line-by-line history

systemd-notify.test.ts

Each line is annotated with the commit that last touched it. Click any SHA to jump to that commit and see the surrounding change.

systemd-notify.test.tsBlame143 lines · 1 contributor
f764c07Claude1/**
2 * BLOCK N2 — systemd_notify(READY=1) helper tests.
3 *
4 * Covers the three guarantees the helper makes:
5 * 1. No-op when NOTIFY_SOCKET is unset (dev / non-systemd hosts).
6 * 2. When NOTIFY_SOCKET IS set, attempts to open a datagram socket and
7 * send "READY=1\n" to it.
8 * 3. Never throws — boot path must be safe even if the socket open fails.
9 */
10
11import { describe, expect, it } from "bun:test";
12import { notifySystemdReady } from "../lib/systemd-notify";
13
14describe("notifySystemdReady", () => {
15 it("is a no-op when NOTIFY_SOCKET is unset", async () => {
16 let opened = false;
17 const opener = async () => {
18 opened = true;
19 return {
20 send: () => undefined,
21 close: () => undefined,
22 };
23 };
24 await notifySystemdReady({ openDatagram: opener, env: {} });
25 expect(opened).toBe(false);
26 });
27
28 it("is a no-op when NOTIFY_SOCKET is empty string", async () => {
29 let opened = false;
30 const opener = async () => {
31 opened = true;
32 return {
33 send: () => undefined,
34 close: () => undefined,
35 };
36 };
37 await notifySystemdReady({
38 openDatagram: opener,
39 env: { NOTIFY_SOCKET: "" },
40 });
41 expect(opened).toBe(false);
42 });
43
44 it("opens a datagram socket and sends READY=1 when NOTIFY_SOCKET is set", async () => {
45 const path = "/run/systemd/notify-test";
46 const calls: Array<{
47 kind: string;
48 data?: string;
49 socketPath?: string;
50 }> = [];
51
52 const opener = async (socketPath: string) => {
53 calls.push({ kind: "open", socketPath });
54 return {
55 send(data: string | Uint8Array) {
56 const s = typeof data === "string" ? data : new TextDecoder().decode(data);
57 calls.push({ kind: "send", data: s });
58 },
59 close() {
60 calls.push({ kind: "close" });
61 },
62 };
63 };
64
65 await notifySystemdReady({
66 openDatagram: opener,
67 env: { NOTIFY_SOCKET: path },
68 });
69
70 expect(calls[0]).toEqual({ kind: "open", socketPath: path });
71 const sendCall = calls.find((c) => c.kind === "send");
72 expect(sendCall).toBeDefined();
73 expect(sendCall?.data).toBe("READY=1\n");
74 const closeCall = calls.find((c) => c.kind === "close");
75 expect(closeCall).toBeDefined();
76 });
77
78 it("never throws when the socket open fails", async () => {
79 const opener = async () => {
80 throw new Error("ENOENT: socket path missing");
81 };
82 // Test that this resolves without throwing.
83 await expect(
84 notifySystemdReady({
85 openDatagram: opener,
86 env: { NOTIFY_SOCKET: "/run/systemd/notify" },
87 })
88 ).resolves.toBeUndefined();
89 });
90
91 it("never throws when send() fails", async () => {
92 const opener = async () => ({
93 send() {
94 throw new Error("EPIPE");
95 },
96 close() {
97 /* clean close */
98 },
99 });
100 await expect(
101 notifySystemdReady({
102 openDatagram: opener,
103 env: { NOTIFY_SOCKET: "/run/systemd/notify" },
104 })
105 ).resolves.toBeUndefined();
106 });
107
108 it("never throws when close() fails", async () => {
109 const opener = async () => ({
110 send() {
111 /* ok */
112 },
113 close() {
114 throw new Error("EBADF");
115 },
116 });
117 await expect(
118 notifySystemdReady({
119 openDatagram: opener,
120 env: { NOTIFY_SOCKET: "/run/systemd/notify" },
121 })
122 ).resolves.toBeUndefined();
123 });
124
125 it("defaults to process.env when env is not provided", async () => {
126 const original = process.env.NOTIFY_SOCKET;
127 delete process.env.NOTIFY_SOCKET;
128 try {
129 let opened = false;
130 const opener = async () => {
131 opened = true;
132 return {
133 send: () => undefined,
134 close: () => undefined,
135 };
136 };
137 await notifySystemdReady({ openDatagram: opener });
138 expect(opened).toBe(false);
139 } finally {
140 if (original !== undefined) process.env.NOTIFY_SOCKET = original;
141 }
142 });
143});