~ubuntu-branches/ubuntu/wily/system-image/wily

« back to all changes in this revision

Viewing changes to systemimage/tests/test_state.py

  • Committer: Package Import Robot
  • Author(s): Barry Warsaw
  • Date: 2013-09-06 18:34:29 UTC
  • mfrom: (1.2.12)
  • Revision ID: package-import@ubuntu.com-20130906183429-mwrrv52ooot0n3ut
Tags: 1.5-0ubuntu1
* New upstream release.
  - `system-image-cli --info` prints additional information:
     + last update time (i.e. the mtime of `/etc/system-image/channel.ini`
       falling back to the mtime of `/etc/ubuntu-build`).
     + version details for ubuntu, the device, and any custom version, if the
       `/etc/system-image/channel.ini` file contains these details.
  - `system-image-cli --dry-run -c <bad-channel>` no longer produces a
     traceback.  You get "Already up-to-date", but use `-v` for more info.
  - D-Bus API method `UpdateAvailableStatus` field `last_update_date`
    has changes its format.  It's still ISO 8601, but with a space
    instead of a 'T' separating the date from the time.
  - LP: #1221841 - Support the new channels.json file format with
    backward compatibility (for now) with the old format.
  - LP: #1215959 - New D-Bus .Info() method returns data similar to
    `system-image-cli --info`

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
    'TestPersistence',
24
24
    'TestRebooting',
25
25
    'TestState',
 
26
    'TestStateNewChannelsFormat',
26
27
    ]
27
28
 
28
29
 
38
39
from systemimage.state import State
39
40
from systemimage.testing.demo import DemoDevice
40
41
from systemimage.testing.helpers import (
41
 
    configuration, copy, get_index, make_http_server, setup_index,
42
 
    setup_keyring_txz, setup_keyrings, sign, temporary_directory)
 
42
    configuration, copy, data_path, get_index, make_http_server, setup_index,
 
43
    setup_keyring_txz, setup_keyrings, sign, temporary_directory, touch_build)
43
44
from unittest.mock import patch
44
45
 
45
46
 
93
94
        # signed correctly, new state transitions will be added to re-aquire a
94
95
        # new image signing key.
95
96
        state = State()
96
 
        next(state)
97
 
        next(state)
 
97
        state.run_thru('get_channel')
98
98
        # Where we would expect a channels object, there is none.
99
99
        self.assertIsNone(state.channels)
100
100
        # Just to prove that the image signing key is going to change, let's
110
110
        # valid channels object.
111
111
        sign(self._channels_path, 'image-signing.gpg')
112
112
        next(state)
113
 
        self.assertEqual(state.channels.stable.nexus7.index,
 
113
        self.assertEqual(state.channels.stable.devices.nexus7.index,
114
114
                         '/stable/nexus7/index.json')
115
115
 
116
116
    @configuration
130
130
        # signed correctly, new state transitions will be added to re-aquire a
131
131
        # new image signing key.
132
132
        state = State()
133
 
        next(state)
134
 
        next(state)
 
133
        state.run_thru('get_channel')
135
134
        # Where we would expect a channels object, there is none.
136
135
        self.assertIsNone(state.channels)
137
136
        # Just to prove that the image signing key is not going to change,
272
271
        self.assertFalse(os.path.exists(config.gpg.image_master))
273
272
        self.assertFalse(os.path.exists(config.gpg.image_signing))
274
273
        state = State()
275
 
        next(state)
276
 
        next(state)
 
274
        state.run_thru('get_channel')
277
275
        # Now the image master and signing keys exist.
278
276
        self.assertTrue(os.path.exists(config.gpg.image_master))
279
277
        self.assertTrue(os.path.exists(config.gpg.image_signing))
300
298
        # Run the state machine three times:
301
299
        # blacklist -(sig fail)-> get master -> blacklist (sig fail)
302
300
        state = State()
303
 
        next(state)
304
 
        next(state)
 
301
        state.run_thru('get_master_key')
305
302
        self.assertRaises(SignatureError, next, state)
306
303
 
307
304
 
454
451
        # machine to completion should not result in a reboot.
455
452
        self._setup_keyrings()
456
453
        # Hack the current build number so that no update is available.
457
 
        with open(config.system.build_file, 'w', encoding='utf-8') as fp:
458
 
            print(20250000, file=fp)
 
454
        touch_build(20250000)
459
455
        with patch('systemimage.reboot.Reboot.reboot') as mock:
460
456
            list(State())
461
457
        self.assertEqual(mock.call_count, 0)
536
532
        # A delta update's command file gets properly filled.
537
533
        self._setup_keyrings()
538
534
        # Set the current build number so a delta update will work.
539
 
        with open(config.system.build_file, 'w', encoding='utf-8') as fp:
540
 
            print(20120100, file=fp)
 
535
        touch_build(20120100)
541
536
        State().run_until('reboot')
542
537
        path = os.path.join(config.updater.cache_partition, 'ubuntu_command')
543
538
        with open(path, 'r', encoding='utf-8') as fp:
566
561
        # within the image by the 'order' key.
567
562
        self._setup_keyrings()
568
563
        # Set the current build number so a delta update will work.
569
 
        with open(config.system.build_file, 'w', encoding='utf-8') as fp:
570
 
            print(20120100, file=fp)
 
564
        touch_build(20120100)
571
565
        State().run_until('reboot')
572
566
        path = os.path.join(config.updater.cache_partition, 'ubuntu_command')
573
567
        with open(path, 'r', encoding='utf-8') as fp:
618
612
    def test_no_update_no_pickle_file(self):
619
613
        # If there's no update, there's no state file.
620
614
        self._setup_keyrings()
621
 
        with open(config.system.build_file, 'w', encoding='utf-8') as fp:
622
 
            print(20250000, file=fp)
 
615
        touch_build(20250000)
623
616
        self.assertFalse(os.path.exists(config.system.state_file))
624
617
        state = State()
625
618
        self.assertIsNone(state.winner)
696
689
    def test_filter_none(self):
697
690
        # With no filter, we get the unadulterated candidate paths.
698
691
        self._setup_keyrings()
699
 
        with open(config.system.build_file, 'w', encoding='utf-8') as fp:
700
 
            print(20120100, file=fp)
 
692
        touch_build(20120100)
701
693
        state = State()
702
694
        state.run_thru('calculate_winner')
703
695
        self.assertEqual(len(state.winner), 1)
707
699
        # The state machine can use a filter to come up with a different set
708
700
        # of candidate upgrade paths.  In this case, no candidates.
709
701
        self._setup_keyrings()
710
 
        with open(config.system.build_file, 'w', encoding='utf-8') as fp:
711
 
            print(20120100, file=fp)
 
702
        touch_build(20120100)
712
703
        def filter_out_everything(candidates):
713
704
            return []
714
705
        state = State(candidate_filter=filter_out_everything)
715
706
        state.run_thru('calculate_winner')
716
707
        self.assertEqual(len(state.winner), 0)
 
708
 
 
709
 
 
710
class TestStateNewChannelsFormat(_StateTestsBase):
 
711
    CHANNEL_FILE = 'channels_09.json'
 
712
    CHANNEL = 'saucy'
 
713
    DEVICE = 'manta'
 
714
    INDEX_FILE = 'index_21.json'
 
715
 
 
716
    @configuration
 
717
    def test_full_reboot(self, ini_file):
 
718
        # Test that state transitions through reboot work for the new channel
 
719
        # format.  Also check that the right files get moved into place.
 
720
        self._stack.enter_context(patch('systemimage.device.check_output',
 
721
                                        return_value='manta'))
 
722
        config.load(data_path('channel_04.ini'), override=True)
 
723
        self._setup_keyrings()
 
724
        state = State()
 
725
        state.run_until('reboot')
 
726
        path = os.path.join(config.updater.cache_partition, 'ubuntu_command')
 
727
        with open(path, 'r', encoding='utf-8') as fp:
 
728
            command = fp.read()
 
729
        self.assertMultiLineEqual(command, """\
 
730
load_keyring image-master.tar.xz image-master.tar.xz.asc
 
731
load_keyring image-signing.tar.xz image-signing.tar.xz.asc
 
732
load_keyring device-signing.tar.xz device-signing.tar.xz.asc
 
733
mount system
 
734
update 6.txt 6.txt.asc
 
735
update 7.txt 7.txt.asc
 
736
update 5.txt 5.txt.asc
 
737
unmount system
 
738
""")
 
739
        got_reboot = False
 
740
        def reboot_mock(self):
 
741
            nonlocal got_reboot
 
742
            got_reboot = True
 
743
        with patch('systemimage.reboot.Reboot.reboot', reboot_mock):
 
744
            list(state)
 
745
        self.assertTrue(got_reboot)