blob: d1ea8a1e34befc272eb85f3104e09d4a96967938 [file] [log] [blame]
David Brownc3898d62019-08-05 14:20:02 -06001//! Support and tests related to the dependency management for multi-image
2//! support.
3
4use crate::image::ImageVersion;
5
6pub trait Depender {
7 /// Generate a version for this particular image. The slot indicates
8 /// which slot this is being put in.
9 fn my_version(&self, offset: usize, slot: usize) -> ImageVersion;
10
11 /// Return dependencies for this image/slot combination.
12 fn my_deps(&self, offset: usize, slot: usize) -> Vec<ImageVersion>;
13
14 /// Return the image ID of the other version.
15 fn other_id(&self) -> u8;
16}
17
18/// A boring image is used when we aren't testing dependencies. There will
19/// be meaningful version numbers. The size field is the image number we
20/// are.
21pub struct BoringDep(pub usize);
22
23impl Depender for BoringDep {
24 fn my_version(&self, _offset: usize, slot: usize) -> ImageVersion {
25 ImageVersion::new_synthetic(self.0 as u8, slot as u8, 0)
26 }
27
28 fn my_deps(&self, _offset: usize, _slot: usize) -> Vec<ImageVersion> {
29 vec![]
30 }
31
32 fn other_id(&self) -> u8 {
33 0
34 }
35}
36
37/// An individual test of the dependency mechanism describes one of the
38/// possibilities for the dependency information for each image, and what
39/// the expected outcome is.
40#[derive(Clone, Debug)]
41pub struct DepTest {
42 /// What kinds of dependency should be installed in the image.
43 pub depends: [DepType; 2],
44
45 /// What is the expected outcome of the upgrade.
46 pub upgrades: [UpgradeInfo; 2],
47}
48
49/// Describes the various types of dependency information that can be
50/// provided.
51#[derive(Clone, Debug)]
52pub enum DepType {
53 /// Do not include dependency information
54 Nothing,
55 /// Provide dependency information that matches the other image.
56 Correct,
57 /// Provide dependency information describing something newer than the
58 /// other image.
59 Newer,
60}
61
62/// Describes what our expectation is for an upgrade.
David Brown207c4572019-09-03 12:21:05 -060063#[derive(Clone, Debug, PartialEq, Eq)]
David Brownc3898d62019-08-05 14:20:02 -060064pub enum UpgradeInfo {
65 /// The current version should be held.
66 Held,
67 /// The image should be upgraded
68 Upgraded,
69}
70
71/// A "test" that gives no dependency information.
72pub static NO_DEPS: DepTest = DepTest {
73 depends: [DepType::Nothing, DepType::Nothing],
74 upgrades: [UpgradeInfo::Upgraded, UpgradeInfo::Upgraded],
75};
76
77/// A PairDep describes the dependencies between two pairs.
78pub struct PairDep {
79 /// The image number of this image.
80 number: usize,
81
82 test: DepTest,
83}
84
85impl PairDep {
86 pub fn new(total_image: usize, my_image: usize, deps: &DepTest) -> PairDep {
87 if total_image != 2 {
88 panic!("PairDep only works when there are two images");
89 }
90
91 PairDep {
92 number: my_image,
93 test: deps.clone(),
94 }
95 }
96}
97
98impl Depender for PairDep {
99 fn my_version(&self, _offset: usize, slot: usize) -> ImageVersion {
100 ImageVersion::new_synthetic(self.number as u8, slot as u8, 0)
101 }
102
103 fn my_deps(&self, _offset: usize, slot: usize) -> Vec<ImageVersion> {
David Brown17909882019-09-03 11:36:06 -0600104 match self.test.depends[self.number] {
David Brownc3898d62019-08-05 14:20:02 -0600105 DepType::Nothing => vec![],
106 DepType::Correct => vec![
107 ImageVersion::new_synthetic(self.other_id(), slot as u8, 0)
108 ],
109 DepType::Newer => vec![
110 ImageVersion::new_synthetic(self.other_id(), slot as u8, 1)
111 ],
112 }
113 }
114
115 fn other_id(&self) -> u8 {
116 (1 - self.number) as u8
117 }
118}
119
120impl ImageVersion {
121 /// Generate an image version based on some key information. The image
122 /// number influences the major version number (by an arbitrary factor),
123 /// and the slot affects the major number on the build_number. The minor
124 /// number can also be given to force numbers to be different.
125 fn new_synthetic(image_id: u8, slot: u8, minor: u8) -> ImageVersion {
126 ImageVersion {
127 major: image_id * 20 + slot,
128 minor: minor,
129 revision: 1,
130 build_num: slot as u32,
131 }
132 }
133}