Skip to content

Commit e3f50a5

Browse files
committed
Add deeper VM integration coverage
1 parent 5cd4b26 commit e3f50a5

1 file changed

Lines changed: 89 additions & 0 deletions

File tree

test/systemd/manager_integration_test.exs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,69 @@ defmodule Systemd.ManagerIntegrationTest do
9797
end
9898
end
9999

100+
test "links, starts, reads, stops, and disables a runtime unit file" do
101+
assert {:ok, conn} = Manager.connect()
102+
103+
name = "systemd-elixir-linked-test-#{System.unique_integer([:positive])}.service"
104+
path = Path.join(System.tmp_dir!(), name)
105+
106+
File.write!(
107+
path,
108+
"[Unit]\nDescription=systemdkit linked integration test\n[Service]\nType=oneshot\nExecStart=/bin/true\nRemainAfterExit=yes\n"
109+
)
110+
111+
try do
112+
case Manager.link_unit_files(conn, [path], runtime: true, force: true) do
113+
{:ok, %UnitFileOperation{}} ->
114+
assert :ok = Manager.reload(conn)
115+
assert {:ok, state} = Manager.unit_file_state(conn, name)
116+
assert state in ["linked", "linked-runtime", "static", "disabled"]
117+
118+
assert {:ok, job} = Manager.start_unit(conn, name)
119+
assert :ok = Job.await(conn, job, timeout: 5_000)
120+
assert {:ok, unit} = Manager.get_unit(conn, name)
121+
assert {:ok, unit_state} = UnitObject.state(conn, unit)
122+
assert unit_state.active_state in ["active", "activating"]
123+
124+
assert :ok = Manager.stop_unit(conn, name) |> await_or_ok(conn)
125+
assert_operation_or_permission(Manager.disable_unit_files(conn, [name], runtime: true))
126+
127+
{:error, %Error{} = error} ->
128+
assert Error.permission?(error)
129+
end
130+
after
131+
File.rm(path)
132+
end
133+
end
134+
135+
test "starts, restarts, kills, and resets a long-running transient unit" do
136+
assert {:ok, conn} = Manager.connect()
137+
138+
name = "systemd-elixir-lifecycle-test-#{System.unique_integer([:positive])}.service"
139+
140+
properties = [
141+
TransientUnit.string("Description", "systemd Elixir lifecycle integration test"),
142+
TransientUnit.string("Type", "simple"),
143+
TransientUnit.exec_start("/bin/sleep", ["/bin/sleep", "60"])
144+
]
145+
146+
case Manager.start_transient_unit(conn, name, properties) do
147+
{:ok, %Job{} = job} ->
148+
assert :ok = Job.await_signal(conn, job, timeout: 5_000)
149+
assert {:ok, unit} = Manager.get_unit(conn, name)
150+
assert {:ok, state} = UnitObject.state(conn, unit)
151+
assert state.active_state == "active"
152+
153+
assert :ok = Manager.try_restart_unit(conn, name) |> await_or_ok(conn)
154+
assert :ok = Manager.kill_unit(conn, name, "main", 15)
155+
assert :ok = eventually_inactive(conn, unit, 5_000)
156+
assert :ok = Manager.reset_failed_unit(conn, name)
157+
158+
{:error, %Error{} = error} ->
159+
assert Error.permission?(error)
160+
end
161+
end
162+
100163
test "starts a transient unit with resource controls" do
101164
assert {:ok, conn} = Manager.connect()
102165

@@ -170,6 +233,32 @@ defmodule Systemd.ManagerIntegrationTest do
170233
end
171234
end
172235

236+
defp eventually_inactive(conn, unit, timeout) do
237+
deadline = System.monotonic_time(:millisecond) + timeout
238+
do_eventually_inactive(conn, unit, deadline)
239+
end
240+
241+
defp do_eventually_inactive(conn, unit, deadline) do
242+
case UnitObject.state(conn, unit) do
243+
{:ok, %{active_state: state}} when state in ["inactive", "failed"] ->
244+
:ok
245+
246+
{:ok, _state} ->
247+
if System.monotonic_time(:millisecond) >= deadline do
248+
{:error, :timeout}
249+
else
250+
Process.sleep(100)
251+
do_eventually_inactive(conn, unit, deadline)
252+
end
253+
254+
{:error, %Error{reason: reason}} when reason in [:unknown_object, :not_found] ->
255+
:ok
256+
257+
{:error, error} ->
258+
{:error, error}
259+
end
260+
end
261+
173262
defp service_property(conn, unit, property) do
174263
Properties.get(conn, unit.object_path, "org.freedesktop.systemd1.Service", property)
175264
end

0 commit comments

Comments
 (0)