diff options
Diffstat (limited to 'tests/cloud_tests/instances/base.py')
-rw-r--r-- | tests/cloud_tests/instances/base.py | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/tests/cloud_tests/instances/base.py b/tests/cloud_tests/instances/base.py new file mode 100644 index 00000000..9559d286 --- /dev/null +++ b/tests/cloud_tests/instances/base.py @@ -0,0 +1,120 @@ +# This file is part of cloud-init. See LICENSE file for license information. + +import os +import uuid + + +class Instance(object): + """ + Base instance object + """ + platform_name = None + + def __init__(self, name): + """ + setup + """ + self.name = name + + def execute(self, command, stdin=None, stdout=None, stderr=None, env={}): + """ + command: the command to execute as root inside the image + stdin, stderr, stdout: file handles + env: environment variables + + Execute assumes functional networking and execution as root with the + target filesystem being available at /. + + return_value: tuple containing stdout data, stderr data, exit code + """ + raise NotImplementedError + + def read_data(self, remote_path, encode=False): + """ + read_data from instance filesystem + remote_path: path in instance + decode: return as string + return_value: data as str or bytes + """ + raise NotImplementedError + + def write_data(self, remote_path, data): + """ + write data to instance filesystem + remote_path: path in instance + data: data to write, either str or bytes + """ + raise NotImplementedError + + def pull_file(self, remote_path, local_path): + """ + copy file at 'remote_path', from instance to 'local_path' + """ + with open(local_path, 'wb') as fp: + fp.write(self.read_data(remote_path), encode=True) + + def push_file(self, local_path, remote_path): + """ + copy file at 'local_path' to instance at 'remote_path' + """ + with open(local_path, 'rb') as fp: + self.write_data(remote_path, fp.read()) + + def run_script(self, script): + """ + run script in target and return stdout + """ + script_path = os.path.join('/tmp', str(uuid.uuid1())) + self.write_data(script_path, script) + (out, err, exit_code) = self.execute(['/bin/bash', script_path]) + return out + + def console_log(self): + """ + return_value: bytes of this instance’s console + """ + raise NotImplementedError + + def reboot(self, wait=True): + """ + reboot instance + """ + raise NotImplementedError + + def shutdown(self, wait=True): + """ + shutdown instance + """ + raise NotImplementedError + + def start(self, wait=True): + """ + start instance + """ + raise NotImplementedError + + def destroy(self): + """ + clean up instance + """ + pass + + def _wait_for_cloud_init(self, wait_time): + """ + wait until system has fully booted and cloud-init has finished + """ + if not wait_time: + return + + found_msg = 'found' + cmd = ('for ((i=0;i<{wait};i++)); do [ -f "{file}" ] && ' + '{{ echo "{msg}";break; }} || sleep 1; done').format( + file='/run/cloud-init/result.json', + wait=wait_time, msg=found_msg) + + (out, err, exit) = self.execute(['/bin/bash', '-c', cmd]) + if out.strip() != found_msg: + raise OSError('timeout: after {}s, cloud-init has not started' + .format(wait_time)) + +# vi: ts=4 expandtab |