<commit_before>import subprocess
import os
import json
import logging

log = logging.getLogger(__name__)

class Terraform:
    def __init__(self, targets=None, state='terraform.tfstate', variables=None):
        self.targets = [] if targets is None else targets
        self.variables = dict() if variables is None else variables

        self.state_filename = state
        self.state_data = dict()
        self.parallelism = 50

    def apply(self, targets=None, variables=None, **kargs):
        """
        refer to https://terraform.io/docs/commands/apply.html
        :param variables: variables in dict type
        :param targets: targets in list
        :returns return_code, stdout, stderr
        """
        variables = self.variables if variables is None else variables
        targets = self.targets if targets is None else targets

        parameters = []
        parameters += self._generate_targets(targets)
        parameters += self._generate_var_string(variables)
        parameters += self._gen_param_string(kargs)

        parameters = \
            ['terraform', 'apply', '-state=%s' % self.state_filename] + parameters

        cmd = ' '.join(parameters)
        return self._run_cmd(cmd)

    def _gen_param_string(self, kargs):
        params = []
        for key, value in kargs.items():
            if not value:
                params += ['-%s=%s' % (key, value)]
            else:
                params += ['-%s' % key]
        return params

    def _run_cmd(self, cmd):
        log.debug('command: ' + cmd)

        p = subprocess.Popen(
            cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        out, err = p.communicate()
        ret_code = p.returncode
        log.debug('output: ' + out)

        if ret_code == 0:
            log.debug('error: ' + err)
            self.read_state_file()
        return ret_code, out, err

    def destroy(self, targets=None, variables=None, **kwargs):
        variables = self.variables if variables is None else variables
        targets = self.targets if targets is None else targets

        parameters = []
        parameters += self._generate_targets(targets)
        parameters += self._generate_var_string(variables)

        parameters = \
            ['terraform', 'destroy', '-force', '-state=%s' % self.state_filename] + \
            parameters
        cmd = ' '.join(parameters)
        return self._run_cmd(cmd)

    def refresh(self, targets=None, variables=None):
        variables = self.variables if variables is None else variables
        targets = self.targets if targets is None else targets

        parameters = []
        parameters += self._generate_targets(targets)
        parameters += self._generate_var_string(variables)
        parameters = \
            ['terraform', 'refresh', '-state=%s' % self.state_filename] + \
            parameters
        cmd = ' '.join(parameters)
        return self._run_cmd(cmd)

    def read_state_file(self):
        """
        read .tfstate file
        :return: states file in dict type
        """
        if os.path.exists(self.state_filename):
            with open(self.state_filename) as f:
                json_data = json.load(f)
            self.state_data = json_data
            log.debug("state_data=%s" % str(self.state_data))
            return json_data

        return dict()

    def is_any_aws_instance_alive(self):
        self.refresh()
        if not os.path.exists(self.state_filename):
            log.debug("can't find %s " % self.state_data)
            return False

        self.read_state_file()
        try:
            main_module = self._get_main_module()
            for resource_key, info in main_module['resources'].items():
                if 'aws_instance' in resource_key:
                    log.debug("%s is found when read state" % resource_key)
                    return True
            log.debug("no aws_instance found in resource key")
            return False
        except KeyError as err:
            log.debug(str(err))
            return False
        except TypeError as err:
            log.debug(str(err))
            return False

    def _get_main_module(self):
        return self.state_data['modules'][0]

    def get_aws_instances(self):
        instances = dict()

        try:
            main_module = self._get_main_module()
            for resource_key, info in main_module['resources'].items():
                if 'aws_instance' in resource_key:
                    instances[resource_key] = info
        except KeyError:
            return instances
        except TypeError:
            return instances

        return instances

    def get_aws_instance(self, resource_name):
        """
        :param resource_name:
            name of terraform resource, make source count is attached
        :return: return None if not exist, dict type if exist
        """
        try:
            return self.get_aws_instances()[resource_name]
        except KeyError:
            return None

    def get_output_value(self, output_name):
        """

        :param output_name:
        :return:
        """
        try:
            main_module = self._get_main_module()
            return main_module['outputs'][output_name]
        except KeyError:
            return None

    @staticmethod
    def _generate_var_string(d):
        str_t = []
        for k, v in d.iteritems():
            str_t += ['-var'] + ["%s=%s" % (k, v)]

        return str_t

    @staticmethod
    def _generate_targets(targets):
        str_t = []
        for t in targets:
            str_t += ['-target=%s' % t]
        return str_t

<commit_msg>fix typo<commit_after>import subprocess
import os
import json
import logging

log = logging.getLogger(__name__)

class Terraform:
    def __init__(self, targets=None, state='terraform.tfstate', variables=None):
        self.targets = [] if targets is None else targets
        self.variables = dict() if variables is None else variables

        self.state_filename = state
        self.state_data = dict()
        self.parallelism = 50

    def apply(self, targets=None, variables=None, **kargs):
        """
        refer to https://terraform.io/docs/commands/apply.html
        :param variables: variables in dict type
        :param targets: targets in list
        :returns return_code, stdout, stderr
        """
        variables = self.variables if variables is None else variables
        targets = self.targets if targets is None else targets

        parameters = []
        parameters += self._generate_targets(targets)
        parameters += self._generate_var_string(variables)
        parameters += self._gen_param_string(kargs)

        parameters = \
            ['terraform', 'apply', '-state=%s' % self.state_filename] + parameters

        cmd = ' '.join(parameters)
        return self._run_cmd(cmd)

    def _gen_param_string(self, kargs):
        params = []
        for key, value in kargs.items():
            if value:
                params += ['-%s=%s' % (key, value)]
            else:
                params += ['-%s' % key]
        return params

    def _run_cmd(self, cmd):
        log.debug('command: ' + cmd)

        p = subprocess.Popen(
            cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
        out, err = p.communicate()
        ret_code = p.returncode
        log.debug('output: ' + out)

        if ret_code == 0:
            log.debug('error: ' + err)
            self.read_state_file()
        return ret_code, out, err

    def destroy(self, targets=None, variables=None, **kwargs):
        variables = self.variables if variables is None else variables
        targets = self.targets if targets is None else targets

        parameters = []
        parameters += self._generate_targets(targets)
        parameters += self._generate_var_string(variables)

        parameters = \
            ['terraform', 'destroy', '-force', '-state=%s' % self.state_filename] + \
            parameters
        cmd = ' '.join(parameters)
        return self._run_cmd(cmd)

    def refresh(self, targets=None, variables=None):
        variables = self.variables if variables is None else variables
        targets = self.targets if targets is None else targets

        parameters = []
        parameters += self._generate_targets(targets)
        parameters += self._generate_var_string(variables)
        parameters = \
            ['terraform', 'refresh', '-state=%s' % self.state_filename] + \
            parameters
        cmd = ' '.join(parameters)
        return self._run_cmd(cmd)

    def read_state_file(self):
        """
        read .tfstate file
        :return: states file in dict type
        """
        if os.path.exists(self.state_filename):
            with open(self.state_filename) as f:
                json_data = json.load(f)
            self.state_data = json_data
            log.debug("state_data=%s" % str(self.state_data))
            return json_data

        return dict()

    def is_any_aws_instance_alive(self):
        self.refresh()
        if not os.path.exists(self.state_filename):
            log.debug("can't find %s " % self.state_data)
            return False

        self.read_state_file()
        try:
            main_module = self._get_main_module()
            for resource_key, info in main_module['resources'].items():
                if 'aws_instance' in resource_key:
                    log.debug("%s is found when read state" % resource_key)
                    return True
            log.debug("no aws_instance found in resource key")
            return False
        except KeyError as err:
            log.debug(str(err))
            return False
        except TypeError as err:
            log.debug(str(err))
            return False

    def _get_main_module(self):
        return self.state_data['modules'][0]

    def get_aws_instances(self):
        instances = dict()

        try:
            main_module = self._get_main_module()
            for resource_key, info in main_module['resources'].items():
                if 'aws_instance' in resource_key:
                    instances[resource_key] = info
        except KeyError:
            return instances
        except TypeError:
            return instances

        return instances

    def get_aws_instance(self, resource_name):
        """
        :param resource_name:
            name of terraform resource, make source count is attached
        :return: return None if not exist, dict type if exist
        """
        try:
            return self.get_aws_instances()[resource_name]
        except KeyError:
            return None

    def get_output_value(self, output_name):
        """

        :param output_name:
        :return:
        """
        try:
            main_module = self._get_main_module()
            return main_module['outputs'][output_name]
        except KeyError:
            return None

    @staticmethod
    def _generate_var_string(d):
        str_t = []
        for k, v in d.iteritems():
            str_t += ['-var'] + ["%s=%s" % (k, v)]

        return str_t

    @staticmethod
    def _generate_targets(targets):
        str_t = []
        for t in targets:
            str_t += ['-target=%s' % t]
        return str_t

<|endoftext|>


<commit_before>from nose.tools import eq_

import hashlib
import json
import nose

from js_helper import _do_real_test_raw as _js_test
from validator.testcases.markup.markuptester import MarkupParser
import validator.testcases.jetpack as jetpack
from validator.errorbundler import ErrorBundle
from validator.xpi import XPIManager

def _do_test(xpi_package, allow_old_sdk=True):

    err = ErrorBundle()
    jetpack.inspect_jetpack(err, xpi_package, allow_old_sdk=allow_old_sdk)
    return err

class MockXPI(object):

    def __init__(self, resources):
        self.resources = resources

    def read(self, name):
        if isinstance(self.resources[name], bool):
            return ''
        return self.resources[name]

    def __iter__(self):
        for name in self.resources.keys():
            yield name

    def __contains__(self, name):
        return name in self.resources

def test_not_jetpack():
    """Test that add-ons which do not match the Jetpack pattern are ignored."""

    err = _do_test(MockXPI({'foo': True, 'bar': True}))
    assert not err.errors
    assert not err.warnings
    assert not err.notices
    eq_(err.metadata.get('is_jetpack', False), False)

def test_package_json_jetpack():
    """Test that add-ons with the new package.json are treated as jetpack."""
    err = _do_test(MockXPI({'bootstrap.js': '', 'package.json': ''}))
    assert not err.errors
    assert not err.warnings
    assert not err.notices
    eq_(err.metadata.get('is_jetpack'), True)

def test_package_json_pass_jetpack():
    """Test that a minimalistic package.json Jetpack setup will pass."""

    with open('tests/resources/bootstrap.js') as bootstrap_file:
        bootstrap = bootstrap_file.read()
    err = _do_test(MockXPI({'bootstrap.js': bootstrap,
                            'package.json': '{}'}))
    print err.print_summary(verbose=True)
    assert not err.failed()
    assert 'is_jetpack' in err.metadata and err.metadata['is_jetpack']

    # Test that all files are marked as pretested.
    pretested_files = err.get_resource('pretested_files')
    assert pretested_files
    assert 'bootstrap.js' in pretested_files

def test_package_json_different_bootstrap():
    """Test that a minimalistic package.json Jetpack setup will pass."""

    err = _do_test(MockXPI({'bootstrap.js': "var foo = 'bar';",
                            'package.json': '{}'}))
    print err.print_summary(verbose=True)
    assert not err.failed()
    assert 'is_jetpack' in err.metadata and err.metadata['is_jetpack']

    # Test that all files are not marked as pretested.
    pretested_files = err.get_resource('pretested_files')
    assert not pretested_files
    assert 'bootstrap.js' not in pretested_files

def test_mismatched_db_hash():
    """
    Test that failure occurs when the hash of a file doesn't exist in the
    Jetpack known file database.
    """

    with open('tests/resources/bootstrap.js') as bootstrap_file:
        bootstrap = bootstrap_file.read()
        # Break the hash with this.
        bootstrap = 'function() {}; %s' % bootstrap

    err = _do_test(MockXPI({'bootstrap.js': bootstrap,
                            'package.json': '{}'}))
    print err.print_summary(verbose=True)
    assert not err.failed()

    assert 'jetpack_identified_files' in err.metadata

    assert 'jetpack_unknown_files' in err.metadata
    unknown_files = err.metadata['jetpack_unknown_files']
    nose.tools.eq_(len(unknown_files), 2)
    nose.tools.ok_('bootstrap.js' in unknown_files)

def test_new_module_location_spec():
    """
    Tests that we don't fail for missing modules in add-ons generated with
    newer versions of the SDK.
    """

    xpi = XPIManager('tests/resources/jetpack/jetpack-1.14.xpi')
    err = _do_test(xpi)

    assert not any(w['id'][2] == 'missing_jetpack_module'
                   for w in err.warnings)

def test_components_flagged():
    """Test that `Components` is flagged in Jetpack."""

    js = """
    var x = Components.services.foo.bar;
    """
    assert not _js_test(js).failed()
    assert _js_test(js, jetpack=True).failed()

def test_safe_require():
    """Test that requiring an innocuous module does not add the
    requires_chrome flag."""

    def base_case():
        err = _js_test("""var foo = require("bar");""",
                       jetpack=True)
        eq_(err.metadata['requires_chrome'], False)
    yield base_case

def test_unsafe_safe_require():
    """Test that requiring low-level modules does add the requires_chrome
    flag."""

    interfaces = ['chrome', 'window-utils', 'observer-service']

    def interface_cases(interface):
        err = _js_test("""var {cc, ci} = require("%s")""" % interface,
                       jetpack=True)
        print err.print_summary(verbose=True)

        first_message = err.warnings[0]['message']
        assert 'non-SDK interface' in first_message, ('unexpected: %s' %
                                                          first_message)
        assert 'requires_chrome' in err.metadata, \
                'unexpected: "requires_chrome" should be in metadata'
        eq_(err.metadata['requires_chrome'], True)

    for case in interfaces:
        yield interface_cases, case

def test_absolute_uris_in_js():
    """
    Test that a warning is thrown for absolute URIs within JS files.
    """

    bad_js = 'alert("resource://foo-data/bar/zap.png");'
    assert not _js_test(bad_js).failed()
    err =_js_test(bad_js, jetpack=True)
    assert err.failed()
    assert err.compat_summary['errors']

    # Test that literals are inspected even if they're the result of an
    # operation.
    bad_js = 'alert("resou" + "rce://foo-" + "data/bar/zap.png");'
    assert not _js_test(bad_js).failed()
    err =_js_test(bad_js, jetpack=True)
    assert err.failed()
    assert err.compat_summary['errors']

def test_observer_service_flagged():
    assert _js_test("""
    var {Ci} = require("chrome");
    thing.QueryInterface(Ci.nsIObserverService);
    """, jetpack=True).failed()

    assert not _js_test("""
    thing.QueryInterface(Ci.nsIObserverService);
    """).failed()

def test_absolute_uris_in_markup():
    """
    Test that a warning is thrown for absolute URIs within markup files.
    """

    err = ErrorBundle()
    bad_html = '<foo><bar src="resource://foo-data/bar/zap.png" /></foo>'

    parser = MarkupParser(err)
    parser.process('foo.html', bad_html, 'html')
    assert not err.failed()

    err.metadata['is_jetpack'] = True
    parser = MarkupParser(err)
    parser.process('foo.html', bad_html, 'html')
    assert err.failed()
    assert err.compat_summary['errors']

def test_fail_on_cfx():
    """
    Test that we fail for add-ons built with 'cfx'.
    """

    with open('tests/resources/bootstrap.js') as bootstrap_file:
        bootstrap = bootstrap_file.read()
        bootstrap_hash = hashlib.sha256(bootstrap).hexdigest()

    harnessoptions = {
            'jetpackID': 'foobar',
            'sdkVersion': '1.17',
            'manifest': {
                'bootstrap.js':
                    {'requirements': {},
                     'packageName': 'addon-kit',
                     'sectionName': 'lib',
                     'moduleName': 'drawing',
                     'jsSHA256': bootstrap_hash,
                     'docsSHA256': bootstrap_hash}}}

    err = _do_test(MockXPI({'bootstrap.js': bootstrap,
                            'harness-options.json':
                                json.dumps(harnessoptions)}))
    print err.print_summary(verbose=True)
    assert err.failed() and err.errors

<commit_msg>Basic test for jetpack compat stuff<commit_after>from nose.tools import eq_

import hashlib
import json
import nose

from js_helper import _do_real_test_raw as _js_test
from validator.testcases.markup.markuptester import MarkupParser
import validator.testcases.jetpack as jetpack
from validator.errorbundler import ErrorBundle
from validator.xpi import XPIManager

def _do_test(xpi_package, allow_old_sdk=True, compat=False):

    err = ErrorBundle()
    if compat:
        err.save_resource('is_compat_test', True)
    jetpack.inspect_jetpack(err, xpi_package, allow_old_sdk=allow_old_sdk)
    return err

class MockXPI(object):

    def __init__(self, resources):
        self.resources = resources

    def read(self, name):
        if isinstance(self.resources[name], bool):
            return ''
        return self.resources[name]

    def __iter__(self):
        for name in self.resources.keys():
            yield name

    def __contains__(self, name):
        return name in self.resources

def test_not_jetpack():
    """Test that add-ons which do not match the Jetpack pattern are ignored."""

    err = _do_test(MockXPI({'foo': True, 'bar': True}))
    assert not err.errors
    assert not err.warnings
    assert not err.notices
    eq_(err.metadata.get('is_jetpack', False), False)

def test_package_json_jetpack():
    """Test that add-ons with the new package.json are treated as jetpack."""
    err = _do_test(MockXPI({'bootstrap.js': '', 'package.json': ''}))
    assert not err.errors
    assert not err.warnings
    assert not err.notices
    eq_(err.metadata.get('is_jetpack'), True)

def test_package_json_pass_jetpack():
    """Test that a minimalistic package.json Jetpack setup will pass."""

    with open('tests/resources/bootstrap.js') as bootstrap_file:
        bootstrap = bootstrap_file.read()
    err = _do_test(MockXPI({'bootstrap.js': bootstrap,
                            'package.json': '{}'}))
    print err.print_summary(verbose=True)
    assert not err.failed()
    assert 'is_jetpack' in err.metadata and err.metadata['is_jetpack']

    # Test that all files are marked as pretested.
    pretested_files = err.get_resource('pretested_files')
    assert pretested_files
    assert 'bootstrap.js' in pretested_files

def test_package_json_different_bootstrap():
    """Test that a minimalistic package.json Jetpack setup will pass."""

    err = _do_test(MockXPI({'bootstrap.js': "var foo = 'bar';",
                            'package.json': '{}'}))
    print err.print_summary(verbose=True)
    assert not err.failed()
    assert 'is_jetpack' in err.metadata and err.metadata['is_jetpack']

    # Test that all files are not marked as pretested.
    pretested_files = err.get_resource('pretested_files')
    assert not pretested_files
    assert 'bootstrap.js' not in pretested_files

def test_mismatched_db_hash():
    """
    Test that failure occurs when the hash of a file doesn't exist in the
    Jetpack known file database.
    """

    with open('tests/resources/bootstrap.js') as bootstrap_file:
        bootstrap = bootstrap_file.read()
        # Break the hash with this.
        bootstrap = 'function() {}; %s' % bootstrap

    err = _do_test(MockXPI({'bootstrap.js': bootstrap,
                            'package.json': '{}'}))
    print err.print_summary(verbose=True)
    assert not err.failed()

    assert 'jetpack_identified_files' in err.metadata

    assert 'jetpack_unknown_files' in err.metadata
    unknown_files = err.metadata['jetpack_unknown_files']
    nose.tools.eq_(len(unknown_files), 2)
    nose.tools.ok_('bootstrap.js' in unknown_files)

def test_new_module_location_spec():
    """
    Tests that we don't fail for missing modules in add-ons generated with
    newer versions of the SDK.
    """

    xpi = XPIManager('tests/resources/jetpack/jetpack-1.14.xpi')
    err = _do_test(xpi)

    assert not any(w['id'][2] == 'missing_jetpack_module'
                   for w in err.warnings)

def test_components_flagged():
    """Test that `Components` is flagged in Jetpack."""

    js = """
    var x = Components.services.foo.bar;
    """
    assert not _js_test(js).failed()
    assert _js_test(js, jetpack=True).failed()

def test_safe_require():
    """Test that requiring an innocuous module does not add the
    requires_chrome flag."""

    def base_case():
        err = _js_test("""var foo = require("bar");""",
                       jetpack=True)
        eq_(err.metadata['requires_chrome'], False)
    yield base_case

def test_unsafe_safe_require():
    """Test that requiring low-level modules does add the requires_chrome
    flag."""

    interfaces = ['chrome', 'window-utils', 'observer-service']

    def interface_cases(interface):
        err = _js_test("""var {cc, ci} = require("%s")""" % interface,
                       jetpack=True)
        print err.print_summary(verbose=True)

        first_message = err.warnings[0]['message']
        assert 'non-SDK interface' in first_message, ('unexpected: %s' %
                                                          first_message)
        assert 'requires_chrome' in err.metadata, \
                'unexpected: "requires_chrome" should be in metadata'
        eq_(err.metadata['requires_chrome'], True)

    for case in interfaces:
        yield interface_cases, case

def test_absolute_uris_in_js():
    """
    Test that a warning is thrown for absolute URIs within JS files.
    """

    bad_js = 'alert("resource://foo-data/bar/zap.png");'
    assert not _js_test(bad_js).failed()
    err =_js_test(bad_js, jetpack=True)
    assert err.failed()
    assert err.compat_summary['errors']

    # Test that literals are inspected even if they're the result of an
    # operation.
    bad_js = 'alert("resou" + "rce://foo-" + "data/bar/zap.png");'
    assert not _js_test(bad_js).failed()
    err =_js_test(bad_js, jetpack=True)
    assert err.failed()
    assert err.compat_summary['errors']

def test_observer_service_flagged():
    assert _js_test("""
    var {Ci} = require("chrome");
    thing.QueryInterface(Ci.nsIObserverService);
    """, jetpack=True).failed()

    assert not _js_test("""
    thing.QueryInterface(Ci.nsIObserverService);
    """).failed()

def test_absolute_uris_in_markup():
    """
    Test that a warning is thrown for absolute URIs within markup files.
    """

    err = ErrorBundle()
    bad_html = '<foo><bar src="resource://foo-data/bar/zap.png" /></foo>'

    parser = MarkupParser(err)
    parser.process('foo.html', bad_html, 'html')
    assert not err.failed()

    err.metadata['is_jetpack'] = True
    parser = MarkupParser(err)
    parser.process('foo.html', bad_html, 'html')
    assert err.failed()
    assert err.compat_summary['errors']

def test_fail_on_cfx():
    """
    Test that we fail for add-ons built with 'cfx'.
    """

    with open('tests/resources/bootstrap.js') as bootstrap_file:
        bootstrap = bootstrap_file.read()
        bootstrap_hash = hashlib.sha256(bootstrap).hexdigest()

    harnessoptions = {
            'jetpackID': 'foobar',
            'sdkVersion': '1.17',
            'manifest': {
                'bootstrap.js':
                    {'requirements': {},
                     'packageName': 'addon-kit',
                     'sectionName': 'lib',
                     'moduleName': 'drawing',
                     'jsSHA256': bootstrap_hash,
                     'docsSHA256': bootstrap_hash}}}

    err = _do_test(MockXPI({'bootstrap.js': bootstrap,
                            'harness-options.json':
                                json.dumps(harnessoptions)}))
    print err.print_summary(verbose=True)
    assert err.failed() and err.errors

def test_pass_cfx_for_compat():
    """
    Test that we fail for add-ons built with 'cfx'.
    """

    with open('tests/resources/bootstrap.js') as bootstrap_file:
        bootstrap = bootstrap_file.read()
        bootstrap_hash = hashlib.sha256(bootstrap).hexdigest()

    harnessoptions = {
            'jetpackID': 'foobar',
            'sdkVersion': '1.17',
            'manifest': {
                'bootstrap.js':
                    {'requirements': {},
                     'packageName': 'addon-kit',
                     'sectionName': 'lib',
                     'moduleName': 'drawing',
                     'jsSHA256': bootstrap_hash,
                     'docsSHA256': bootstrap_hash}}}

    err = _do_test(MockXPI({'bootstrap.js': bootstrap,
                            'harness-options.json':
                                json.dumps(harnessoptions)}),
                   compat=True)
    print err.print_summary(verbose=True)
    assert not err.failed() and not err.errors
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# This file is subject to the terms and conditions defined in
# file 'LICENSE.md', which is part of this source code package.
#

import unittest
from kubernetes import K8sPod, K8sConfig
from kubernetes.models.v1 import Pod, ObjectMeta, PodSpec

class K8sPodTest(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    # ------------------------------------------------------------------------------------- init

    def test_init_no_args(self):
        try:
            K8sPod()
            self.fail("Should have failed.")
        except Exception as err:
            self.assertIsInstance(err, SyntaxError)

    def test_init_with_name(self):
        name = "yomama"
        pod = K8sPod(name=name)
        self.assertIsNotNone(pod)
        self.assertIsInstance(pod, K8sPod)
        self.assertEqual(pod.name, name)

    def test_init_with_config_and_pull_secrets(self):
        ps = "yomama"
        name = "sofat"
        config = K8sConfig(pull_secret=ps)
        pod = K8sPod(config=config, name=name)
        self.assertIsNotNone(pod.config)
        self.assertEqual(ps, pod.config.pull_secret)

    # ------------------------------------------------------------------------------------- struct

    def test_struct_k8spod(self):
        name = "yomama"
        pod = K8sPod(name=name)
        self.assertIsNotNone(pod)
        self.assertIsInstance(pod, K8sPod)
        self.assertIsNotNone(pod.model)
        self.assertIsInstance(pod.model, Pod)

    def test_struct_pod(self):
        name = "yomama"
        pod = K8sPod(name=name)
        model = pod.model
        self.assertIsInstance(model.model, dict)
        self.assertIsInstance(model.pod_metadata, ObjectMeta)
        self.assertIsInstance(model.pod_spec, PodSpec)
        self.assertIsNone(model.pod_status)

    def test_struct_pod_model(self):
        name = "yomama"
        pod = K8sPod(name=name)
        model = pod.model
        self.assertIsInstance(model, Pod)
        self.assertIsNotNone(model)
        self.assertIn('apiVersion', model)
        self.assertIsInstance(model['apiVersion'], str)
        self.assertIn('kind', model)
        self.assertIsInstance(model['kind'], str)
        self.assertIn('metadata', model)
        self.assertIsInstance(model['metadata'], dict)
        self.assertIn('labels', model['metadata'])
        self.assertIsInstance(model['metadata']['labels'], dict)
        self.assertIn('name', model['metadata']['labels'])
        self.assertEqual(model['metadata']['labels']['name'], name)
        self.assertIn('name', model['metadata'])
        self.assertIsInstance(model['metadata']['name'], str)
        self.assertEqual(model['metadata']['name'], name)
        self.assertIn('namespace', model['metadata'])
        self.assertIsInstance(model['metadata']['namespace'], str)
        self.assertIn('spec', model)
        self.assertIsInstance(model['spec'], dict)
        self.assertIn('containers', model['spec'])
        self.assertIsInstance(model['spec']['containers'], list)
        self.assertIn('dnsPolicy', model['spec'])
        self.assertIsInstance(model['spec']['dnsPolicy'], str)
        self.assertIn('restartPolicy', model['spec'])
        self.assertIsInstance(model['spec']['restartPolicy'], str)
        self.assertIn('volumes', model['spec'])
        self.assertIsInstance(model['spec']['volumes'], list)

<commit_msg>K8sPod: fixes struct test<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
# This file is subject to the terms and conditions defined in
# file 'LICENSE.md', which is part of this source code package.
#

import unittest
from kubernetes import K8sPod, K8sConfig
from kubernetes.models.v1 import Pod, ObjectMeta, PodSpec

class K8sPodTest(unittest.TestCase):

    def setUp(self):
        pass

    def tearDown(self):
        pass

    # ------------------------------------------------------------------------------------- init

    def test_init_no_args(self):
        try:
            K8sPod()
            self.fail("Should have failed.")
        except Exception as err:
            self.assertIsInstance(err, SyntaxError)

    def test_init_with_name(self):
        name = "yomama"
        pod = K8sPod(name=name)
        self.assertIsNotNone(pod)
        self.assertIsInstance(pod, K8sPod)
        self.assertEqual(pod.name, name)

    def test_init_with_config_and_pull_secrets(self):
        ps = "yomama"
        name = "sofat"
        config = K8sConfig(pull_secret=ps)
        pod = K8sPod(config=config, name=name)
        self.assertIsNotNone(pod.config)
        self.assertEqual(ps, pod.config.pull_secret)

    # ------------------------------------------------------------------------------------- struct

    def test_struct_k8spod(self):
        name = "yomama"
        pod = K8sPod(name=name)
        self.assertIsNotNone(pod)
        self.assertIsInstance(pod, K8sPod)
        self.assertIsNotNone(pod.model)
        self.assertIsInstance(pod.model, Pod)

    def test_struct_pod(self):
        name = "yomama"
        pod = K8sPod(name=name)
        model = pod.model
        self.assertIsInstance(model.model, dict)
        self.assertIsInstance(model.pod_metadata, ObjectMeta)
        self.assertIsInstance(model.pod_spec, PodSpec)
        self.assertIsNone(model.pod_status)

    def test_struct_pod_model(self):
        name = "yomama"
        pod = K8sPod(name=name)
        model = pod.model.model
        self.assertIsNotNone(model)
        self.assertIsInstance(model, dict)
        self.assertIn('apiVersion', model)
        self.assertIsInstance(model['apiVersion'], str)
        self.assertIn('kind', model)
        self.assertIsInstance(model['kind'], str)
        self.assertIn('metadata', model)
        self.assertIsInstance(model['metadata'], dict)
        self.assertIn('labels', model['metadata'])
        self.assertIsInstance(model['metadata']['labels'], dict)
        self.assertIn('name', model['metadata']['labels'])
        self.assertEqual(model['metadata']['labels']['name'], name)
        self.assertIn('name', model['metadata'])
        self.assertIsInstance(model['metadata']['name'], str)
        self.assertEqual(model['metadata']['name'], name)
        self.assertIn('namespace', model['metadata'])
        self.assertIsInstance(model['metadata']['namespace'], str)
        self.assertIn('spec', model)
        self.assertIsInstance(model['spec'], dict)
        self.assertIn('containers', model['spec'])
        self.assertIsInstance(model['spec']['containers'], list)
        self.assertIn('dnsPolicy', model['spec'])
        self.assertIsInstance(model['spec']['dnsPolicy'], str)
        self.assertIn('restartPolicy', model['spec'])
        self.assertIsInstance(model['spec']['restartPolicy'], str)
        self.assertIn('volumes', model['spec'])
        self.assertIsInstance(model['spec']['volumes'], list)

<|endoftext|>


<commit_before>from simplejson import loads, dumps
import socket

class ZombieProxyClient(object):
    """
    Sends data to a ZombieProxyServer bound to a specific
    TCP socket.  Data is evaulated by the server and results
    (if any) are returned.
    """

    def __init__(self, socket='/tmp/zombie.sock'):
        self.socket = socket

    def send(self, js):
        # Establish a socket connection to the Zombie.js proxy server
        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        s.connect(self.socket)

        # Send Zombie.js API calls, followed by a stream.end() call.
        s.send("%s" % js)

        # Read the response
        response = []
        while True:
            data = s.recv(4096)
            if not data:
                break
            response.append(data)

        # Close the socket connection
        s.close()

        return ''.join(response)

    def encode(self, obj):
        if hasattr(obj, 'json'):
            return obj.json
        return dumps(obj)

    def decode(self, json):
        return loads(json)

    def json(self, js):
        return self.decode(self.send(
            "stream.end(JSON.stringify(%s));" % js
        ))

    def wait(self, method, *args):
        if args:
            methodargs = ', '.join(
                [self.encode(a) for a in args]
            )
        else:
            methodargs = 'null'

        js = """
        browser.%s(%s, function(err, browser){
            if(err)
                stream.end(JSON.stringify(err.stack));
            else
                stream.end();
        });
        """ % (
            method,
            methodargs
        )

        return self.send(js)
<commit_msg>Changed client.wait() to raise NodeError in all cases when an error happens in server process.<commit_after>from simplejson import loads, dumps
import socket

class NodeError(Exception):
    pass

class ZombieProxyClient(object):
    """
    Sends data to a ZombieProxyServer bound to a specific
    TCP socket.  Data is evaulated by the server and results
    (if any) are returned.
    """

    def __init__(self, socket='/tmp/zombie.sock'):
        self.socket = socket

    def send(self, js):
        # Establish a socket connection to the Zombie.js proxy server
        s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        s.connect(self.socket)

        # Send Zombie.js API calls, followed by a stream.end() call.
        s.send("%s" % js)

        # Read the response
        response = []
        while True:
            data = s.recv(4096)
            if not data:
                break
            response.append(data)

        # Close the socket connection
        s.close()

        return ''.join(response)

    def encode(self, obj):
        if hasattr(obj, 'json'):
            return obj.json
        return dumps(obj)

    def decode(self, json):
        return loads(json)

    def json(self, js):
        return self.decode(self.send(
            "stream.end(JSON.stringify(%s));" % js
        ))

    def wait(self, method, *args):
        if args:
            methodargs = ', '.join(
                [self.encode(a) for a in args]
            )
        else:
            methodargs = 'null'

        js = """
        try {
            browser.%s(%s, function(err, browser){
                if (err)
                    stream.end(JSON.stringify(err.message));
                else
                    stream.end();
            });
        } catch (err) {
            stream.end(JSON.stringify(err.message));
        }
        """ % (
            method,
            methodargs
        )

        response = self.send(js)
        if response:
            raise NodeError(self.decode(response))
<|endoftext|>


<commit_before># -*- coding: utf-8  -*-
from pywikibot import family

__version__ = '$Id$'

# The Wikimedia family that is known as Wikinews

class Family(family.Family):
    def __init__(self):
        family.Family.__init__(self)
        self.name = 'wikinews'

        self.languages_by_size = [
            'sr', 'en', 'pl', 'de', 'fr', 'it', 'es', 'pt', 'zh', 'ja', 'sv',
            'ru', 'ta', 'fi', 'cs', 'he', 'ro', 'bg', 'ar', 'hu', 'sd', 'fa',
            'tr', 'ca', 'uk', 'sq', 'no', 'bs', 'th', 'ko', 'eo',
        ]

        for lang in self.languages_by_size:
            self.langs[lang] = '%s.wikinews.org' % lang

        self.obsolete = {
            'jp': 'ja',
            'nb': 'no',
            'nl': None, # https://bugzilla.wikimedia.org/show_bug.cgi?id=20325
            'zh-tw': 'zh',
            'zh-cn': 'zh'
        }

        # Which languages have a special order for putting interlanguage links,
        # and what order is it? If a language is not in interwiki_putfirst,
        # alphabetical order on language code is used. For languages that are in
        # interwiki_putfirst, interwiki_putfirst is checked first, and
        # languages are put in the order given there. All other languages are put
        # after those, in code-alphabetical order.
        self.interwiki_putfirst = {
            'en': self.alphabetic,
            'fi': self.alphabetic,
            'fr': self.alphabetic,
            'he': ['en'],
            'hu': ['en'],
            'pl': self.alphabetic,
        }

        # Global bot allowed languages on http://meta.wikimedia.org/wiki/Bot_policy/Implementation#Current_implementation
        self.cross_allowed = ['cs', 'hu',]
        # CentralAuth cross avaliable projects.
        self.cross_projects = [
            'wikipedia', 'wiktionary', 'wikibooks', 'wikiquote', 'wikisource', 'wikiversity',
            'meta', 'mediawiki', 'test', 'incubator', 'commons', 'species'
        ]

    def code2encoding(self, code):
        return 'utf-8'

    def version(self, code):
        return '1.17wmf1'

    def shared_image_repository(self, code):
        return ('commons', 'commons')
<commit_msg>new site el for wikinews (patch tracker bug #3282069),update from trunk r9155<commit_after># -*- coding: utf-8  -*-
from pywikibot import family

__version__ = '$Id$'

# The Wikimedia family that is known as Wikinews

class Family(family.Family):
    def __init__(self):
        family.Family.__init__(self)
        self.name = 'wikinews'

        self.languages_by_size = [
            'sr', 'en', 'pl', 'de', 'fr', 'it', 'es', 'pt', 'zh', 'ja', 'sv',
            'ru', 'ta', 'fi', 'cs', 'he', 'ro', 'bg', 'ar', 'hu', 'sd', 'fa',
            'tr', 'ca', 'uk', 'sq', 'no', 'bs', 'el', 'th', 'ko', 'eo',
        ]

        for lang in self.languages_by_size:
            self.langs[lang] = '%s.wikinews.org' % lang

        self.obsolete = {
            'jp': 'ja',
            'nb': 'no',
            'nl': None, # https://bugzilla.wikimedia.org/show_bug.cgi?id=20325
            'zh-tw': 'zh',
            'zh-cn': 'zh'
        }

        # Which languages have a special order for putting interlanguage links,
        # and what order is it? If a language is not in interwiki_putfirst,
        # alphabetical order on language code is used. For languages that are in
        # interwiki_putfirst, interwiki_putfirst is checked first, and
        # languages are put in the order given there. All other languages are put
        # after those, in code-alphabetical order.
        self.interwiki_putfirst = {
            'en': self.alphabetic,
            'fi': self.alphabetic,
            'fr': self.alphabetic,
            'he': ['en'],
            'hu': ['en'],
            'pl': self.alphabetic,
        }

        # Global bot allowed languages on http://meta.wikimedia.org/wiki/Bot_policy/Implementation#Current_implementation
        self.cross_allowed = ['cs', 'hu',]
        # CentralAuth cross avaliable projects.
        self.cross_projects = [
            'wikipedia', 'wiktionary', 'wikibooks', 'wikiquote', 'wikisource', 'wikiversity',
            'meta', 'mediawiki', 'test', 'incubator', 'commons', 'species'
        ]

    def code2encoding(self, code):
        return 'utf-8'

    def version(self, code):
        return '1.17wmf1'

    def shared_image_repository(self, code):
        return ('commons', 'commons')
<|endoftext|>


<commit_before>import logging
from pyuia import PageObject, cacheable
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException

__all__ = ['SeleniumPageObject', 'find_by', 'cacheable']
_logger = logging.getLogger(__name__)

class SeleniumPageObject(PageObject):

    def __init__(self, context):
        PageObject.__init__(
            self, context,
            (NoSuchElementException, StaleElementReferenceException))

    @property
    def _driver(self):
        return self._context.driver

    def _is_displayed(self, element):
        try:
            return element.is_displayed()
        except StaleElementReferenceException:
            return False

_strategy_kwargs = ['id_', 'xpath', 'link_text', 'partial_link_text',
                    'name', 'tag_name', 'class_name', 'css_selector']

from pyuia import cacheable as cacheable_decorator # naming conflict between global and parameter names

def find_by(how=None, using=None, multiple=False, cacheable=True, if_exists=False,
            context=None, driver_attr='_driver', max_swipe_times=5, scrollable=None, **kwargs):

    def func(self):

        def swipe(scrollable_view, up=True, swipe_times=1):
            # Get start point
            horizontal_midpoint_of_scrollable_view = scrollable_view.location.get('x') + scrollable_view.size.get('width')*0.5
            vertical_base_of_scrollable_view = scrollable_view.location.get('y')
            vertical_addition_base = scrollable_view.size.get('height')

            if up:
                # Get start point
                start_point_y = vertical_base_of_scrollable_view + vertical_addition_base*0.9
                start = {'x': horizontal_midpoint_of_scrollable_view, 'y': start_point_y}

                # Get end point
                end_point_y = vertical_base_of_scrollable_view + vertical_addition_base*0.1
                end = {'x': horizontal_midpoint_of_scrollable_view, 'y': end_point_y}

            else:
                # Get start point
                start_point_y = vertical_base_of_scrollable_view + vertical_addition_base*0.1
                start = {'x': horizontal_midpoint_of_scrollable_view, 'y': start_point_y}

                # Get end point
                end_point_y = vertical_base_of_scrollable_view + vertical_addition_base*0.9
                end = {'x': horizontal_midpoint_of_scrollable_view, 'y': end_point_y}

            for x in range(swipe_times):
                ctx.swipe(start.get('x'), start.get('y'), end.get('x'), end.get('y'), 1000)

        # context - driver or a certain element
        if callable(context):
            ctx = context(self)
            if not ctx:
                if if_exists:
                    return None
                else:
                    raise NoSuchElementException("The element as the context doesn't exist.")
        else:
            ctx = getattr(self, driver_attr)

        # 'how' AND 'using' take precedence over keyword arguments
        if how and using:
            lookup = ctx.find_elements if multiple else ctx.find_element
            return lookup(how, using)

        if len(kwargs) != 1 or kwargs.keys()[0] not in _strategy_kwargs :
            raise ValueError(
                "If 'how' AND 'using' are not specified, one and only one of the following "
                "valid keyword arguments should be provided: %s." % _strategy_kwargs)

        key = kwargs.keys()[0]; value = kwargs[key]
        suffix = key[:-1] if key.endswith('_') else key # find_element(s)_by_xxx
        prefix = 'find_elements_by' if multiple else 'find_element_by'
        lookup = getattr(ctx, '%s_%s' % (prefix, suffix))

        scrollable_view = scrollable(self) if callable(scrollable) else scrollable

        current_time = 0
        while True:
            try:
                return lookup(value)

            except NoSuchElementException:
                if if_exists: return None
                if current_time==0 and scrollable_view:
                    swipe(scrollable_view, up=False, swipe_times=max_swipe_times)
                else:
                    if current_time > max_swipe_times: raise
                    if scrollable_view:
                        swipe(scrollable_view, up=True)

                current_time+=1

    return cacheable_decorator(func, cache_none=not if_exists) if cacheable else func<commit_msg>Revamp the impl. to support more flexible usages.<commit_after>import logging
from pyuia import PageObject, cacheable
from selenium.common.exceptions import NoSuchElementException, StaleElementReferenceException

__all__ = ['SeleniumPageObject', 'find_by', 'cacheable']
_logger = logging.getLogger(__name__)

class SeleniumPageObject(PageObject):

    def __init__(self, context):
        PageObject.__init__(
            self, context,
            (NoSuchElementException, StaleElementReferenceException))

    @property
    def _driver(self):
        return self._context.driver

    def _is_displayed(self, element):
        try:
            return element.is_displayed()
        except StaleElementReferenceException:
            return False

_strategy_kwargs = ['id_', 'xpath', 'link_text', 'partial_link_text',
                    'name', 'tag_name', 'class_name', 'css_selector']

from pyuia import cacheable as cacheable_decorator # naming conflict between global and parameter names

def find_by(how=None, using=None, multiple=False, cacheable=True, if_exists=False,
            context=None, scrollable=False, scroll_forward=True, scroll_vertically=True,
            scroll_margin=None, maximum_scrolls=5, driver_attr='_driver', **kwargs):
    """Create a callable which can be evaluated lazily to find UI elements.

    This function implements the concept mentioned in Page Factory (or PageFactory) pattern (https://code.google.com/p/selenium/wiki/PageFactory). It helps to reduce the amount of boilerplate code while implementing page objects. For more details, see https://jeremykao.wordpress.com/2015/06/10/pagefactory-pattern-in-python/.

    Args:
        how: Locator strategy. It can be one of the class variables defined in
            `selenium.webdriver.common.by.By`, e.g., `By.ID`, `By.NAME` etc.
        using: The locator.
        multiple: Whether the lookup return multiple elements.
        cacheable: Whether to cache the result.
        if_exists: Whether to return `None` to indicate the element doesn't exist,
            instead of raising an exception.
        context: The starting point of a search, and the scrollable container
            if argument `scrollable` is set to `True` explicitly.
        scrollable: Whether to perform scroll actions if the element is not found.
            Defaults to `False`.
        scroll_forward: Whether to scroll forward or backward. Defaults to `True`.
        scroll_vertically: Whether to scroll vertically or horizontally. Defaults to `True`.
        scroll_margin: No-touch zone. Defaults to `None`.
        maximum_scrolls: The maximum number of attempts to scroll. Defaults to 5.
        driver_attr: The attribute name for getting the reference to WebDriver. Defaults to '_driver'.

    Kwargs:
        The following keyword arguments are supported for various locator strategies: id_ (to avoid conflict with the built-in keyword id), name, class_name, css_selector, tag_name, xpath, link_text, and partial_link_text.

    Returns: A callable which can be evaluated lazily to find UI elements.

    """
    def func(page_object):
        driver = getattr(page_object, driver_attr)

        # ctx - driver or a certain element
        if context is None:
            ctx = driver
            container = None
        elif callable(context):
            container = ctx = context(page_object)
            if not ctx:
                if if_exists:
                    return None
                else:
                    raise NoSuchElementException("The element as the context doesn't exist.")
        else: # element
            container = ctx = context

        # 'how' AND 'using' take precedence over keyword arguments
        if how and using:
            lookup = ctx.find_elements if multiple else ctx.find_element
            return lookup(how, using)

        if len(kwargs) != 1 or kwargs.keys()[0] not in _strategy_kwargs :
            raise ValueError(
                "If 'how' AND 'using' are not specified, one and only one of the following "
                "valid keyword arguments should be provided: %s." % _strategy_kwargs)

        key = kwargs.keys()[0]; value = kwargs[key]
        suffix = key[:-1] if key.endswith('_') else key # find_element(s)_by_xxx
        prefix = 'find_elements_by' if multiple else 'find_element_by'
        lookup = getattr(ctx, '%s_%s' % (prefix, suffix))

        scrolls = 0;
        while True:
            try:
                return lookup(value)
            except NoSuchElementException:
                if not scrollable or scrolls == maximum_scrolls:
                    if if_exists: return None
                    raise

                scroller = _get_scroller(page_object, container, scrollable)
                _scroll(page_object, driver, scroller, scroll_forward, scroll_vertically, scroll_margin)
                scrolls += 1

    return cacheable_decorator(func, cache_none=not if_exists) if cacheable else func

def _get_scroller(page_object, container, scrollable):
    if callable(scrollable): # find_by
        scroller = scrollable(page_object)
        if not scroller:
            raise ValueError("The element as the scrollable container doesn't exist.")
        return scroller
    elif scrollable is True:
        if container is None:
            raise ValueError("The argument 'context' is mandatory if argument 'scrollable' is set to True explicitly.")
        else:
            return container
    else: # element
        return scrollable

def _scroll(page_object, driver, scroller, forward, vertically, margin):
    loc, size = scroller.location, scroller.size
    x, y, w, h = loc['x'], loc['y'], size['width'], size['height']

    if vertically:
        points = [(x + w / 2, y + h - 1), (x + w / 2, y + 1)]
    else:
        points = [(x + w - 1, y + h / 2), (x + 1, y + h / 2)]

    if not forward:
        points.reverse()

    x1, y1 = points[0]
    x2, y2 = points[1]

    # take margin (no-touch zone) into account
    if isinstance(margin, (int, float)):
        if isinstance(margin, float):
            margin = int((h if vertically else w) * margin)

        offset = margin if forward else -margin

        if vertically:
            y1 += offset
        else:
            x1 += offset
    elif margin is not None:
        margin = margin(page_object) if callable(margin) else margin
        if margin is not None:
            loc, size = margin.location, margin.size
            x, y, w, h = loc['x'], loc['y'], size['width'], size['height']

            if vertically:
                y1 = y - 1 if forward else y + h + 1
            else:
                x1 = x - 1 if forward else x + w + 1

    driver.swipe(x1, y1, x2, y2, 2000)

<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

#   Copyright (c) 2010-2016, MIT Probabilistic Computing Project
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

import json
import pytest
import re
import time

from bayeslite import loggers

class StubCallable:
    def __init__(self, sleep=None, throw=None):
        self.calls = []
        self.sleep = sleep
        self.throw = throw
    def __call__(self, *args, **kwargs):
        self.calls.append((args, kwargs))
        if self.sleep:
            time.sleep(self.sleep)
        if self.throw:
            raise self.throw  # pylint: disable=raising-bad-type
            # https://github.com/PyCQA/pylint/issues/157

def test_failstub():
    failstub = StubCallable(throw=NotImplementedError('foo'))
    try:
        failstub('sanity')
        assert False
    except NotImplementedError:
        pass
    assert 1 == len(failstub.calls)
    assert "(('sanity',), {})" == str(failstub.calls[0])

def test_logged_query_no_name():
    stubc = StubCallable()
    lgr = loggers.CallHomeStatusLogger(post=stubc)
    with loggers.logged_query(query_string='q', bindings=('b',), logger=lgr):
        stubc('inside')
    # Just the one call: nothing posted.
    assert "[(('inside',), {})]" == str(stubc.calls)

THE_USUAL = {'query_string': 'q',
             'bindings': ('b',),
             'name': 'test_logged_query_success'}
def check_logcall(logcall):
    assert logcall[0][0].startswith('https://projects.csail.mit.edu/probcomp')
    msg = logcall[1]
    assert 'data' in msg
    msgdata = msg['data']
    assert 'User-Agent' in msgdata
    assert 'session_json' in msgdata
    logdata = json.loads(msgdata['session_json'])
    assert 'entries' in logdata
    assert 'fields' in logdata
    assert 'version' in logdata
    entries = logdata['entries']
    the_only_entry = entries[0]
    assert "test_logged_query_success" == the_only_entry[0]
    assert 'q["b"]' == the_only_entry[2]

def test_logged_query_success():
    query_stub = StubCallable()
    post_stub = StubCallable()
    lgr = loggers.CallHomeStatusLogger(post=post_stub)
    with loggers.logged_query(logger=lgr, **THE_USUAL):
        query_stub('inside')
    assert 1 == len(query_stub.calls)
    assert "(('inside',), {})" == str(query_stub.calls[0])
    time.sleep(0.2)  # To let the call-home thread run, so this is less flaky.
    assert 1 == len(post_stub.calls)
    check_logcall(post_stub.calls[0])

def test_logged_query_successful_log_failure():
    okstub = StubCallable()
    failstub = StubCallable(throw=NotImplementedError('foo'))
    lgr = loggers.CallHomeStatusLogger(post=failstub)
    with loggers.logged_query(logger=lgr, **THE_USUAL):
        okstub('inside')
    assert 1 == len(okstub.calls)
    assert "[(('inside',), {})]" == str(okstub.calls)
    # There will have been a failure on another thread,
    # and it will have been ignored.
    time.sleep(0.2) # To let the call-home thread run, so this is less flaky.
    assert 1 == len(failstub.calls)
    check_logcall(failstub.calls[0])

def test_logged_query_fail():
    failstub = StubCallable(throw=NotImplementedError('foo'))
    okstub = StubCallable()
    lgr = loggers.CallHomeStatusLogger(post=okstub)
    try:
        with loggers.logged_query(logger=lgr, **THE_USUAL):
            failstub('die')
        assert False
    except NotImplementedError:
        pass
    assert 1 == len(okstub.calls)
    check_logcall(okstub.calls[0])

    assert 1 == len(failstub.calls)
    assert "[(('die',), {})]" == str(failstub.calls)

def test_logged_query_reporting_timeout():
    okstub = StubCallable()
    slumbertime = 1
    slowstub = StubCallable(sleep=slumbertime)
    start_time = time.time()
    lgr = loggers.CallHomeStatusLogger(post=slowstub)
    with loggers.logged_query(logger=lgr, **THE_USUAL):
        okstub('inside')
    elapsed_time = time.time() - start_time
    # Success after done.
    assert 1 == len(okstub.calls)
    assert "(('inside',), {})" == str(okstub.calls[0])
    assert elapsed_time < .9 * slumbertime  # Shouldn't even be close.

    # But the call should have registered already:
    assert 1 == len(slowstub.calls)
    check_logcall(slowstub.calls[0])
<commit_msg>Delay all threaded uses until the thread gets a chance to run.<commit_after># -*- coding: utf-8 -*-

#   Copyright (c) 2010-2016, MIT Probabilistic Computing Project
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.

import json
import pytest
import re
import time

from bayeslite import loggers

class StubCallable:
    def __init__(self, sleep=None, throw=None):
        self.calls = []
        self.sleep = sleep
        self.throw = throw
    def __call__(self, *args, **kwargs):
        self.calls.append((args, kwargs))
        if self.sleep:
            time.sleep(self.sleep)
        if self.throw:
            raise self.throw  # pylint: disable=raising-bad-type
            # https://github.com/PyCQA/pylint/issues/157

def test_failstub():
    failstub = StubCallable(throw=NotImplementedError('foo'))
    try:
        failstub('sanity')
        assert False
    except NotImplementedError:
        pass
    assert 1 == len(failstub.calls)
    assert "(('sanity',), {})" == str(failstub.calls[0])

def test_logged_query_no_name():
    stubc = StubCallable()
    lgr = loggers.CallHomeStatusLogger(post=stubc)
    with loggers.logged_query(query_string='q', bindings=('b',), logger=lgr):
        stubc('inside')
    # Just the one call: nothing posted.
    assert "[(('inside',), {})]" == str(stubc.calls)

THE_USUAL = {'query_string': 'q',
             'bindings': ('b',),
             'name': 'test_logged_query_success'}
def check_logcall(logcall):
    assert logcall[0][0].startswith('https://projects.csail.mit.edu/probcomp')
    msg = logcall[1]
    assert 'data' in msg
    msgdata = msg['data']
    assert 'User-Agent' in msgdata
    assert 'session_json' in msgdata
    logdata = json.loads(msgdata['session_json'])
    assert 'entries' in logdata
    assert 'fields' in logdata
    assert 'version' in logdata
    entries = logdata['entries']
    the_only_entry = entries[0]
    assert "test_logged_query_success" == the_only_entry[0]
    assert 'q["b"]' == the_only_entry[2]

def test_logged_query_success():
    query_stub = StubCallable()
    post_stub = StubCallable()
    lgr = loggers.CallHomeStatusLogger(post=post_stub)
    with loggers.logged_query(logger=lgr, **THE_USUAL):
        query_stub('inside')
    assert 1 == len(query_stub.calls)
    assert "(('inside',), {})" == str(query_stub.calls[0])
    time.sleep(0.2)  # To let the call-home thread run, so this is less flaky.
    assert 1 == len(post_stub.calls)
    check_logcall(post_stub.calls[0])

def test_logged_query_successful_log_failure():
    okstub = StubCallable()
    failstub = StubCallable(throw=NotImplementedError('foo'))
    lgr = loggers.CallHomeStatusLogger(post=failstub)
    with loggers.logged_query(logger=lgr, **THE_USUAL):
        okstub('inside')
    assert 1 == len(okstub.calls)
    assert "[(('inside',), {})]" == str(okstub.calls)
    # There will have been a failure on another thread,
    # and it will have been ignored.
    time.sleep(0.2) # To let the call-home thread run, so this is less flaky.
    assert 1 == len(failstub.calls)
    check_logcall(failstub.calls[0])

def test_logged_query_fail():
    failstub = StubCallable(throw=NotImplementedError('foo'))
    okstub = StubCallable()
    lgr = loggers.CallHomeStatusLogger(post=okstub)
    try:
        with loggers.logged_query(logger=lgr, **THE_USUAL):
            failstub('die')
        assert False
    except NotImplementedError:
        pass
    time.sleep(0.2) # To let the call-home thread run, so this is less flaky.
    assert 1 == len(okstub.calls)
    check_logcall(okstub.calls[0])

    assert 1 == len(failstub.calls)
    assert "[(('die',), {})]" == str(failstub.calls)

def test_logged_query_reporting_timeout():
    okstub = StubCallable()
    slumbertime = 1
    slowstub = StubCallable(sleep=slumbertime)
    start_time = time.time()
    lgr = loggers.CallHomeStatusLogger(post=slowstub)
    with loggers.logged_query(logger=lgr, **THE_USUAL):
        okstub('inside')
    elapsed_time = time.time() - start_time
    time.sleep(0.2) # To let the call-home thread run, so this is less flaky.
    # Success after done.
    assert 1 == len(okstub.calls)
    assert "(('inside',), {})" == str(okstub.calls[0])
    assert elapsed_time < .9 * slumbertime  # Shouldn't even be close.

    # But the call should have registered already:
    assert 1 == len(slowstub.calls)
    check_logcall(slowstub.calls[0])
<|endoftext|>


<commit_before># GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
#    Free Software Foundation, Inc.,
#    59 Temple Place,
#    Suite 330,
#    Boston, MA 02111-1307 USA

"Tests for clipboard.py"

__revision__ = "$Revision: 234 $"

import unittest

from pywinauto.clipboard import *
from pywinauto.application import Application
from pywinauto.win32structures import RECT

import time

class ClipboardTestCases(unittest.TestCase):
    "Unit tests for the clipboard"

    def setUp(self):
        """Start the application set some data and ensure the application
        is in the state we want it."""
        self.app1 = Application.start("notepad.exe")
        self.app2 = Application.start("notepad.exe")

        self.app1.UntitledNotepad.MoveWindow(RECT(0, 0, 200, 200))
        self.app2.UntitledNotepad.MoveWindow(RECT(0, 200, 200, 400))

    def tearDown(self):
        "Close the application after tests"
        # close the application
        #self.dlg.SendMessage(win32defines.WM_CLOSE)
        self.app1.UntitledNotepad.MenuSelect('File -> Exit')
        if self.app1.Notepad.No.Exists():
            self.app1.Notepad.No.Click()

        self.app2.UntitledNotepad.MenuSelect('File -> Exit')
        if self.app2.Notepad.No.Exists():
            self.app2.Notepad.No.Click()

    def testGetClipBoardFormats(self):
        typetext(self.app1, "here we are")
        copytext(self.app1)

        self.assertEquals(GetClipboardFormats(), [13, 16, 1, 7])

    def testGetFormatName(self):

        self.assertEquals(
            [GetFormatName(f) for f in GetClipboardFormats()],
            ['CF_UNICODETEXT', 'CF_LOCALE', 'CF_SCREENFONTS', 'CF_OEMTEXT']
        )

    def testBug1452832(self):
        "Failing test for sourceforge bug 1452832"
        self.app1.UntitledNotepad.MenuSelect("Edit -> Select All")
        typetext(self.app1, "some text")
        copytext(self.app1)

        # was not closing the clipboard!
        data = GetData()
        self.assertEquals(data, "some text")

        self.assertEquals(gettext(self.app2), "")
        pastetext(self.app2)
        self.assertEquals(gettext(self.app2), "some text")

def gettext(app):
    return app.UntitledNotepad.Edit.Texts()[1]

def typetext(app, text):
    app.UntitledNotepad.Edit.SetEditText(text)

def copytext(app):
    app.UntitledNotepad.MenuSelect("Edit -> Select All")
    app.UntitledNotepad.MenuSelect("Edit -> Copy")

def pastetext(app):
    app.UntitledNotepad.MenuItem("Edit -> Paste").Click()

if __name__ == "__main__":
    #_unittests()

    unittest.main()

<commit_msg>Added a small bit more information to docstring for bug 1452832 test<commit_after># GUI Application automation and testing library
# Copyright (C) 2006 Mark Mc Mahon
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public License
# as published by the Free Software Foundation; either version 2.1
# of the License, or (at your option) any later version.
#
# This library 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the
#    Free Software Foundation, Inc.,
#    59 Temple Place,
#    Suite 330,
#    Boston, MA 02111-1307 USA

"Tests for clipboard.py"

__revision__ = "$Revision: 234 $"

import unittest

from pywinauto.clipboard import *
from pywinauto.application import Application
from pywinauto.win32structures import RECT

import time

class ClipboardTestCases(unittest.TestCase):
    "Unit tests for the clipboard"

    def setUp(self):
        """Start the application set some data and ensure the application
        is in the state we want it."""
        self.app1 = Application.start("notepad.exe")
        self.app2 = Application.start("notepad.exe")

        self.app1.UntitledNotepad.MoveWindow(RECT(0, 0, 200, 200))
        self.app2.UntitledNotepad.MoveWindow(RECT(0, 200, 200, 400))

    def tearDown(self):
        "Close the application after tests"
        # close the application
        #self.dlg.SendMessage(win32defines.WM_CLOSE)
        self.app1.UntitledNotepad.MenuSelect('File -> Exit')
        if self.app1.Notepad.No.Exists():
            self.app1.Notepad.No.Click()

        self.app2.UntitledNotepad.MenuSelect('File -> Exit')
        if self.app2.Notepad.No.Exists():
            self.app2.Notepad.No.Click()

    def testGetClipBoardFormats(self):
        typetext(self.app1, "here we are")
        copytext(self.app1)

        self.assertEquals(GetClipboardFormats(), [13, 16, 1, 7])

    def testGetFormatName(self):

        self.assertEquals(
            [GetFormatName(f) for f in GetClipboardFormats()],
            ['CF_UNICODETEXT', 'CF_LOCALE', 'CF_SCREENFONTS', 'CF_OEMTEXT']
        )

    def testBug1452832(self):
        """Failing test for sourceforge bug 1452832

        Where GetData was not closing the clipboard. FIXED.
        """
        self.app1.UntitledNotepad.MenuSelect("Edit -> Select All")
        typetext(self.app1, "some text")
        copytext(self.app1)

        # was not closing the clipboard!
        data = GetData()
        self.assertEquals(data, "some text")

        self.assertEquals(gettext(self.app2), "")
        pastetext(self.app2)
        self.assertEquals(gettext(self.app2), "some text")

def gettext(app):
    return app.UntitledNotepad.Edit.Texts()[1]

def typetext(app, text):
    app.UntitledNotepad.Edit.SetEditText(text)

def copytext(app):
    app.UntitledNotepad.MenuSelect("Edit -> Select All")
    app.UntitledNotepad.MenuSelect("Edit -> Copy")

def pastetext(app):
    app.UntitledNotepad.MenuItem("Edit -> Paste").Click()

if __name__ == "__main__":
    #_unittests()

    unittest.main()

<|endoftext|>


<commit_before>import xlrd
from collections import defaultdict
import csv
import cStringIO

"""
XLS-to-dict and csv-to-dict are essentially backends for xls2json.
"""

def xls_value_to_unicode(value, value_type):
    """
    Take a xls formatted value and try to make a unicode string representation.
    """
    if value_type == xlrd.XL_CELL_BOOLEAN:
        return u"TRUE" if value else u"FALSE"
    if value_type == xlrd.XL_CELL_NUMBER:
        #Try to display as an int if possible.
        int_value = int(value)
        if int_value == value:
            return unicode(int_value)
        else:
            return unicode(value)
    else:
        return unicode(value).strip()

def xls_to_dict(path_or_file):
    """
    Return a Python dictionary with a key for each worksheet
    name. For each sheet there is a list of dictionaries, each
    dictionary corresponds to a single row in the worksheet. A
    dictionary has keys taken from the column headers and values
    equal to the cell value for that row and column.
    All the keys and leaf elements are unicode text.
    """
    if isinstance(path_or_file, basestring):
        workbook = xlrd.open_workbook(filename=path_or_file)
    else:
        workbook = xlrd.open_workbook(file_contents=path_or_file.read())

    result = {}
    for sheet in workbook.sheets():
        result[sheet.name] = []
        for row in range(1, sheet.nrows):
            row_dict = {}
            for column in range(0, sheet.ncols):
                #Changing to cell_value function
                key = sheet.cell_value(0, column)#.value
                value = sheet.cell_value(row, column)#.value
                value_type = sheet.cell_type(row, column)
                if value is not None and value != "":
                    row_dict[key] = xls_value_to_unicode(value, value_type)
#            Taking this condition out so I can get accurate row numbers.
#            TODO: Do the same for csvs
#            if row_dict != {}:
            result[sheet.name].append(row_dict)
    return result

def csv_to_dict(path_or_file):
    if isinstance(path_or_file, basestring):
        with open(path_or_file) as f:
            csv_data = f.read()
    else:
        csv_data = path_or_file.read()

    _dict = {}
    def first_column_as_sheet_name(row):
        if len(row) == 0:
            return (None, None)
        elif len(row) == 1:
            return (row[0], None)
        else:
            s_or_c = row[0]
            content = row[1:]
            if s_or_c == '':
                s_or_c = None
            #concatenate all the strings in content
            if reduce(lambda x, y: x+y, content) == '':
                # content is a list of empty strings
                content = None
            return (s_or_c, content)

    reader = csv.reader(csv_data.split("\n"))
    sheet_name = None
    current_headers = None
    for row in reader:
        survey_or_choices, content = first_column_as_sheet_name(row)
        if survey_or_choices != None:
            sheet_name = survey_or_choices
            if sheet_name not in _dict:
                _dict[unicode(sheet_name)] = []
            current_headers = None
        if content != None:
            if current_headers == None:
                current_headers = content
            else:
                _d = {}
                for key, val in zip(current_headers, content):
                    if val != "":
                        #Slight modification so values are striped
                        #this is because csvs often spaces following commas (but the csv reader might already handle that.)
                        _d[unicode(key)] = unicode(val.strip())
                _dict[sheet_name].append(_d)
    return _dict

"""
I want the ability to go:

    xls => csv
so that we can go:
    xls => csv => survey

and some day:
    csv => xls

"""

def convert_file_to_csv_string(path):
    """
    This will open a csv or xls file and return a CSV in the format:
        sheet_name1
        ,col1,col2
        ,r1c1,r1c2
        ,r2c1,r2c2
        sheet_name2
        ,col1,col2
        ,r1c1,r1c2
        ,r2c1,r2c2

    Currently, it processes csv files and xls files to ensure consistent
    csv delimiters, etc. for tests.
    """
    if path.endswith(".csv"):
        imported_sheets = csv_to_dict(path)
    else:
        imported_sheets = xls_to_dict(path)
    foo = cStringIO.StringIO()
    writer = csv.writer(foo, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    for sheet_name, rows in imported_sheets.items():
        writer.writerow([sheet_name])
        out_keys = []
        out_rows = []
        for row in rows:
            out_row = []
            for key in row.keys():
                if key not in out_keys:
                    out_keys.append(key)
            for out_key in out_keys:
                out_row.append(row.get(out_key, None))
            out_rows.append(out_row)
        writer.writerow([None] + out_keys)
        for out_row in out_rows:
            writer.writerow([None] + out_row)
    return foo.getvalue()
<commit_msg>getting ready for parsing cascades differently<commit_after>import xlrd
from collections import defaultdict
import csv
import cStringIO
import constants

"""
XLS-to-dict and csv-to-dict are essentially backends for xls2json.
"""

def xls_value_to_unicode(value, value_type):
    """
    Take a xls formatted value and try to make a unicode string representation.
    """
    if value_type == xlrd.XL_CELL_BOOLEAN:
        return u"TRUE" if value else u"FALSE"
    if value_type == xlrd.XL_CELL_NUMBER:
        #Try to display as an int if possible.
        int_value = int(value)
        if int_value == value:
            return unicode(int_value)
        else:
            return unicode(value)
    else:
        return unicode(value).strip()

def xls_to_dict(path_or_file):
    """
    Return a Python dictionary with a key for each worksheet
    name. For each sheet there is a list of dictionaries, each
    dictionary corresponds to a single row in the worksheet. A
    dictionary has keys taken from the column headers and values
    equal to the cell value for that row and column.
    All the keys and leaf elements are unicode text.
    """
    def xls_to_dict_normal_sheet(sheet):
        result = []
        for row in range(1, sheet.nrows):
            row_dict = {}
            for column in range(0, sheet.ncols):
                #Changing to cell_value function
                key = sheet.cell_value(0, column)#.value
                value = sheet.cell_value(row, column)#.value
                value_type = sheet.cell_type(row, column)
                if value is not None and value != "":
                    row_dict[key] = xls_value_to_unicode(value, value_type)
#            Taking this condition out so I can get accurate row numbers.
#            TODO: Do the same for csvs
#            if row_dict != {}:
            result.append(row_dict)
        return result
    if isinstance(path_or_file, basestring):
        workbook = xlrd.open_workbook(filename=path_or_file)
    else:
        workbook = xlrd.open_workbook(file_contents=path_or_file.read())

    result = {}
    for sheet in workbook.sheets():
        result[sheet.name] = xls_to_dict_normal_sheet(sheet)
    return result

def csv_to_dict(path_or_file):
    if isinstance(path_or_file, basestring):
        with open(path_or_file) as f:
            csv_data = f.read()
    else:
        csv_data = path_or_file.read()

    _dict = {}
    def first_column_as_sheet_name(row):
        if len(row) == 0:
            return (None, None)
        elif len(row) == 1:
            return (row[0], None)
        else:
            s_or_c = row[0]
            content = row[1:]
            if s_or_c == '':
                s_or_c = None
            #concatenate all the strings in content
            if reduce(lambda x, y: x+y, content) == '':
                # content is a list of empty strings
                content = None
            return (s_or_c, content)

    reader = csv.reader(csv_data.split("\n"))
    sheet_name = None
    current_headers = None
    for row in reader:
        survey_or_choices, content = first_column_as_sheet_name(row)
        if survey_or_choices != None:
            sheet_name = survey_or_choices
            if sheet_name not in _dict:
                _dict[unicode(sheet_name)] = []
            current_headers = None
        if content != None:
            if current_headers == None:
                current_headers = content
            else:
                _d = {}
                for key, val in zip(current_headers, content):
                    if val != "":
                        #Slight modification so values are striped
                        #this is because csvs often spaces following commas (but the csv reader might already handle that.)
                        _d[unicode(key)] = unicode(val.strip())
                _dict[sheet_name].append(_d)
    return _dict

"""
I want the ability to go:

    xls => csv
so that we can go:
    xls => csv => survey

and some day:
    csv => xls

"""

def convert_file_to_csv_string(path):
    """
    This will open a csv or xls file and return a CSV in the format:
        sheet_name1
        ,col1,col2
        ,r1c1,r1c2
        ,r2c1,r2c2
        sheet_name2
        ,col1,col2
        ,r1c1,r1c2
        ,r2c1,r2c2

    Currently, it processes csv files and xls files to ensure consistent
    csv delimiters, etc. for tests.
    """
    if path.endswith(".csv"):
        imported_sheets = csv_to_dict(path)
    else:
        imported_sheets = xls_to_dict(path)
    foo = cStringIO.StringIO()
    writer = csv.writer(foo, delimiter=',', quotechar='"', quoting=csv.QUOTE_MINIMAL)
    for sheet_name, rows in imported_sheets.items():
        writer.writerow([sheet_name])
        out_keys = []
        out_rows = []
        for row in rows:
            out_row = []
            for key in row.keys():
                if key not in out_keys:
                    out_keys.append(key)
            for out_key in out_keys:
                out_row.append(row.get(out_key, None))
            out_rows.append(out_row)
        writer.writerow([None] + out_keys)
        for out_row in out_rows:
            writer.writerow([None] + out_row)
    return foo.getvalue()
<|endoftext|>


<commit_before>import re

class ScanMetadataBase:
    """
    This is a base class. Instances of classes should be created from
    a child class, which has meaningful implementation of the ``_gen_default_descriptions``
    and ``_gen_print_order`` functions.
    """

    def __init__(self):

        # This dictionary contains key-value pairs that represent parameter values
        self._values = {}

        # The following dictionary contains key-description pairs, that represent
        #   user-friendly description of each key, that may be used for printing.
        #   It is not assumed that there is one-to-one match for the keys
        #   in 'values' and 'key_description' dictionaries. The 'key_descriptions'
        #   should contain comprehensive list of keys. It is also assumed that
        #   some keys in 'values' dictionary may not have matching descriptions.
        #   'key_descriptions' dictionary set at the different place in the program.
        #   In principle the descriptions may not be set at all.
        self.descriptions = self._gen_default_descriptions()

        self._print_order = self._gen_default_print_order()

    def _gen_default_print_order(self):
        """
        This function must have meaningful implementation in the child class
        """
        return []

    def _gen_default_descriptions(self):
        """
        This function must have meaningful implementation in the child class
        """
        return {}

    # The following methods override standard operators to enable direct access
    #   to ``self.values`` dictionary

    def __getitem__(self, key):
        return self._values[key]

    def __setitem__(self, key, value):
        self._values[key] = value

    def __delitem__(self, key):
        del self._values[key]

    def __contains__(self, key):
        return key in self._values

    def __iter__(self):
        return self._values.__iter__()

    def keys(self):
        return self._values.keys()

    def values(self):
        return self._values.values()

    def get_metadata_dictionary(self):
        """
        Returns reference to metadata dictionary ``self._values``
        """
        return self._values

    def is_metadata_available(self):
        """
        Returns True if at least one metadata key:value pair is available.
        Otherwise returns False.
        """
        return bool(self._values)

    def get_formatted_output(self):
        """
        Returns formatted metadata in the form ready for printing.
        Formatting is performed based on specifications located in ``self._print_order``
        list. Key names are replaced by descriptions from ``self.descriptions`` if
        the available.
        """
        str_out = ""

        printed_keys = set()
        flag_empty_line = False  # Indicates if empty line was just printed

        for ptn in self._gen_default_print_order():
            # We don't want to print multiple empty lines in a row
            if ptn == "" and not flag_empty_line:
                str_out += "\n"
                flag_empty_line = True
                continue

            for key, v in self._values.items():
                if re.search(f"^{ptn}$", key) and (key not in printed_keys):
                    flag_empty_line = False  # Something is getting printed
                    # Mark the entry as printed
                    printed_keys.add(key)
                    # Extracted printable expression for the key
                    s_key = key
                    if key in self.descriptions and self.descriptions[key]:
                        s_key = self.descriptions[key]
                        # Capitalize the first letter
                        s_key = s_key[:1].upper() + s_key[1:]

                    val = v

                    # If the value is a string and it is too long, then add line breaks
                    #   so that it fits the width of a normal sized window
                    if isinstance(val, str):
                        # Now check if 'v' is too long and insert line breaks if needed
                        n_max = 60  # Maximum number of symbols in the line
                        n_gap = len(s_key) + 2  # Size of the left margin
                        s_insert = "\n" + " " * n_gap  # New line and spaces to form a paragraph

                        nc = n_max
                        while True:
                            n = val.find(' ', nc)
                            if n < 0:  # n is -1 if nc > len(val).
                                break  # Exit here if the line is too short as well
                            val = val[:n] + s_insert + val[n+1:]
                            nc += n_max + len(s_insert)

                    # Print the key
                    str_out += f"{s_key}: {val}\n"

        return str_out

class ScanMetadataXRF(ScanMetadataBase):

    def __init__(self):
        super().__init__()

    def _gen_default_print_order(self):
        """
        Generates a list of strings, used to determine printing order of metadata
        The strings in the list are treated as regex strings:
        the symbols ^ and $ are added at the beginning and the end of each string.
        Empty string "" means that the empty string is inserted in the printout.
        The metadata entries are never repeated in the printout, so in each group
        the patterns are specified from more specific to more general.
        """
        print_order = ["scan_id", "scan_uid", "scan_instrument_name",
                       "scan_instrument_id", "scan_time_start", "scan.*"
                       "", "sample_name", "sample.*",
                       "", "proposal_num", "proposal_title", "proposal.*",
                       "", "experiment.*",
                       "", "instrument.*",
                       "", "(?!file).*",
                       "", "file_format", "file_format_version",
                       "file_software", "file_software_version", "file.*"]
        return print_order

    def _gen_default_descriptions(self):
        descriptions = {
            # The descriptions are not capitalized. They can be capitalized
            #   before printing if needed.
            "scan_id": "scan ID",
            "scan_uid": "scan Unique ID",
            "scan_time_start": "start time",
            "scan_time_stop": "stop time",
            "scan_instrument_id": "beamline ID",
            "scan_instrument_name": "beamline name",
            "scan_exit_status": "exit status",

            "instrument_mono_incident_energy": "incident energy",
            "": "beam current",
            "instrument_detectors": "detectors",

            "sample_name": "sample name",

            "experiment_plan_name": "plan name",
            "experiment_plan_type": "plan type",

            "proposal_num": "proposal #",
            "proposal_title": "proposal title",
            "proposal_PI_lastname": "PI last name",
            "proposal_saf_num": "proposal SAF #",
            "proposal_cycle": "cycle",

            "file_created_time": "file creation time",
            "file_format": "file format",
            "file_format_version": "file format version",
            "file_software": "software",
            "file_software_version": "version",
            "file_type": "file type"
        }

        return descriptions

    def is_mono_incident_energy_available(self):
        """
        Returns True if data on monochromator incident energy is available.
        Otherwise returns False
        """
        return "instrument_mono_incident_energy" in self._values

    def get_mono_incident_energy(self):
        """
        Returns the value of the incident energy. Incident energy is an important
        parameter used in processing, so a separate function is created to fetch it.
        """
        return self._values['instrument_mono_incident_energy']<commit_msg>Fix: loading of metadata from databroker to GUI<commit_after>import re

class ScanMetadataBase:
    """
    This is a base class. Instances of classes should be created from
    a child class, which has meaningful implementation of the ``_gen_default_descriptions``
    and ``_gen_print_order`` functions.
    """

    def __init__(self):

        # This dictionary contains key-value pairs that represent parameter values
        self._values = {}

        # The following dictionary contains key-description pairs, that represent
        #   user-friendly description of each key, that may be used for printing.
        #   It is not assumed that there is one-to-one match for the keys
        #   in 'values' and 'key_description' dictionaries. The 'key_descriptions'
        #   should contain comprehensive list of keys. It is also assumed that
        #   some keys in 'values' dictionary may not have matching descriptions.
        #   'key_descriptions' dictionary set at the different place in the program.
        #   In principle the descriptions may not be set at all.
        self.descriptions = self._gen_default_descriptions()

        self._print_order = self._gen_default_print_order()

    def _gen_default_print_order(self):
        """
        This function must have meaningful implementation in the child class
        """
        return []

    def _gen_default_descriptions(self):
        """
        This function must have meaningful implementation in the child class
        """
        return {}

    # The following methods override standard operators to enable direct access
    #   to ``self.values`` dictionary

    def __getitem__(self, key):
        return self._values[key]

    def __setitem__(self, key, value):
        self._values[key] = value

    def __delitem__(self, key):
        del self._values[key]

    def __contains__(self, key):
        return key in self._values

    def __iter__(self):
        return self._values.__iter__()

    def keys(self):
        return self._values.keys()

    def values(self):
        return self._values.values()

    def items(self):
        return self._values.items()

    def get_metadata_dictionary(self):
        """
        Returns reference to metadata dictionary ``self._values``
        """
        return self._values

    def is_metadata_available(self):
        """
        Returns True if at least one metadata key:value pair is available.
        Otherwise returns False.
        """
        return bool(self._values)

    def get_formatted_output(self):
        """
        Returns formatted metadata in the form ready for printing.
        Formatting is performed based on specifications located in ``self._print_order``
        list. Key names are replaced by descriptions from ``self.descriptions`` if
        the available.
        """
        str_out = ""

        printed_keys = set()
        flag_empty_line = False  # Indicates if empty line was just printed

        for ptn in self._gen_default_print_order():
            # We don't want to print multiple empty lines in a row
            if ptn == "" and not flag_empty_line:
                str_out += "\n"
                flag_empty_line = True
                continue

            for key, v in self._values.items():
                if re.search(f"^{ptn}$", key) and (key not in printed_keys):
                    flag_empty_line = False  # Something is getting printed
                    # Mark the entry as printed
                    printed_keys.add(key)
                    # Extracted printable expression for the key
                    s_key = key
                    if key in self.descriptions and self.descriptions[key]:
                        s_key = self.descriptions[key]
                        # Capitalize the first letter
                        s_key = s_key[:1].upper() + s_key[1:]

                    val = v

                    # If the value is a string and it is too long, then add line breaks
                    #   so that it fits the width of a normal sized window
                    if isinstance(val, str):
                        # Now check if 'v' is too long and insert line breaks if needed
                        n_max = 60  # Maximum number of symbols in the line
                        n_gap = len(s_key) + 2  # Size of the left margin
                        s_insert = "\n" + " " * n_gap  # New line and spaces to form a paragraph

                        nc = n_max
                        while True:
                            n = val.find(' ', nc)
                            if n < 0:  # n is -1 if nc > len(val).
                                break  # Exit here if the line is too short as well
                            val = val[:n] + s_insert + val[n+1:]
                            nc += n_max + len(s_insert)

                    # Print the key
                    str_out += f"{s_key}: {val}\n"

        return str_out

class ScanMetadataXRF(ScanMetadataBase):

    def __init__(self):
        super().__init__()

    def _gen_default_print_order(self):
        """
        Generates a list of strings, used to determine printing order of metadata
        The strings in the list are treated as regex strings:
        the symbols ^ and $ are added at the beginning and the end of each string.
        Empty string "" means that the empty string is inserted in the printout.
        The metadata entries are never repeated in the printout, so in each group
        the patterns are specified from more specific to more general.
        """
        print_order = ["scan_id", "scan_uid", "scan_instrument_name",
                       "scan_instrument_id", "scan_time_start",
                       "scan_time_stop", "scan.*"
                       "", "sample_name", "sample.*",
                       "", "proposal_num", "proposal_title", "proposal.*",
                       "", "experiment.*",
                       "", "instrument.*",
                       "", "(?!file).*",
                       "", "file_format", "file_format_version",
                       "file_software", "file_software_version", "file.*"]
        return print_order

    def _gen_default_descriptions(self):
        descriptions = {
            # The descriptions are not capitalized. They can be capitalized
            #   before printing if needed.
            "scan_id": "scan ID",
            "scan_uid": "scan Unique ID",
            "scan_time_start": "start time",
            "scan_time_stop": "stop time",
            "scan_instrument_id": "beamline ID",
            "scan_instrument_name": "beamline name",
            "scan_exit_status": "exit status",

            "instrument_mono_incident_energy": "incident energy",
            "instrument_beam_current": "beam current",
            "instrument_detectors": "detectors",

            "sample_name": "sample name",

            "experiment_plan_name": "plan name",
            "experiment_plan_type": "plan type",

            "proposal_num": "proposal #",
            "proposal_title": "proposal title",
            "proposal_PI_lastname": "PI last name",
            "proposal_saf_num": "proposal SAF #",
            "proposal_cycle": "cycle",

            "file_created_time": "file creation time",
            "file_format": "file format",
            "file_format_version": "file format version",
            "file_software": "software",
            "file_software_version": "version",
            "file_type": "file type"
        }

        return descriptions

    def is_mono_incident_energy_available(self):
        """
        Returns True if data on monochromator incident energy is available.
        Otherwise returns False
        """
        return "instrument_mono_incident_energy" in self._values

    def get_mono_incident_energy(self):
        """
        Returns the value of the incident energy. Incident energy is an important
        parameter used in processing, so a separate function is created to fetch it.
        """
        return self._values['instrument_mono_incident_energy']<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

"""Main test script."""

from django.test import TestCase

import meerkat

class MainTestCase(TestCase):
    """Main Django test case."""

    def setUp(self):
        """Setup method."""
        pass

    def test_main(self):
        """Main test method."""
        assert meerkat

    def tearDown(self):
        """Tear down method."""
        pass
<commit_msg>Remove blank line<commit_after># -*- coding: utf-8 -*-

"""Main test script."""

from django.test import TestCase

import meerkat

class MainTestCase(TestCase):
    """Main Django test case."""

    def setUp(self):
        """Setup method."""
        pass

    def test_main(self):
        """Main test method."""
        assert meerkat

    def tearDown(self):
        """Tear down method."""
        pass
<|endoftext|>