Aktualizr
C++ SOTA Client
All Classes Namespaces Files Functions Variables Enumerations Enumerator Pages
test_update.py
1 #!/usr/bin/env python3
2 
3 import logging
4 import argparse
5 import time
6 
7 from os import getcwd, chdir
8 
9 from test_fixtures import KeyStore, with_aktualizr, with_uptane_backend, with_secondary, with_director, with_imagerepo,\
10  with_sysroot, with_treehub, TestRunner
11 
12 
13 logger = logging.getLogger(__file__)
14 
15 
16 """
17  Test update of Primary and Secondary if their package manager differs, `ostree`
18  and binary (`none` or `fake`) respectively
19 
20  Aktualizr/Primary's package manager is set to `ostree`
21  Secondary's package manager is set to `fake` which means a file/binary update
22  Primary goal is to verify whether aktualizr succeeds with a binary/fake update of secondary
23  while aktualizr/primary is configured with ostree package manager
24 """
25 @with_uptane_backend(start_generic_server=True)
26 @with_secondary(start=True)
27 @with_director()
28 @with_treehub()
29 @with_sysroot()
30 @with_aktualizr(start=False, run_mode='once', output_logs=True)
31 def test_primary_ostree_secondary_file_updates(uptane_repo, secondary, aktualizr, director, sysroot,
32  treehub, uptane_server, **kwargs):
33  target_rev = treehub.revision
34  # add an ostree update for Primary
35  uptane_repo.add_ostree_target(aktualizr.id, target_rev)
36  # add a fake/binary update for Secondary
37  secondary_update_hash = uptane_repo.add_image(secondary.id, "secondary-update.bin")
38 
39  with aktualizr:
40  aktualizr.wait_for_completion()
41 
42  # check the Primary update, must be in pending state since it requires reboot
43  pending_rev = aktualizr.get_primary_pending_version()
44  if pending_rev != target_rev:
45  logger.error("Pending version {} != the target version {}".format(pending_rev, target_rev))
46  return False
47 
48  # check the Secondary update
49  current_secondary_image_hash = aktualizr.get_current_image_info(secondary.id)
50  if current_secondary_image_hash != secondary_update_hash:
51  logger.error("Current secondary image {} != expected image {}".format(current_secondary_image_hash,
52  secondary_update_hash))
53  return False
54 
55  # emulate reboot and run aktualizr once more
56  sysroot.update_revision(pending_rev)
57  aktualizr.emulate_reboot()
58 
59  with aktualizr:
60  aktualizr.wait_for_completion()
61 
62  # check the Primary update after reboot
63  result = director.get_install_result() and (target_rev == aktualizr.get_current_primary_image_info())
64  return result
65 
66 
67 """
68  Test update of Secondary's ostree repo if an ostree target metadata are expired
69 
70  Metadata are valid at the moment of a new ostree revision installation,
71  but are expired after that and before Secondary is rebooted,
72  we still expect that the installed update is applied in this case
73 """
74 @with_treehub()
75 @with_uptane_backend()
76 @with_director()
77 @with_sysroot()
78 @with_secondary(start=False)
79 @with_aktualizr(start=False, run_mode='once', output_logs=True)
80 def test_secodary_ostree_update_if_metadata_expires(uptane_repo, secondary, aktualizr, treehub, sysroot, director, **kwargs):
81  target_rev = treehub.revision
82  expires_within_sec = 10
83 
84  uptane_repo.add_ostree_target(secondary.id, target_rev, expires_within_sec=expires_within_sec)
85  start_time = time.time()
86 
87  with secondary:
88  with aktualizr:
89  aktualizr.wait_for_completion()
90 
91  pending_rev = aktualizr.get_current_pending_image_info(secondary.id)
92 
93  if pending_rev != target_rev:
94  logger.error("Pending version {} != the target one {}".format(pending_rev, target_rev))
95  return False
96 
97  # wait until the target metadata are expired
98  time.sleep(max(0, expires_within_sec - (time.time() - start_time)))
99 
100  sysroot.update_revision(pending_rev)
101  secondary.emulate_reboot()
102 
103  with secondary:
104  with aktualizr:
105  aktualizr.wait_for_completion()
106 
107  if not director.get_install_result():
108  logger.error("Installation result is not successful")
109  return False
110 
111  installed_rev = aktualizr.get_current_image_info(secondary.id)
112 
113  if installed_rev != target_rev:
114  logger.error("Installed version {} != the target one {}".format(installed_rev, target_rev))
115  return False
116 
117  return True
118 
119 
120 """
121  Test update of Primary's ostree repo if an ostree target metadata are expired
122 
123  Metadata are valid at the moment of a new ostree revision installation,
124  but are expired after that and before Primary is rebooted,
125  we still expect that the installed update is applied in this case
126 """
127 @with_uptane_backend(start_generic_server=True)
128 @with_director()
129 @with_treehub()
130 @with_sysroot()
131 @with_aktualizr(start=False, run_mode='once', output_logs=True)
132 def test_primary_ostree_update_if_metadata_expires(uptane_repo, aktualizr, director, sysroot, treehub, uptane_server, **kwargs):
133  target_rev = treehub.revision
134  expires_within_sec = 10
135 
136  # add an ostree update for Primary
137  uptane_repo.add_ostree_target(aktualizr.id, target_rev, expires_within_sec=expires_within_sec)
138  start_time = time.time()
139 
140  with aktualizr:
141  aktualizr.wait_for_completion()
142 
143  # check the Primary update, must be in pending state since it requires reboot
144  pending_rev = aktualizr.get_primary_pending_version()
145  if pending_rev != target_rev:
146  logger.error("Pending version {} != the target version {}".format(pending_rev, target_rev))
147  return False
148 
149  # wait until the target metadata are expired
150  time.sleep(max(0, expires_within_sec - (time.time() - start_time)))
151 
152  # emulate reboot and run aktualizr once more
153  sysroot.update_revision(pending_rev)
154  aktualizr.emulate_reboot()
155 
156  with aktualizr:
157  aktualizr.wait_for_completion()
158 
159  # check the Primary update after reboot
160  result = director.get_install_result() and (target_rev == aktualizr.get_current_primary_image_info())
161  return result
162 
163 
164 if __name__ == "__main__":
165  logging.basicConfig(level=logging.INFO)
166 
167  parser = argparse.ArgumentParser(description='Test backend failure')
168  parser.add_argument('-b', '--build-dir', help='build directory', default='build')
169  parser.add_argument('-s', '--src-dir', help='source directory', default='.')
170 
171  input_params = parser.parse_args()
172 
173  KeyStore.base_dir = input_params.src_dir
174  initial_cwd = getcwd()
175  chdir(input_params.build_dir)
176 
177  test_suite = [
178  test_primary_ostree_secondary_file_updates,
179  test_secodary_ostree_update_if_metadata_expires,
180  test_primary_ostree_update_if_metadata_expires
181  ]
182 
183  test_suite_run_result = TestRunner(test_suite).run()
184 
185  chdir(initial_cwd)
186  exit(0 if test_suite_run_result else 1)