Skip to content

Commit

Permalink
Add helper for testing version comparison based update logic
Browse files Browse the repository at this point in the history
  • Loading branch information
yfyf committed Sep 3, 2024
1 parent fa0b3d9 commit 3ff1c43
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 137 deletions.
4 changes: 2 additions & 2 deletions controller/tests/mock_rauc.ml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class mock = object (self)
| Slot.SystemA -> state.rauc_status.a
| Slot.SystemB -> state.rauc_status.b

method set_primary slot = state.primary_slot <- Some slot
method set_primary some_slot = state.primary_slot <- some_slot
method get_primary () = state.primary_slot |> Lwt.return

method set_booted_slot slot = state.booted_slot <- slot
Expand Down Expand Up @@ -65,7 +65,7 @@ class mock = object (self)
(* Note: UpdateService or RAUC bindings do not explicitly set the
primary, but it is part of RAUC's install process, so we simulate it
here too. *)
let () = self#set_primary other_slot in
let () = self#set_primary (Some other_slot) in
Lwt.return ()

method mark_good _ = failwith "Not implemented"
Expand Down
40 changes: 40 additions & 0 deletions controller/tests/update_test_helpers.ml
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,43 @@ let run_test_case scenario_gen =
let test_context = setup_test_deps () in
let (scenario, init_state) = scenario_gen test_context in
run_test_scenario test_context (Queue.of_seq (List.to_seq scenario)) init_state


let other_slot slot = match slot with
| Rauc.Slot.SystemA -> Rauc.Slot.SystemB
| Rauc.Slot.SystemB -> Rauc.Slot.SystemA


let semver_v1 = Semver.of_string "1.0.0" |> Option.get
let semver_v2 = Semver.of_string "2.0.0" |> Option.get
let semver_v3 = Semver.of_string "3.0.0" |> Option.get

let test_version_logic_case
?(booted_slot=Rauc.Slot.SystemA)
?(primary_slot=(Some Rauc.Slot.SystemA))
~(input_versions:Update.version_info)
(expected_state:Update.state) =

let init_state = GettingVersionInfo in

let booted_version = Semver.to_string input_versions.booted in
let secondary_version = Semver.to_string input_versions.inactive in
let upstream_version = Semver.to_string input_versions.latest in

let inactive_slot = other_slot booted_slot in

fun {update_client; rauc} ->
let expected_state_sequence =
[
UpdateMock (fun () ->
rauc#set_version booted_slot booted_version;
rauc#set_version inactive_slot secondary_version;
rauc#set_booted_slot booted_slot;
rauc#set_primary primary_slot;
update_client#set_latest_version upstream_version
);
StateReached GettingVersionInfo;
StateReached expected_state;
]
in
(expected_state_sequence, init_state)
186 changes: 51 additions & 135 deletions controller/tests/update_tests.ml
Original file line number Diff line number Diff line change
Expand Up @@ -44,154 +44,70 @@ let both_out_of_date {update_client; rauc} =
in
(expected_state_sequence, init_state)

let both_newer_than_upstream {update_client; rauc} =
let init_state = GettingVersionInfo in

(* both slots have a newer version than fetched from update *)
let installed_version = "10.0.0" in
let upstream_version = "9.0.0" in

let expected_state_sequence =
[
UpdateMock (fun () ->
rauc#set_version SystemA installed_version;
rauc#set_version SystemB installed_version;
rauc#set_primary SystemA;
update_client#set_latest_version upstream_version
);
StateReached GettingVersionInfo;
(* TODO: is this really a non-sensical scenario? *)
StateReached
(ErrorGettingVersionInfo "nonsensical version information: <..>");
StateReached GettingVersionInfo;
]
let both_newer_than_upstream =
let input_versions = {
booted = semver_v3;
inactive = semver_v2;
latest = semver_v1;
} in
let expected_state =
ErrorGettingVersionInfo "nonsensical version information: <..>"
in
(expected_state_sequence, init_state)

let booted_newer_secondary_older {update_client; rauc} =
let init_state = GettingVersionInfo in

let booted_version = "10.0.0" in
let secondary_version = "8.0.0" in
let upstream_version = "9.0.0" in
test_version_logic_case ~input_versions expected_state

let expected_state_sequence =
[
UpdateMock (fun () ->
rauc#set_version SystemA booted_version;
rauc#set_version SystemB secondary_version;
rauc#set_booted_slot SystemA;
rauc#set_primary SystemA;
update_client#set_latest_version upstream_version
);
StateReached GettingVersionInfo;
StateReached (Downloading upstream_version);
]
let booted_newer_secondary_older =
let input_versions = {
latest = semver_v2;
booted = semver_v3;
inactive = semver_v1;
} in
let expected_state =
Downloading (Semver.to_string semver_v2)
in
(expected_state_sequence, init_state)


let booted_older_secondary_newer {update_client; rauc} =
let init_state = GettingVersionInfo in

let booted_version = "8.0.0" in
let secondary_version = "10.0.0" in
let upstream_version = "9.0.0" in
test_version_logic_case ~input_versions expected_state

let expected_state_sequence =
[
UpdateMock (fun () ->
rauc#set_version SystemA booted_version;
rauc#set_version SystemB secondary_version;
rauc#set_booted_slot SystemA;
rauc#set_primary SystemA;
update_client#set_latest_version upstream_version
);
StateReached GettingVersionInfo;
StateReached
(ErrorGettingVersionInfo "nonsensical version information: <..>");
]
let booted_older_secondary_newer =
let input_versions = {
latest = semver_v2;
booted = semver_v1;
inactive = semver_v3;
} in
let expected_state =
ErrorGettingVersionInfo "nonsensical version information: <..>"
in
(expected_state_sequence, init_state)
test_version_logic_case ~input_versions expected_state

let booted_current_secondary_current {update_client; rauc} =
let init_state = GettingVersionInfo in

let upstream_version = "9.0.0" in
let booted_version = upstream_version in
let secondary_version = upstream_version in

let expected_version_info = {
latest = Semver.of_string upstream_version |> Option.get;
booted = Semver.of_string booted_version |> Option.get;
inactive = Semver.of_string secondary_version |> Option.get;
let booted_current_secondary_current =
let input_versions = {
latest = semver_v2;
booted = semver_v2;
inactive = semver_v2;
} in

let expected_state_sequence =
[
UpdateMock (fun () ->
rauc#set_version SystemA booted_version;
rauc#set_version SystemB secondary_version;
rauc#set_booted_slot SystemA;
rauc#set_primary SystemA;
update_client#set_latest_version upstream_version
);
StateReached GettingVersionInfo;
StateReached (UpToDate expected_version_info);
]
let expected_state =
UpToDate input_versions
in
(expected_state_sequence, init_state)

let booted_current_secondary_older {update_client; rauc} =
let init_state = GettingVersionInfo in
test_version_logic_case ~input_versions expected_state

let upstream_version = "9.0.0" in
let booted_version = upstream_version in
let secondary_version = "8.0.0" in

let expected_version_info = {
latest = Semver.of_string upstream_version |> Option.get;
booted = Semver.of_string booted_version |> Option.get;
inactive = Semver.of_string secondary_version |> Option.get;
let booted_current_secondary_older =
let input_versions = {
latest = semver_v2;
booted = semver_v2;
inactive = semver_v1;
} in

let expected_state_sequence =
[
UpdateMock (fun () ->
rauc#set_version SystemA booted_version;
rauc#set_version SystemB secondary_version;
rauc#set_booted_slot SystemA;
rauc#set_primary SystemA;
update_client#set_latest_version upstream_version
);
StateReached GettingVersionInfo;
StateReached (UpToDate expected_version_info);
]
let expected_state =
UpToDate input_versions
in
(expected_state_sequence, init_state)


let booted_older_secondary_current {update_client; rauc} =
let init_state = GettingVersionInfo in

let upstream_version = "9.0.0" in
let booted_version = "8.0.0" in
let secondary_version = upstream_version in
test_version_logic_case ~input_versions expected_state

let expected_state_sequence =
[
UpdateMock (fun () ->
rauc#set_version SystemA booted_version;
rauc#set_version SystemB secondary_version;
rauc#set_booted_slot SystemA;
rauc#set_primary SystemA;
update_client#set_latest_version upstream_version
);
StateReached GettingVersionInfo;
StateReached OutOfDateVersionSelected;
]
let booted_older_secondary_current =
let input_versions = {
latest = semver_v2;
booted = semver_v1;
inactive = semver_v2;
} in
let expected_state = OutOfDateVersionSelected
in
(expected_state_sequence, init_state)
test_version_logic_case ~input_versions expected_state

let setup_log () =
Fmt_tty.setup_std_outputs ();
Expand Down

0 comments on commit 3ff1c43

Please sign in to comment.