blob: a67bcd82def4ecaef89c1191ce853eb59ce473a9 [file] [log] [blame]
David Browne2acfae2020-01-21 16:45:01 -07001// Copyright (c) 2019 Linaro LTD
2//
3// SPDX-License-Identifier: Apache-2.0
4
David Brownc3898d62019-08-05 14:20:02 -06005//! Support and tests related to the dependency management for multi-image
6//! support.
7
8use crate::image::ImageVersion;
9
10pub trait Depender {
11 /// Generate a version for this particular image. The slot indicates
12 /// which slot this is being put in.
13 fn my_version(&self, offset: usize, slot: usize) -> ImageVersion;
14
15 /// Return dependencies for this image/slot combination.
16 fn my_deps(&self, offset: usize, slot: usize) -> Vec<ImageVersion>;
17
18 /// Return the image ID of the other version.
19 fn other_id(&self) -> u8;
20}
21
22/// A boring image is used when we aren't testing dependencies. There will
23/// be meaningful version numbers. The size field is the image number we
24/// are.
David Brown2ee5f7f2020-01-13 14:04:01 -070025pub struct BoringDep {
26 number: usize,
27 test: DepTest,
28}
29
30impl BoringDep {
31 pub fn new(number: usize, test: &DepTest) -> BoringDep {
32 BoringDep {
David Brown4dfb33c2021-03-10 05:15:45 -070033 number,
David Brown2ee5f7f2020-01-13 14:04:01 -070034 test: test.clone(),
35 }
36 }
37}
David Brownc3898d62019-08-05 14:20:02 -060038
39impl Depender for BoringDep {
40 fn my_version(&self, _offset: usize, slot: usize) -> ImageVersion {
David Brown2ee5f7f2020-01-13 14:04:01 -070041 let slot = if self.test.downgrade {
42 1 - slot
43 } else {
44 slot
45 };
46 ImageVersion::new_synthetic(self.number as u8, slot as u8, 0)
David Brownc3898d62019-08-05 14:20:02 -060047 }
48
49 fn my_deps(&self, _offset: usize, _slot: usize) -> Vec<ImageVersion> {
50 vec![]
51 }
52
53 fn other_id(&self) -> u8 {
54 0
55 }
56}
57
58/// An individual test of the dependency mechanism describes one of the
59/// possibilities for the dependency information for each image, and what
60/// the expected outcome is.
61#[derive(Clone, Debug)]
62pub struct DepTest {
63 /// What kinds of dependency should be installed in the image.
64 pub depends: [DepType; 2],
65
66 /// What is the expected outcome of the upgrade.
67 pub upgrades: [UpgradeInfo; 2],
David Brown2ee5f7f2020-01-13 14:04:01 -070068
69 /// Should this be considered a downgrade (cause the version number to
70 /// decrease).
71 pub downgrade: bool,
David Brownc3898d62019-08-05 14:20:02 -060072}
73
74/// Describes the various types of dependency information that can be
75/// provided.
76#[derive(Clone, Debug)]
77pub enum DepType {
78 /// Do not include dependency information
79 Nothing,
80 /// Provide dependency information that matches the other image.
81 Correct,
David Brown873be312019-09-03 12:22:32 -060082 /// Provide a dependency that matches the old version of the other
83 /// image.
84 OldCorrect,
David Brownc3898d62019-08-05 14:20:02 -060085 /// Provide dependency information describing something newer than the
86 /// other image.
87 Newer,
David Brown873be312019-09-03 12:22:32 -060088 /// Don't provide an upgrade image at all for this image
89 NoUpgrade,
David Brownc3898d62019-08-05 14:20:02 -060090}
91
92/// Describes what our expectation is for an upgrade.
David Brown207c4572019-09-03 12:21:05 -060093#[derive(Clone, Debug, PartialEq, Eq)]
David Brownc3898d62019-08-05 14:20:02 -060094pub enum UpgradeInfo {
95 /// The current version should be held.
96 Held,
97 /// The image should be upgraded
98 Upgraded,
99}
100
101/// A "test" that gives no dependency information.
102pub static NO_DEPS: DepTest = DepTest {
103 depends: [DepType::Nothing, DepType::Nothing],
104 upgrades: [UpgradeInfo::Upgraded, UpgradeInfo::Upgraded],
David Brown2ee5f7f2020-01-13 14:04:01 -0700105 downgrade: false,
106};
107
108/// A "test" with no dependency information, and the images marked as a
109/// downgrade.
110pub static REV_DEPS: DepTest = DepTest {
111 depends: [DepType::Nothing, DepType::Nothing],
112 upgrades: [UpgradeInfo::Held, UpgradeInfo::Held],
113 downgrade: true,
David Brownc3898d62019-08-05 14:20:02 -0600114};
115
116/// A PairDep describes the dependencies between two pairs.
117pub struct PairDep {
118 /// The image number of this image.
119 number: usize,
120
121 test: DepTest,
122}
123
124impl PairDep {
125 pub fn new(total_image: usize, my_image: usize, deps: &DepTest) -> PairDep {
126 if total_image != 2 {
127 panic!("PairDep only works when there are two images");
128 }
129
130 PairDep {
131 number: my_image,
132 test: deps.clone(),
133 }
134 }
135}
136
137impl Depender for PairDep {
138 fn my_version(&self, _offset: usize, slot: usize) -> ImageVersion {
David Brown2ee5f7f2020-01-13 14:04:01 -0700139 let slot = if self.test.downgrade {
140 1 - slot
141 } else {
142 slot
143 };
David Brownc3898d62019-08-05 14:20:02 -0600144 ImageVersion::new_synthetic(self.number as u8, slot as u8, 0)
145 }
146
147 fn my_deps(&self, _offset: usize, slot: usize) -> Vec<ImageVersion> {
David Brown873be312019-09-03 12:22:32 -0600148 // For now, don't put any dependencies in slot zero. They could be
149 // added here if we someday implement checking these.
150 if slot == 0 {
151 vec![]
152 } else {
153 match self.test.depends[self.number] {
154 DepType::Nothing => vec![],
155 DepType::NoUpgrade => panic!("Shouldn't get to this point"),
156 DepType::Correct => vec![
157 ImageVersion::new_synthetic(self.other_id(), slot as u8, 0)
158 ],
159 DepType::OldCorrect => vec![
160 ImageVersion::new_synthetic(self.other_id(), 0, 0)
161 ],
162 DepType::Newer => vec![
163 ImageVersion::new_synthetic(self.other_id(), slot as u8, 1)
164 ],
165 }
David Brownc3898d62019-08-05 14:20:02 -0600166 }
167 }
168
169 fn other_id(&self) -> u8 {
170 (1 - self.number) as u8
171 }
172}
173
174impl ImageVersion {
175 /// Generate an image version based on some key information. The image
176 /// number influences the major version number (by an arbitrary factor),
177 /// and the slot affects the major number on the build_number. The minor
178 /// number can also be given to force numbers to be different.
179 fn new_synthetic(image_id: u8, slot: u8, minor: u8) -> ImageVersion {
180 ImageVersion {
181 major: image_id * 20 + slot,
David Brown4dfb33c2021-03-10 05:15:45 -0700182 minor,
David Brownc3898d62019-08-05 14:20:02 -0600183 revision: 1,
184 build_num: slot as u32,
185 }
186 }
187}