def unzip(archive, path):
    log_new('unzip')
    logg('archive', archive)
    logg('path', path)

    with zipfile.ZipFile(archive, "r") as z:
        z.extractall(path)
Пример #2
0
def adb_load_base(config, parameters):
    log_new('load_base')

    [
        base,
        device_name,
    ] = parameters

    base_name = os.path.basename(base)

    logg('base', base)
    logg('device_name', device_name)

    adb_client = get_adb_client()

    adb_device = AdbDevice(device_name, config, adb_client)

    adb_device.echo('Recreating work dir {}'.format(config.ANDROID_WORK_DIR))
    if config.ANDROID_WORK_DIR == config.ANDROID_MAIN_DIR:
        raise Exception('Incorrect work dir: {}'.format(
            config.ANDROID_WORK_DIR))
    adb_device.delete_path_on_android(config.ANDROID_WORK_DIR)
    adb_device.create_dir_on_android(config.ANDROID_WORK_DIR)

    adb_device.echo('Loading base to Android device: {}'.format(device_name))
    adb_device.copy_file_to_android(
        base, '{}/{}'.format(config.ANDROID_WORK_DIR, base_name))

    adb_device.list_dir_content_on_android(config.ANDROID_WORK_DIR)

    adb_device.echo('Loading base finished')
 def list_dir_content_on_android(self, dir_path):
     log_new('list_dir_content_on_android')
     logg('dir_path', dir_path)
     cl = 'ls {}'.format(dir_path)
     log('-------------------')
     self._execute_shell_command_on_device(cl)
     log('-------------------')
def get_tags(tcserver_info, build_id):
    log_new('get_tags')

    url = ''.join((
        tcserver_info.url,
        '/app/rest/builds/buildType:',
        tcserver_info.project,
        ',id:',
        build_id,
        '/tags/',
    ))

    logg('url', url)

    response = requests.get(url,
                            auth=(tcserver_info.login, tcserver_info.password))
    answer = response.content
    logg('answer', answer)

    if response.status_code != 200:
        raise Exception(
            'Unable to get builds information from server, status code: {}'.
            format(str(response.status_code)))

    tags = parse_xml_answer(answer, "//tag/@name")

    return tags
def run_process(config, cl):
    log_new('run_process')

    def wait_process(process, timeout):
        log_new('wait_process')

        start_time = time.time()
        wait_key = True
        while wait_key:
            time.sleep(config.PROCESS_WAIT_TIME_STEP_SEC)

            if process.poll() is None:  # process is running / not terminated
                current_time = time.time()
                seconds_passed = int(current_time - start_time)

                if seconds_passed > int(timeout):
                    log(' '.join(('timeout:', str(seconds_passed), 'sec')))
                    wait_key = False
                    subprocess.call(
                        ['taskkill', '/F', '/T', '/PID',
                         str(process.pid)])
                    log('process terminated')
            else:
                wait_key = False

    logg('cl', cl)
    process = subprocess.Popen(cl)
    wait_process(process, config.SHORT_TIMEOUT_SEC)
 def __init__(self, device_name, config, client):
     self.device_name = device_name
     self.config = config
     self.client = client
     device_code = config.DEVICE_CODES[device_name]
     logg('device_code', device_code)
     self.device = client.device(device_code)
Пример #7
0
def _get_parameters():
    log_new('_get_parameters')

    logg('cl', sys.argv)

    parser = argparse.ArgumentParser()
    parser.add_argument("--current-results-build", type=str,
                        required=False)  #left for backward compatability
    parser.add_argument("--baseline-results-build", type=str,
                        required=False)  #left for backward compatability
    parser.add_argument("--current-build", type=str, required=True)
    parser.add_argument("--baseline-build", type=str, required=True)
    parser.add_argument("--base-name", type=str, required=True)
    parser.add_argument("--test-name", type=str, required=True)
    parser.add_argument("--devices", type=str, required=True)
    parser.add_argument("--rgb-filter-threshold", type=str, required=True)
    parser.add_argument("--size-filter-threshold", type=str, required=True)
    parser.add_argument("--test-branch", type=str, required=True)
    parser.add_argument("--recreate-artifacts",
                        type=str,
                        default="false",
                        required=True)
    parser.add_argument("--qa-tcserver", type=str, required=True)

    parameters = parser.parse_args()
    logg('parameters', parameters)
    return parameters
def get_test_data(parameters, config):
    log_new('prepare_test_data')

    artifacts = select_artifact(parameters.device_name, config)
    build_base = add_build_to_filename(artifacts.base, config.ARTIFACT_EXTENSIONS, parameters.build_number)
    build_dynamic_layout = add_build_to_filename(
        artifacts.dynamic_layout, config.ARTIFACT_EXTENSIONS, parameters.build_number)
    build_app = add_build_to_filename(artifacts.app, config.ARTIFACT_EXTENSIONS, parameters.build_number)
    scenario_name = '.'.join((parameters.test_name, 'json'))
    device_config_name = config.DEFAULT_DEVICE_CONFIG.replace('device', str(parameters.device_name))

    test_data = Data(
        base=os.path.join(config.TEMP_DATA_DIR, build_base),
        app_src=os.path.join(config.TEMP_DATA_DIR, build_app),
        scenario_name=scenario_name,
        scenario_src=os.path.join(config.ENV_TESTS_DIR, scenario_name),
        sh_script_src=os.path.join(config.ENV_SHELL_SCRIPTS_DIR, config.ANDROID_SIDE_RUN_SCRIPT_NAME),
        wait_script_src=os.path.join(config.ENV_PROJECT_DIR, config.WAIT_SCRIPT_NAME),
        result_screens_dir=os.path.join(config.TEMP_ARTIFACTS_DIR, 'screens'),
        result_logs_dir=os.path.join(config.TEMP_ARTIFACTS_DIR, 'logs'),
        device_config_src=os.path.join(config.ENV_CONFIG_DIR, device_config_name),
        device_config_name=device_config_name,
        log_name=config.LOG_NAME.replace('build', str(parameters.build_number)),
        dynamic_layout=os.path.join(config.TEMP_DATA_DIR, build_dynamic_layout),
    )

    logg('test_data', test_data)

    return test_data
Пример #9
0
    def check_result_file(cb, result_name):
        log_new('check_result_file')

        def is_existing_file(path):
            log_new('is_existing_file')
            return os.path.exists(path) and os.path.isfile(path)

        if 'current' in cb:
            cb_build = os.path.split(parameters.current_dir)[-1]
            cb_dir = parameters.current_dir
        elif 'baseline' in cb:
            cb_build = os.path.split(parameters.baseline_dir)[-1]
            cb_dir = parameters.baseline_dir

        if result_name == 'scenario':
            result_file_name = '_'.join((
                result_name,
                parameters.test_name,
                parameters.city_name
            )) + config.ARTIFACT_FORMAT
        else:
            result_file_name = '_'.join((
                result_name,
                parameters.device_name,
                parameters.test_name,
                parameters.city_name,
                cb_build
            )) + config.ARTIFACT_FORMAT

        result_file = os.path.join(cb_dir, result_file_name)
        logg('result_file', result_file)

        assert is_existing_file(result_file), 'result file not found: {}'.format(result_file)
def remove_files_if(func, files):
    log_new('remove_files_if')
    for file in files:
        if func(file):
            if os.path.isfile(file):
                logg('deleting file', file)
                os.remove(file)
            else:
                delete_directory(file)
def get_parameters():
    log_new('_get_parameters')

    logg('cl', sys.argv)

    parser = argparse.ArgumentParser()
    parser.add_argument("-b", "--build-number", type=str, required=True)
    args = parser.parse_args()
    logg('args', args)
    return args
Пример #12
0
def _set_tag(chosen_build, builds_info, del_tags, new_tag, tcserver_info):
    log_new('_set_tag')
    log('{} -> {}'.format(del_tags, new_tag))

    build_info = builds_info[chosen_build]
    old_tags = set(build_info.tags)
    logg('old_tags', old_tags)
    tags_to_delete = set(del_tags)
    new_tags = (old_tags - tags_to_delete) | {new_tag}

    add_tags(chosen_build, new_tags, tcserver_info)
def get_teamcity_artifact_file_name(build_number, config):
    log_new('get_artifact_file_name')

    artifact_file_name = ''.join((
        config.ARTIFACT_NAME,
        '-',
        build_number,
        config.ARTIFACT_FORMAT
    ))
    logg('artifact_file_name', artifact_file_name)
    return artifact_file_name
def check_input_artifacts(artifacts_path, build_number, device, config):
    log_new('check_input_artifacts')
    logg('artifacts_path', artifacts_path)

    artifacts = select_artifact(device, config)
    artifact_files = os.listdir(artifacts_path)
    expected_artifact_files = map(lambda name: add_build_to_filename(name, config.ARTIFACT_EXTENSIONS, build_number),
                                  artifacts)
    logg('expected_artifact_files', expected_artifact_files)
    not_found_files = filter(lambda name: name not in artifact_files, expected_artifact_files)
    assert len(not_found_files) is 0, 'Artifact files not found: {}'.format(not_found_files)
def get_parameters():
    log_new('_get_parameters')

    logg('cl', sys.argv)

    parser = argparse.ArgumentParser()
    parser.add_argument("-b", "--build-number", type=str, required=True)
    parser.add_argument("-d", "--device-name", type=str, required=True)
    parser.add_argument("-t", "--test-name", type=str, required=True)
    parameters = parser.parse_args()
    logg('parameters', parameters)
    return parameters
def get_teamcity_artifact_url(build_number, artifact_file_name, config):
    log_new('get_artifact_url')

    url = '/'.join((
        config.REMOTE_TC_SERVER_GUEST_URL,
        'repository/download',
        config.REMOTE_TC_PROJECT,
        build_number,
        artifact_file_name
    ))
    logg('url created', url)
    return url
 def parse_response(response, build_fields):
     log_new('parse_response')
     response_content = response.content
     root = etree.fromstring(response_content)
     node = root.xpath('/builds/build')[0]
     result = {}
     for field_name in build_fields:
         value = node.get(field_name)
         logg(field_name, value)
         assert value is not None
         result[field_name] = value
     return result
Пример #18
0
def _choose_build(config, tcserver_info):
    log_new('_choose_build')

    builds_info = get_builds(tcserver_info)
    queue = _create_queue(builds_info, config)

    chosen_build = str(queue[0])
    log_new('* * * * * * *')
    logg('chosen_build', chosen_build)
    log('* * * * * * *')

    return chosen_build.strip('"')
 def get_files_list_on_android(self, dir_path, extension):
     log_new('get_files_list_on_android')
     log('in dir: {} with extension: {}'.format(dir_path, extension))
     cl = 'ls {}'.format(dir_path)
     dir_content = self.device.shell(cl)
     dir_content = dir_content.encode("utf-8")
     logg('dir_content', dir_content)
     dir_content = dir_content.replace('\n', ' ')
     result = []
     for item in dir_content.split(' '):
         item = item.encode("utf-8")
         if item.strip().endswith('.{}'.format(extension)):
             result.append(item)
     return result
def parse_xml_answer(answer, xpath_pattern):
    log_new('parse_xml_answer')

    doc = etree.fromstring(answer.strip())

    result = []

    for element in doc:
        el = etree.fromstring(etree.tostring(element))
        name = ensure_not_single_element_list(el.xpath(xpath_pattern))
        logg('name', name)
        result.append(name.lower())

    return result
Пример #21
0
def _find_tagged_baseline_build(config, tcserver_info):
    log_new('_find_tagged_baseline_build')

    builds_info = get_builds(tcserver_info)

    tagged = []

    for build_number, build_info in builds_info.iteritems():
        if config.tag_baseline in build_info.tags:
            tagged.append(int(build_number))

    logg('tagged baseline build', tagged)

    return str(max(tagged)) if len(tagged) > 0 else None
Пример #22
0
    def save_diff_image(l_path, r_path, count):
        # saving resulting diff png on disk
        if count == 0:
            return None

        image1_name = os.path.basename(l_path)
        image2_name = os.path.basename(r_path)
        assert image1_name == image2_name
        diff_name = image1_name.replace('.png', '_{}.png'.format(str(count)))
        diff_path = os.path.join(diff_dir, diff_name)
        diff_image = build_diff_image(diff_gray_alpha, image1, whitening_ratio)
        cv2.imwrite(diff_path, diff_image)

        logg('diff', diff_path)
        return diff_path
Пример #23
0
def get_parameters():
    log_new('_get_parameters')

    logg('cl', sys.argv)

    parser = argparse.ArgumentParser()

    parser.add_argument('--current-dir', '-c', type=str, required=True)
    parser.add_argument('--baseline-dir', '-b', type=str, required=True)
    parser.add_argument('--device-name', '-d', type=str, required=True)
    parser.add_argument('--test-name', '-t', type=str, required=True)
    parser.add_argument('--city-name', '-city', type=str, required=True)

    parameters = parser.parse_args()

    logg('parameters', parameters)

    return parameters
    def get_image_set_info(image_set):
        log_new('get_image_set_info')

        correct_name = image_set.correct
        info_set = correct_name.rstrip('.png').split('_')
        screen_name = correct_name.rstrip('.png')

        if image_set.diff is not None:

            diff_name = os.path.basename(image_set.diff)
            logg('diff_name', diff_name)
            diff_info_set = diff_name.rstrip('.png').split('_')

            if len(diff_info_set) == 7:
                diff_sum = diff_info_set[6]
            else:
                raise Exception(
                    'Incorrect format of diff name: number of "_"-devided items = {} (expected 7)'
                    .format(len(diff_info_set)))
        else:
            diff_sum = None

        if len(info_set) == 6:

            result = ScreenInfo(
                screen_name,
                info_set[0],
                get_testcase_name(screen_name),
                info_set[1].replace('scr', ''),
                info_set[2],
                info_set[3],
                info_set[4],
                info_set[5],
                diff_sum,
                status[screen_name],
            )

        else:
            raise Exception(
                'Incorrect format of screenshot name: number of "_"-devided items = {} (expected 6)"'
                .format(len(info_set)))

        return result
Пример #25
0
def get_parameters(config):
    log_new('_get_parameters')

    logg('cl', sys.argv)

    parser = argparse.ArgumentParser()

    parser.add_argument('--current-dir', '-c', type=str, required=True)
    parser.add_argument('--baseline-dir', '-b', type=str, required=True)
    parser.add_argument('--diff-dir', '-d', type=str, required=True)
    parser.add_argument('--rgb-threshold',
                        '-f1',
                        type=int,
                        required=False,
                        default=config.DEFAULT_RGB_THRESHOLD)
    parser.add_argument('--size-threshold',
                        '-f2',
                        type=int,
                        required=False,
                        default=config.DEFAULT_SIZE_THRESHOLD)
    parser.add_argument('--test_name', '-t', type=str, required=False)
    parser.add_argument('--base_name', '-base', type=str, required=True)
    parser.add_argument('--device_name', '-device', type=str, required=True)
    parser.add_argument('--current-build', '-cb', type=int, required=True)
    parser.add_argument('--baseline-build', '-bb', type=int, required=True)
    parser.add_argument('--current-test-build', '-ct', type=int, required=True)
    parser.add_argument('--baseline-test-build',
                        '-bt',
                        type=int,
                        required=True)

    parameters = parser.parse_args()

    logg('parameters', parameters)

    assert isinstance(parameters.rgb_threshold, int)
    assert isinstance(parameters.size_threshold, int)
    assert isinstance(parameters.current_build, int)
    assert isinstance(parameters.baseline_build, int)
    assert isinstance(parameters.current_test_build, int)
    assert isinstance(parameters.baseline_test_build, int)

    return parameters
def create_tag(tcserver_info, build_id, tag):
    log_new('create_tag')
    logg('tag', tag)

    build_id = str(build_id)

    tags_xml = '<?xml version="1.0" encoding="UTF-8" standalone="yes"?><tags count="1"><tag name="{}"/></tags>'. \
        format(tag.lower())
    logg('tags_xml', tags_xml)

    headers = {'Content-Type': 'application/xml'}
    url = '{}/app/rest/builds/buildType:{},id:{}/tags/'.format(
        tcserver_info.url, tcserver_info.project, str(build_id))

    response = requests.put(url,
                            data=tags_xml,
                            headers=headers,
                            auth=(tcserver_info.login, tcserver_info.password))
    log(response.content)
Пример #27
0
def _create_queue(builds_info, config):
    log_new('_create_queue')

    tagged_for_execution = []
    ready_for_execution = []
    processed_tags = [
        config.tag_finished, config.tag_progress, config.tag_broken,
        config.tag_baseline
    ]
    processed_tags_set = set(processed_tags)

    for build_number, build_info in builds_info.iteritems():

        if not build_info.status == 'SUCCESS':
            continue

        is_tagged = len(build_info.tags) > 0
        is_root = config.tag_root in build_info.tags
        is_processed = len(set(build_info.tags) & processed_tags_set) > 0

        if is_root:
            logg('tagged for execution', build_number)
            tagged_for_execution.append(int(build_number))
        elif not is_processed:
            if is_tagged:
                logg('tagged with irrelevant tag(s) ready for execution',
                     build_number)
            else:
                logg('untagged ready for execution', build_number)
            ready_for_execution.append(int(build_number))

    queue = tagged_for_execution + ready_for_execution

    logg('unsorted queue', queue)

    queue.sort(reverse=True)

    logg('sorted queue', queue)

    if len(queue) == 0:
        raise Exception('No builds in queue')

    return queue
Пример #28
0
def _check_artifacts(test_name, base_name, device_name, build_number,
                     build_artifacts):
    log_new('_check_artifacts')

    logg('build_number', build_number)
    logg('build_artifacts', build_artifacts)

    correct_artifacts = [
        'logs_{}_{}_{}_{}.zip'.format(device_name.lower(), test_name,
                                      base_name, build_number),
        'screens_{}_{}_{}_{}.zip'.format(device_name.lower(), test_name,
                                         base_name, build_number),
        'scenario_{}_{}.zip'.format(test_name, base_name),
    ]

    result = True
    for artifact in correct_artifacts:
        if artifact not in build_artifacts:
            result = False
            log('artifact not found {}'.format(artifact))
    return result
def download_teamcity_artifact(artifact_url, artifact_file):
    log_new('download_teamcity_artifact')
    logg('artifact_url', artifact_url)
    logg('artifact_file', artifact_file)

    response = requests.get(artifact_url)
    logg('response', response)
    status_code = response.status_code
    logg('status_code', status_code)
    assert status_code == 200, 'wrong status code: {}'.format(status_code)

    with open(artifact_file, 'wb') as f:
        for chunk in response.iter_content(1024):
            f.write(chunk)
def create_correct_list(scenario1, scenario2):
    """
    :param scenario: path to scenario json file
    :type scenario: str
    :return: list of expected screenshots obtained from json
    :rtype: list[str]
    """
    log_new('create_correct_list')
    logg('scenario1', scenario1)
    logg('scenario2', scenario2)

    _check_jsons_identity(scenario1, scenario2)

    screenshots = []
    with open(scenario1, 'r') as json_file:
        json_data = json.load(json_file)
    for json_line in json_data:
        if json_line['name'] == 'make_screenshot':
            screenshot_name = json_line['arguments']['file_name'].replace(
                'screens/', '')
            if screenshot_name != 'finish.png':
                screenshots.append(screenshot_name)
    return screenshots