summaryrefslogtreecommitdiffstats
path: root/tests/src/lib/replicant_releases.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/src/lib/replicant_releases.py')
-rw-r--r--tests/src/lib/replicant_releases.py260
1 files changed, 260 insertions, 0 deletions
diff --git a/tests/src/lib/replicant_releases.py b/tests/src/lib/replicant_releases.py
new file mode 100644
index 0000000..3da6e47
--- /dev/null
+++ b/tests/src/lib/replicant_releases.py
@@ -0,0 +1,260 @@
+#!/usr/bin/env python3
+# Copyright (C) 2020 Denis 'GNUtoo' Carikli <GNUtoo@cyberdimension.org>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <https://www.gnu.org/licenses/>.
+import os
+import re
+import sh
+
+import lib.devices
+import lib.hosts
+
+from lib.common import get_output
+from lib.common import trace
+
+class ReplicantRelease(object):
+ def __init__(self, config, major_version, minor_version, host, device,
+ quiet=False):
+ self.config = config
+ self.quiet = quiet
+
+ self.major_version = major_version
+ self.minor_version = minor_version
+ self.host = host
+ self.device = device
+
+ @trace
+ def get_recovery_path(self):
+ path = ""
+ path += os.sep.join([
+ self.config['releases_directory'],
+ 'replicant' + '-' + self.major_version,
+ self.minor_version])
+ path += os.sep + 'images' + os.sep + str(self.device)
+ path += os.sep + 'recovery-{}.img'.format(self.device)
+ return path
+
+ @trace
+ def get_zip_path(self):
+ filename = 'replicant-{}-{}.zip'.format(self.major_version,
+ self.device)
+ if self.major_version == '6.0':
+ if self.minor_version > '0003':
+ filename = 'replicant-{}-{}-{}.zip'.format(self.major_version,
+ self.minor_version,
+ self.device)
+ path = ""
+ path += os.sep.join([
+ self.config['releases_directory'],
+ 'replicant' + '-' + self.major_version,
+ self.minor_version])
+ path += os.sep + 'images' + os.sep + str(self.device)
+ path += os.sep + filename
+ return path
+
+ @trace
+ def get_supported_targets(self):
+ if self.major_version != '6.0':
+ assert(False)
+
+ return ['espresso3g', 'espressowifi', 'i9100', 'i9300', 'i9305',
+ 'maguro', 'n5100', 'n5110', 'n7000', 'n7100']
+
+class RecoveryRuntime(object):
+ def __init__(self, config, host, device, release, quiet=False):
+ self.config = config
+ self.quiet = quiet
+ self.host = host
+ self.device = device
+ self.release = release
+
+ @trace
+ def get_partition(self, partition):
+ if not self.release.major_version == '6.0':
+ assert(False)
+
+ if str(self.device) in ['i9100', 'i9300', 'n7100', 'n5100']:
+ return '/dev/block/platform/dw_mmc/by-name/' + str(partition)
+ elif str(self.device) in ['maguro']:
+ return '/dev/block/platform/omap/omap_hsmmc.0/by-name/' \
+ + str(partition)
+ elif str(self.device) in ['p3100']:
+ return '/dev/block/platform/omap/omap_hsmmc.1/by-name/' \
+ + str(partition)
+ else:
+ # TODO:
+ # - i9305
+ # - n5110
+ # - n7000
+ # - p3110
+ # - p311
+ # - p5100
+ # - p5510
+ assert(False)
+
+ @trace
+ def get_boot_partition(self):
+ if self.release.major_version != '6.0':
+ # TODO
+ assert(False)
+
+ if str(self.device) in ['i9300', 'i9305', 'n7100']:
+ return self.get_partition('BOOT')
+ else:
+ # TODO:
+ # - i9100
+ # - maguro
+ # - n5110
+ # - n7000
+ # - p3100
+ # - p3110
+ # - p3113
+ # - p5100
+ # - p5100
+ # - p5510
+ assert(False)
+
+ @trace
+ def get_cache_partition(self):
+ if self.release.major_version != '6.0':
+ # TODO
+ assert(False)
+
+ if str(self.device) in ['maguro']:
+ return self.get_partition('cache')
+ elif str(self.device) in ['espresso3g', 'espressowifi', 'i9100',
+ 'i9300', 'i9305', 'n5100', 'n5110', 'n7000',
+ 'n7100']:
+ return self.get_partition('CACHE')
+ else:
+ # TODO:
+ # - p3110
+ # - p3113
+ # - p5100
+ # - p5510
+ assert(False)
+
+ @trace
+ def wait_for_ready(self):
+ self.host.run(['adb', 'wait-for-recovery'])
+
+ @trace
+ def is_remote(self):
+ if self.config['machine'] == None:
+ return False
+ if re.match('^ssh://', self.config['machine']):
+ return True
+ else:
+ return False
+
+ @trace
+ def run(self, commands):
+ result = None
+
+ if not self.quiet:
+ print('\tRunning \'{}\''.format(' '.join(commands)))
+
+ if type(commands) == type(list()):
+ commands = ' '.join(commands)
+
+ shell_command = 'cd {} && {}'.format('~',
+ 'adb shell '
+ + '"'
+ + commands.replace('"', '\\"')
+ + '"')
+
+ self.wait_for_ready()
+
+ if self.is_remote():
+ machine = re.sub('^ssh://', '', self.config['machine'])
+ result = sh.ssh(machine, shell_command)
+ else:
+ result = sh.bash('-c', shell_command)
+
+ return result
+
+ @trace
+ def mount_cache(self):
+ return self.run(['mount', self.get_cache_partition(), '/cache'])
+
+ # Documentation: bootable/recovery/recovery.cpp
+ @trace
+ def append_recovery_command(self, command):
+ self.wait_for_ready()
+ self.run(['echo', command, '>>', '/cache/recovery/command'])
+
+ @trace
+ def wipe_cache_and_data(self):
+ if not self.quiet:
+ print('Starting to wipe the data data and cache partition:')
+
+ self.mount_cache()
+
+ self.append_recovery_command('--wipe_data')
+
+ self.host.run(['adb', 'reboot', 'recovery'])
+
+ @trace
+ def install_zip(self, recovery_path):
+ filename = recovery_path.split(os.sep)[-1]
+
+ if not self.quiet:
+ print('RecoveryRuntime.install_zip: '
+ + 'Starting to install {} on {}'.format(filename, self.device))
+
+ self.append_recovery_command('--sideload')
+ self.host.run(['adb', 'reboot', 'recovery'])
+
+ @trace
+ def install_boot_img(self, path, retries=100):
+ if not self.quiet:
+ print('Starting to install the {} boot image on {}'.format(
+ path, self.device))
+
+ filename = os.path.basename(path)
+ partition = self.get_boot_partition()
+
+ self.host.run(['adb', 'wait-for-recovery'])
+ self.host.run(['adb', 'push', path, '/' + filename])
+ self.host.run(['adb', 'shell', 'dd', 'if=/dev/zero', 'of=' + partition])
+ self.host.run(['adb', 'shell', 'dd', 'if=' + filename, 'of=' + partition])
+ self.host.run(['adb', 'shell', 'sync'])
+ self.host.run(['adb', 'shell', 'rm', '-f', '/' + filename])
+
+def install_replicant_release(local_config,
+ major_version, minor_version,
+ device, wipe_cache_and_data=True,
+ add_root=True,
+ disable_modem=False, quiet=False):
+ if not quiet:
+ print('RecoveryRuntime.install_replicant_release: '
+ + 'Installing Replicant {} release for the {}'.format(
+ minor_version, device))
+ host = lib.hosts.Host(local_config, quiet=quiet)
+ device = lib.devices.Device(host, device, quiet=quiet)
+
+ release = lib.replicant_releases.ReplicantRelease(local_config,
+ major_version,
+ minor_version,
+ host, device, quiet)
+
+ runtime = lib.devices.DeviceRuntime(local_config, host, device, release,
+ quiet=quiet)
+
+ runtime.install_recovery(release.get_recovery_path(), add_root)
+ if wipe_cache_and_data:
+ runtime.wipe_cache_and_data()
+ runtime.install_zip(release.get_zip_path(), add_root, disable_modem)
+ runtime.boot('replicant')
+ runtime.wait_for_boot_complete()