예제 #1
0
 def test_cli_destroy_nonexistent_config_file_fails(self, fixture_cli_base):
     with pytest.raises(SystemCallException):
         for base in fixture_cli_base:
             syscall('{} destroy'.format(base), check=True)
     with pytest.raises(SystemCallException):
         for base in fixture_cli_base:
             syscall('{} destroy -v'.format(base), check=True)
예제 #2
0
def test_cli_commands_nonexistent_config_fails(
        fixture_cli_base_nonexistent_config_file,
        fixture_supported_cli_commands):
    for command in fixture_supported_cli_commands.keys():
        with pytest.raises(SystemCallException):
            syscall('{} {}'.format(fixture_cli_base_nonexistent_config_file,
                                   command),
                    check=True)
예제 #3
0
def fixture_valid_docker_machine(): # type: () -> None
    if environ.get('FLOOP_LOCAL_HARDWARE_TEST'):
        pass
    elif environ.get('FLOOP_CLOUD_TEST'):
        pass
    # default to local 1GB Virtualbox machine
    else: 
        create_local_machine = '''docker-machine create 
        --driver virtualbox 
        --virtualbox-memory 1024
        {}'''.format(_TEST_CORE_NAME)
        syscall(create_local_machine, check=False)
예제 #4
0
def destroy(core, check=True):  # type: (Core, bool) -> None
    '''
    Parallelizable; destroy core by rm'ing Docker machine

    Args:
        core (:py:class:`floopcli.iot.core.Core`):
            initialized target core object
        check (bool):
            if True, check that core destroy system calls
            return non-zero exit codes
    Raises:
        :py:class:`floopcli.iot.core.CoreDestroyException`:
            destroy commands returned non-zero exit code
    '''
    try:
        rm_core = ('sys', '{} rm -f {}'.format(core.host_docker_machine_bin,
                                               core.core))
        # order matters
        commands = [rm_core]
        for command_ in commands:
            kind, command = command_
            __log(core, 'info', command)
            if kind == 'sys':
                out, err = syscall(command=command, check=check)
                __log(core, 'info', str((out, err)))
    # TODO: find a case where init succeeds but destroy fails, enforce idempotency
    except SystemCallException as e:
        __log(core, 'error', repr(e))
        raise CoreDestroyException(repr(e))
예제 #5
0
def create(core, check=True, timeout=240):  # type: (Core, bool, int) -> None
    '''
    Parallelizable; create new docker-machine on target core

    Args:
        core (:py:class:`floopcli.core.iot.Core`):
            initialized target core object
        check (bool):
            if True, check core creation succeeded by running
            'pwd' via docker-machine SSH on newly created core
        timeout (int):
            time in seconds to wait for success before throwing error
            (docker-machine create timeout is too long)
    Raises:
        :py:class:`floopcli.core.iot.CoreCreateException`:
            core creation failed during docker-machine create or
            'pwd' check failed
    '''
    def timeout_handler(signum, frame):  #type: ignore
        raise CoreCreateException('Create core timed out')

    create_command = '{} create --driver generic --generic-ip-address {} --generic-ssh-port {} --generic-ssh-user {} --generic-ssh-key {} --engine-storage-driver overlay {}'.format(
        core.host_docker_machine_bin, core.address, core.port, core.user,
        core.host_key, core.core)
    __log(core, 'info', create_command)
    signal.signal(signal.SIGALRM, timeout_handler)
    signal.alarm(timeout)
    try:
        out, err = syscall(create_command, check=False, verbose=verbose())
        __log(core, 'info', out)
        if check:
            check_command = 'pwd'
            __log(core, 'info', 'Checking with {}'.format(check_command))
            outd = core.run_ssh_command('pwd', check=check)
            __log(core, 'info', outd)
    except SystemCallException as e:
        __log(core, 'error', 'Create timed out')
        raise CoreCreateException(repr(e))
예제 #6
0
    def run_ssh_command(self,
                        command,
                        check=True,
                        verbose=False):  # type: (str, bool, bool) -> str
        '''
        Run docker-machine SSH command on target core

        Args:
            command (str):
                command to run on target core
            check (bool):
                if True, check whether command exit code is non-zero
        Returns:
            str:
                stdout output of SSH command
        Raises:
            :py:class:`floopcli.util.syscall.SystemCallException`:
                SSH command exit code was non-zero
        '''
        sys_string = '{} ssh {} {}'.format(self.host_docker_machine_bin,
                                           self.core, command)
        out, _ = syscall(sys_string, check=check, verbose=verbose)
        return out
예제 #7
0
def push(core, check=True):  # type: (Core, bool) -> None
    '''
    Parallelizable; push files from host to target core 

    Ignores floop.log and floop.json

    Args:
        core (:py:class:`floopcli.core.iot.Core`):
            initialized target core object
        check (bool):
            if True, check core creation succeeded by running
            'pwd' via docker-machine SSH on newly created core
    Raises:
        :py:class:`floopcli.core.iot.CoreCreateException`:
            core creation failed during docker-machine create or
            'pwd' check failed
    '''
    # prevents race condition where source exists at start of floop
    # call but gets removed before push
    # TODO: simulate the race condition
    if not isdir(core.host_source):
        __log(core, 'error', 'Source not found: {}'.format(core.host_source))
        raise CoreSourceNotFound(core.host_source)
    try:
        mkdir_string = 'mkdir -p {}'.format(core.target_source)
        __log(core, 'info', mkdir_string)
        out = core.run_ssh_command(mkdir_string, check=True)
        __log(core, 'info', out)
        sync_string = "rsync -avhz -e '{} ssh' {} {}:'{}' --exclude=floop.log --exclude=floop.json --delete".format(
            core.host_docker_machine_bin, core.host_source, core.core,
            core.target_source)
        __log(core, 'info', sync_string)
        out, err = syscall(sync_string, check=check)
        __log(core, 'info', out)
    except SystemCallException as e:
        __log(core, 'error', repr(e))
        raise CoreCommunicationException(repr(e))
예제 #8
0
def test_cli_version():
    syscall('floop --version', check=True)
예제 #9
0
def test_cli_test_fail_fails(fixture_valid_config_file,
                             fixture_failing_testfile):
    with pytest.raises(SystemCallException):
        syscall('floop -c {} test'.format(fixture_valid_config_file),
                check=True)
예제 #10
0
def test_cli_push_nonexistent_src_dir_fails(
        fixture_nonexistent_source_dir_cli_config_file):
    with pytest.raises(SystemCallException):
        syscall('floop -c {} push'.format(
            fixture_nonexistent_source_dir_cli_config_file),
                check=True)
예제 #11
0
def test_cli_bases_fail(fixture_cli_base, fixture_valid_config_file):
    for base in fixture_cli_base:
        with pytest.raises(SystemCallException):
            syscall(base, check=True)
예제 #12
0
def test_cli_build_fail_fails(fixture_valid_config_file,
                              fixture_failing_buildfile):
    with pytest.raises(SystemCallException):
        print(
            syscall('floop -c {} build'.format(fixture_valid_config_file),
                    check=True))
예제 #13
0
def test_cli_unknown_commands_fail(fixture_cli_base, fixture_valid_config_file,
                                   fixture_unknown_cli_commands):
    for base in fixture_cli_base:
        for command in fixture_unknown_cli_commands:
            with pytest.raises(SystemCallException):
                syscall('{} {}'.format(base, command), check=True)
예제 #14
0
 def test_cli_destroy_nonexistent_core_is_idempotent(
         self, fixture_cli_base, fixture_invalid_core_config_file):
     syscall('floop destroy', check=True)
     syscall('floop destroy', check=True)
예제 #15
0
 def test_cli_push_nonexistent_config_file_fails(self):
     with pytest.raises(SystemCallException):
         syscall('floop push', check=True)
     with pytest.raises(SystemCallException):
         syscall('floop push -v', check=True)
예제 #16
0
 def test_cli_run(self, fixture_cli_base, fixture_valid_config_file,
                  fixture_buildfile):
     for base in fixture_cli_base:
         syscall('{} run'.format(base), check=True)
         syscall('{} run -v'.format(base), check=True)
예제 #17
0
def test_cli_commands_malformed_configs_fails(fixture_malformed_floop_configs,
                                              fixture_supported_cli_commands):
    for config in fixture_malformed_floop_configs:
        for command in fixture_supported_cli_commands.keys():
            with pytest.raises(SystemCallException):
                syscall('floop -c {} {}'.format(config, command), check=True)
예제 #18
0
def test_syscall_check_nonzero_exit_fails():
    with pytest.raises(SystemCallException):
        syscall('cp', check=True, verbose=True)
예제 #19
0
 def test_cli_logs(self, fixture_cli_base, fixture_valid_config_file):
     syscall('floop logs', check=True)
     syscall('floop logs -m test', check=True)
     syscall('floop logs -v', check=True)
     syscall('floop logs -v -m test', check=True)
예제 #20
0
 def test_cli_create(self, fixture_cli_base, fixture_valid_config_file):
     for base in fixture_cli_base:
         syscall('{} create --timeout 10'.format(base), check=True)
예제 #21
0
 def test_cli_config_overwrite(fixture_cleanup_config):
     syscall('floop config', check=True)
     syscall('floop config', check=True)
     syscall('floop config --overwrite', check=True)
예제 #22
0
def test_cli_push_redundant_config_fails(fixture_redundant_config_file):
    with pytest.raises(SystemCallException):
        syscall('floop -c {} push'.format(fixture_redundant_config_file),
                check=True)
예제 #23
0
 def test_cli_test(self, fixture_cli_base, fixture_valid_config_file,
                   fixture_testfile):
     for base in fixture_cli_base:
         syscall('{} test'.format(base), check=True)
         syscall('{} test -v'.format(base), check=True)
예제 #24
0
 def test_cli_logs_incompatible_flags(self):
     with pytest.raises(SystemCallException):
         syscall('floop -c floop.json logs', check=True)
예제 #25
0
def test_incompatible_cli_commands_fail(fixture_incompatible_cli_commands):
    for command in fixture_incompatible_cli_commands:
        with pytest.raises(SystemCallException):
            syscall(command, check=True)
예제 #26
0
 def test_cli_push(self, fixture_cli_base, fixture_valid_config_file):
     for base in fixture_cli_base:
         syscall('{} push'.format(base), check=True)
         syscall('{} push -v'.format(base), check=True)
예제 #27
0
def test_syscall_pwd():
    syscall('pwd', check=True, verbose=True)