From f9498eb7795cb1f33a6a0be6c2348d3c58eb49b9 Mon Sep 17 00:00:00 2001 From: Henrik Skupin Date: Mon, 30 Jan 2017 17:05:27 +0100 Subject: [PATCH] Bug 1333803 - Revert setting of the update channel to modifying channel-prefs.js. r=maja_zf As it has been turned out setting the desired update channel via a preference on the default branch does not work. Instead it really has to be set in the channel-prefs.js file. If not done so, the updater will see the new channel as invalid and abort the update process. MozReview-Commit-ID: 6NqYaijAcsX --HG-- extra : rebase_source : 31f3da79c960ca68b715df4b7cf70e4d486a2281 --- .../harness/firefox_ui_harness/testcases.py | 24 ++++++++---- .../tests/puppeteer/test_software_update.py | 37 +++++++++++++++---- .../firefox_puppeteer/api/software_update.py | 35 +++++++++++++++++- 3 files changed, 79 insertions(+), 17 deletions(-) diff --git a/testing/firefox-ui/harness/firefox_ui_harness/testcases.py b/testing/firefox-ui/harness/firefox_ui_harness/testcases.py index 77aa85f5c2cd..36e6b1b72de2 100644 --- a/testing/firefox-ui/harness/firefox_ui_harness/testcases.py +++ b/testing/firefox-ui/harness/firefox_ui_harness/testcases.py @@ -52,10 +52,26 @@ class UpdateTestCase(PuppeteerMixin, MarionetteTestCase): self.software_update = SoftwareUpdate(self.marionette) + # If a custom update channel has to be set, force a restart of + # Firefox to actually get it applied as a default pref. Use the clean + # option to force a non in_app restart, which would allow Firefox to + # dump the logs to the console. + if self.update_channel: + self.software_update.update_channel = self.update_channel + self.restart(clean=True) + + self.assertEqual(self.software_update.update_channel, self.update_channel) + # If requested modify the list of allowed MAR channels if self.update_mar_channels: self.software_update.mar_channels.add_channels(self.update_mar_channels) + self.assertTrue(self.update_mar_channels.issubset( + self.software_update.mar_channels.channels), + 'Allowed MAR channels have been set: expected "{}" in "{}"'.format( + ', '.join(self.update_mar_channels), + ', '.join(self.software_update.mar_channels.channels))) + # Ensure that there exists no already partially downloaded update self.remove_downloaded_update() @@ -70,12 +86,6 @@ class UpdateTestCase(PuppeteerMixin, MarionetteTestCase): 'success': False, }] - self.assertTrue(self.update_mar_channels.issubset( - self.software_update.mar_channels.channels), - 'Allowed MAR channels have been set: expected "{}" in "{}"'.format( - ', '.join(self.update_mar_channels), - ', '.join(self.software_update.mar_channels.channels))) - # Check if the user has permissions to run the update self.assertTrue(self.software_update.allowed, 'Current user has permissions to update the application.') @@ -349,8 +359,6 @@ class UpdateTestCase(PuppeteerMixin, MarionetteTestCase): def set_preferences_defaults(self): """Set the default value for specific preferences to force its usage.""" - if self.update_channel: - self.software_update.update_channel = self.update_channel if self.update_url: self.software_update.update_url = self.update_url diff --git a/testing/firefox-ui/tests/puppeteer/test_software_update.py b/testing/firefox-ui/tests/puppeteer/test_software_update.py index acb4a548ba70..04ca4a1f4a3e 100644 --- a/testing/firefox-ui/tests/puppeteer/test_software_update.py +++ b/testing/firefox-ui/tests/puppeteer/test_software_update.py @@ -17,14 +17,11 @@ class TestSoftwareUpdate(PuppeteerMixin, MarionetteTestCase): self.software_update = SoftwareUpdate(self.marionette) self.saved_mar_channels = self.software_update.mar_channels.channels - self.saved_update_channel = self.software_update.update_channel - self.software_update.mar_channels.channels = set(['expected', 'channels']) def tearDown(self): try: self.software_update.mar_channels.channels = self.saved_mar_channels - self.software_update.update_channel = self.saved_update_channel finally: super(TestSoftwareUpdate, self).tearDown() @@ -71,10 +68,36 @@ class TestSoftwareUpdate(PuppeteerMixin, MarionetteTestCase): def test_staging_directory(self): self.assertTrue(self.software_update.staging_directory) - def test_set_update_channel(self): - self.software_update.update_channel = 'new_channel' - self.assertEqual(self.marionette.get_pref('app.update.channel', default_branch=True), - 'new_channel') + +class TestUpdateChannel(PuppeteerMixin, MarionetteTestCase): + + def setUp(self): + super(TestUpdateChannel, self).setUp() + + self.software_update = SoftwareUpdate(self.marionette) + + self.saved_channel = self.software_update.update_channel + self.software_update.update_channel = 'expected_channel' + + def tearDown(self): + try: + self.software_update.update_channel = self.saved_channel + finally: + super(TestUpdateChannel, self).tearDown() + + def test_update_channel_default_channel(self): + # Without a restart the update channel will not change. + self.assertEqual(self.software_update.update_channel, self.saved_channel) + + def test_update_channel_set_channel(self): + try: + # Use the clean option to force a non in_app restart, which would allow + # Firefox to dump the logs to the console. + self.restart(clean=True) + self.assertEqual(self.software_update.update_channel, 'expected_channel') + finally: + self.software_update.update_channel = self.saved_channel + self.restart(clean=True) class TestMARChannels(PuppeteerMixin, MarionetteTestCase): diff --git a/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/software_update.py b/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/software_update.py index 0e19a9ae9ee9..09df04fbb68b 100644 --- a/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/software_update.py +++ b/testing/marionette/puppeteer/firefox/firefox_puppeteer/api/software_update.py @@ -4,6 +4,7 @@ import ConfigParser import os +import re import mozinfo @@ -324,8 +325,8 @@ class SoftwareUpdate(BaseLib): :param channel: New update channel to use """ - self.marionette.set_pref(self.PREF_APP_UPDATE_CHANNEL, channel, - default_branch=True) + writer = UpdateChannelWriter(self.marionette) + writer.set_channel(channel) @property def update_url(self): @@ -389,3 +390,33 @@ class SoftwareUpdate(BaseLib): url += 'force=1' return url + + +class UpdateChannelWriter(BaseLib): + """Class to handle the update channel as listed in channel-prefs.js""" + REGEX_UPDATE_CHANNEL = re.compile(r'("app\.update\.channel", ")([^"].*)(?=")') + + def __init__(self, *args, **kwargs): + BaseLib.__init__(self, *args, **kwargs) + + self.file_path = self.marionette.execute_script(""" + Components.utils.import('resource://gre/modules/Services.jsm'); + + let file = Services.dirsvc.get('PrfDef', Components.interfaces.nsIFile); + file.append('channel-prefs.js'); + + return file.path; + """) + + def set_channel(self, channel): + """Set default update channel. + + :param channel: New default update channel + """ + with open(self.file_path) as f: + file_contents = f.read() + + new_content = re.sub( + self.REGEX_UPDATE_CHANNEL, r'\g<1>' + channel, file_contents) + with open(self.file_path, 'w') as f: + f.write(new_content)