-
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
The main change is to split them into modules to let `async: true` do something. The second change is to use Erlang's process mailbox and selective receive feature to fix message race and simplify code.
- Loading branch information
Showing
11 changed files
with
398 additions
and
363 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
defmodule BasicTest do | ||
use ExUnit.Case, async: true | ||
|
||
import HeartTestCommon | ||
|
||
setup do | ||
common_setup() | ||
end | ||
|
||
test "heart acks on start and exits on shutdown", context do | ||
heart = start_supervised!({Heart, context.init_args}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
graceful_shutdown(heart) | ||
end | ||
|
||
test "heart pets watchdog when petted itself", context do | ||
heart = start_supervised!({Heart, context.init_args}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
Heart.pet(heart) | ||
assert_receive {:event, "pet(1)"} | ||
|
||
Heart.pet(heart) | ||
assert_receive {:event, "pet(1)"} | ||
|
||
graceful_shutdown(heart) | ||
end | ||
|
||
test "heart doesn't pet watchdog when not petted", context do | ||
# The default wdt_timeout is 120s and the VM timeout is 60s, so no | ||
# pet should happen. Wait for 6s to detect whether the default pet | ||
# timeout of 5 seconds was erroneously used. | ||
heart = start_supervised!({Heart, context.init_args}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
refute_receive _, 6000 | ||
|
||
graceful_shutdown(heart) | ||
end | ||
|
||
test "heart reboots when not petted", context do | ||
# Shortest timeout is 11 seconds | ||
start_supervised!({Heart, context.init_args ++ [heart_beat_timeout: 11]}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
Process.sleep(10000) | ||
refute_received _ | ||
|
||
assert_receive {:event, "sync()"}, 1500 | ||
assert_receive {:event, "reboot(0x01234567)"} | ||
assert_receive {:exit, 0} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
defmodule CrashDumpTest do | ||
use ExUnit.Case, async: true | ||
|
||
import HeartTestCommon | ||
|
||
setup do | ||
common_setup() | ||
end | ||
|
||
test "crash dump waits for notification", context do | ||
heart = start_supervised!({Heart, context.init_args ++ [crash_dump_seconds: 10]}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
Heart.preparing_crash(heart) | ||
|
||
# Capture the WDT pet that's sent before the crash | ||
assert_receive {:event, "pet(1)"} | ||
|
||
# Nothing should happen now | ||
refute_receive _, 500 | ||
|
||
# Any write to the socket will cause a reboot now. | ||
Heart.pet(heart) | ||
|
||
assert_receive {:event, "sync()"} | ||
assert_receive {:event, "reboot(0x01234567)"} | ||
assert_receive {:exit, 0} | ||
end | ||
|
||
test "crash dump crashes anyway after timeout", context do | ||
heart = start_supervised!({Heart, context.init_args ++ [crash_dump_seconds: 2]}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
Heart.preparing_crash(heart) | ||
|
||
# Capture the WDT pet that's sent before the crash | ||
assert_receive {:event, "pet(1)"} | ||
|
||
# Nothing should happen for most of the 2 seconds | ||
refute_receive _, 1900 | ||
|
||
# Timeout should trigger a crash in ~100 ms | ||
assert_receive {:event, "sync()"}, 200 | ||
assert_receive {:event, "reboot(0x01234567)"} | ||
assert_receive {:exit, 0} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
defmodule DisableHwTest do | ||
use ExUnit.Case, async: true | ||
|
||
import HeartTestCommon | ||
|
||
setup do | ||
common_setup() | ||
end | ||
|
||
test "sending disable_hw stops petting the hardware watchdog", context do | ||
heart = start_supervised!({Heart, context.init_args}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
{:ok, :heart_ack} = Heart.set_cmd(heart, "disable_hw") | ||
|
||
refute_receive _, 11000 | ||
|
||
# NOTE: even graceful shutdown doesn't do a final pet of the WDT | ||
Heart.shutdown(heart) | ||
assert_receive {:exit, 0} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
defmodule DisableVmTest do | ||
use ExUnit.Case, async: true | ||
|
||
import HeartTestCommon | ||
|
||
setup do | ||
common_setup() | ||
end | ||
|
||
test "sending disable_vm causes a heart timeout exit", context do | ||
heart = start_supervised!({Heart, context.init_args}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
{:ok, :heart_ack} = Heart.set_cmd(heart, "disable_vm") | ||
|
||
assert_receive {:event, "sync()"} | ||
assert_receive {:event, "reboot(0x01234567)"} | ||
assert_receive {:exit, 0} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
defmodule GuardedRebootTest do | ||
use ExUnit.Case, async: true | ||
|
||
import HeartTestCommon | ||
|
||
setup do | ||
common_setup() | ||
end | ||
|
||
test "guarded reboot", context do | ||
heart = start_supervised!({Heart, context.init_args}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
{:ok, :heart_ack} = Heart.set_cmd(heart, "guarded_reboot") | ||
|
||
# Final WDT pet | ||
assert_receive {:event, "pet(1)"} | ||
|
||
# Tell PID 1 to reboot | ||
assert_receive {:event, "kill(1, SIGTERM)"} | ||
|
||
# Proactive sync | ||
assert_receive {:event, "sync()"} | ||
|
||
Process.sleep(6) | ||
|
||
# Run normal shutdown and check that there aren't any more WDT pets | ||
Heart.shutdown(heart) | ||
assert_receive {:exit, 0} | ||
end | ||
|
||
test "guarded poweroff", context do | ||
heart = start_supervised!({Heart, context.init_args}) | ||
assert_receive {:heart, :heart_ack} | ||
assert_receive {:event, "open(/dev/watchdog0) succeeded"} | ||
assert_receive {:event, "pet(1)"} | ||
|
||
{:ok, :heart_ack} = Heart.set_cmd(heart, "guarded_poweroff") | ||
|
||
# Final WDT pet | ||
assert_receive {:event, "pet(1)"} | ||
|
||
# Tell PID 1 to reboot | ||
assert_receive {:event, "kill(1, SIGUSR1)"} | ||
|
||
# Proactive sync | ||
assert_receive {:event, "sync()"} | ||
|
||
Process.sleep(6) | ||
|
||
# Run normal shutdown and check that there aren't any more WDT pets | ||
Heart.shutdown(heart) | ||
assert_receive {:exit, 0} | ||
end | ||
end |
Oops, something went wrong.