<commit_before>"""
I/O functions: reading and writing molecules.
"""

__author__ = "Steven Kearnes"
__copyright__ = "Copyright 2014, Stanford University"
__license__ = "3-clause BSD"

import cPickle
import gzip
import numpy as np
import os
import warnings

from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem.SaltRemover import SaltRemover

class MolIO(object):
    """
    Base class for molecule I/O.

    Parameters
    ----------
    f : file-like, optional
        File-like object.
    mol_format : str, optional
        Molecule file format. Currently supports 'sdf', 'smi', and 'pkl'.
    """
    def __init__(self, f=None, mol_format=None):
        self.f = f
        self.mol_format = mol_format

        # placeholder
        self.filename = None

    def __del__(self):
        self.close()

    def __enter__(self):
        """
        Context manager entrance. Returns this object so it can be closed
        after finishing the 'with' block.
        """
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        Context manager exit. Closes any open file handles.

        Parameters
        ----------
        exc_type : class
            Exception class that caused the context to exit.
        exc_val : object
            Exception that caused the context to exit.
        exc_tb : traceback
            Exception traceback.

        Note that all arguments will be None on successful completion of
        the context. See https://docs.python.org/2/reference/datamodel.html
        #context-managers for more information. Any exception will be
        raised as normal after this method is finished (since it does not
        return True).
        """
        self.close()

    def open(self, filename, mol_format=None, mode='rb'):
        """
        Open a file for reading or writing.

        Parameters
        ----------
        filename : str
            Filename.
        mol_format : str, optional
            Molecule file format. Currently supports 'sdf', 'smi', and
            'pkl'. If not provided, the format is inferred from the
            filename.
        mode : str, optional (default 'rb')
            Mode used to open file.
        """
        self.filename = filename
        if filename.endswith('.gz'):
            self.f = gzip.open(filename, mode)
        else:
            self.f = open(filename, mode)
        if mol_format is not None:
            self.mol_format = mol_format
        else:
            self.mol_format = self.guess_mol_format(filename)
        return self

    def close(self):
        """
        Close output file (only if it was opened by this object).
        """
        if self.f is not None and self.filename is not None:
            self.f.close()

        # cleanup
        self.filename = None

    def guess_mol_format(self, filename):
        """
        Guess molecule file format from filename.

        Parameters
        ----------
        filename : str
            Filename.
        """

        # strip gzip suffix
        if filename.endswith('.gz'):
            filename = os.path.splitext(filename)[0]

        # guess format from extension
        if filename.endswith('.sdf'):
            mol_format = 'sdf'
        elif filename.endswith(('.smi', '.can', '.ism')):
            mol_format = 'smi'
        elif filename.endswith('.pkl'):
            mol_format = 'pkl'
        else:
            raise NotImplementedError('Unrecognized file format.')
        return mol_format

class MolReader(MolIO):
    """
    Read molecules from files and file-like objects. Supports SDF, SMILES,
    and RDKit binary format (via pickle).

    Parameters
    ----------
    f : file, optional
        File-like object.
    mol_format : str, optional
        Molecule file format. Currently supports 'sdf', 'smi', and 'pkl'.
    remove_hydrogens : bool, optional (default False)
        Remove hydrogens from molecules.
    remove_salts : bool, optional (default False)
        Remove salts from molecules. Note that this will remove any hydrogens
        present on the molecule.
    compute_2d_coords : bool, optional (default True)
        Compute 2D coordinates when reading SMILES. If molecules are written to
        SDF without 2D coordinates, stereochemistry information will be lost.
    """
    def __init__(self, f=None, mol_format=None, remove_hydrogens=False,
                 remove_salts=False, compute_2d_coords=True):
        if not remove_hydrogens and remove_salts:
            warnings.warn('remove_salts=True forcing remove_hydrogens=True')
            remove_hydrogens = True
        super(MolReader, self).__init__(f, mol_format)
        self.remove_hydrogens = remove_hydrogens
        self.remove_salts = remove_salts
        if remove_salts:
            self.salt_remover = SaltRemover()
        self.compute_2d_coords = compute_2d_coords

    def __iter__(self):
        """
        Iterate over molecules.
        """
        return self.get_mols()

    def get_mols(self):
        """
        Read molecules from a file-like object.

        Molecule conformers are grouped into a single molecule. Two
        molecules are considered conformers of the same molecule if they:
        * Are contiguous in the file
        * Have identical (canonical isomeric) SMILES strings
        * Have identical compound names (if set)

        Returns
        -------
        A generator yielding (possibly multi-conformer) RDKit Mol objects.
        """
        parent = None
        for mol in self._get_mols():
            if parent is None:
                parent = mol
                continue
            if self.are_same_molecule(parent, mol):
                if mol.GetNumConformers():
                    for conf in mol.GetConformers():
                        parent.AddConformer(conf, assignId=True)
                else:
                    continue  # skip duplicate molecules without conformers
            else:
                parent = self.clean_mol(parent)
                yield parent
                parent = mol
        if parent is not None:
            parent = self.clean_mol(parent)
            yield parent

    def _get_mols(self):
        """
        Read molecules from a file-like object.

        This method returns individual conformers from a file and does not
        attempt to combine them into multiconformer Mol objects.

        Returns
        -------
        A generator yielding RDKit Mol objects.
        """
        if self.mol_format == 'sdf':
            mols = self._get_mols_from_sdf()
        elif self.mol_format == 'smi':
            mols = self._get_mols_from_smiles()
        elif self.mol_format == 'pkl':
            mols = self._get_mols_from_pickle()
        else:
            raise NotImplementedError('Unrecognized molecule format ' +
                                      '"{}"'.format(self.mol_format))

        # skip read errors
        while True:
            try:
                mol = mols.next()
            except StopIteration:
                break
            except Exception:
                warnings.warn('Skipping molecule.')
                continue
            else:
                if mol is not None:
                    yield mol

    def _get_mols_from_sdf(self):
        """
        Read SDF molecules from a file-like object.
        """
        supplier = Chem.ForwardSDMolSupplier(self.f,
                                             removeHs=self.remove_hydrogens)
        for mol in supplier:
            yield mol

    def _get_mols_from_smiles(self):
        """
        Read SMILES molecules from a file-like object.
        """
        for line in self.f.readlines():
            line = line.strip()
            if not line:
                continue
            split_line = line.split()
            if len(split_line) > 1:
                smiles, name = split_line
            else:
                smiles, = split_line
                name = None

            # hydrogens are removed by default, which triggers sanitization
            try:
                if self.remove_hydrogens:
                    mol = Chem.MolFromSmiles(smiles)
                else:
                    mol = Chem.MolFromSmiles(smiles, sanitize=False)
                    Chem.SanitizeMol(mol)

                if self.compute_2d_coords:
                    AllChem.Compute2DCoords(mol)
            except Exception:
                warnings.warn('Skipping ' + line)
                continue
            else:
                if name is not None:
                    mol.SetProp('_Name', name)
                yield mol

    def _get_mols_from_pickle(self):
        """
        Read pickled molecules from a file-like object.

        Files that contain multiple pickles are supported by repeated calls
        to load.
        """
        while True:
            try:
                mols = cPickle.load(self.f)
                for mol in np.atleast_1d(mols):
                    yield mol
            except EOFError:
                break

    def are_same_molecule(self, a, b):
        """
        Test whether two molecules are conformers of the same molecule.

        Test for:
        * Identical (canonical isomeric) SMILES strings
        * Identical compound names (if set)

        Parameters
        ----------
        a, b : RDKit Mol
            Molecules to compare.
        """

        # get names, if available
        a_name = self._get_name(a)
        b_name = self._get_name(b)

        # get canonical isomeric SMILES
        a_smiles = self._get_isomeric_smiles(a)
        b_smiles = self._get_isomeric_smiles(b)
        assert a_smiles and b_smiles

        # test for same molecule
        return a_smiles == b_smiles and a_name == b_name

    def _get_name(self, mol):
        """
        Get molecule name, if available.

        Parameters
        ----------
        mol : RDKit Mol
            Molecule.
        """
        if mol.HasProp('_Name'):
            return mol.GetProp('_Name')
        else:
            return None

    def _get_isomeric_smiles(self, mol):
        """
        Get canonical isomeric SMILES for a molecule. Also sets the
        isomericSmiles property to avoid recomputing.

        Note that stereochemistry is not assigned from 3D coordinates; it
        must be explicitly present in the file or it will not show up in
        the SMILES conversion.

        Parameters
        ----------
        mol : RDKit Mol
            Molecule.
        """
        if mol.HasProp('isomericSmiles'):
            return mol.GetProp('isomericSmiles')
        else:
            smiles = Chem.MolToSmiles(mol, isomericSmiles=True, canonical=True)
            mol.SetProp('isomericSmiles', smiles, computed=True)
            return smiles

    def clean_mol(self, mol):
        """
        Clean a molecule.

        Parameters
        ----------
        mol : RDKit Mol
            Molecule.
        """
        if self.remove_salts:
            # hydrogens must be removed for pattern matching to work properly
            new = self.salt_remover.StripMol(Chem.RemoveHs(mol))
            if new.GetNumAtoms():
                mol = new  # the molecule may _be_ a salt
        return mol

class MolWriter(MolIO):
    """
    Write molecules to files or file-like objects. Supports SDF, SMILES,
    and RDKit binary format (via pickle).

    Parameters
    ----------
    f : file, optional
        File-like object.
    mol_format : str, optional
        Molecule file format. Currently supports 'sdf', 'smi', and 'pkl'.
    stereo : bool, optional (default True)
        Whether to preserve stereochemistry in output.
    """
    def __init__(self, f=None, mol_format=None, stereo=True):
        super(MolWriter, self).__init__(f, mol_format)
        self.stereo = stereo

    def open(self, filename, mol_format=None, mode='wb'):
        """
        Open output file.

        Parameters
        ----------
        filename : str
            Filename.
        mol_format : str, optional
            Molecule file format. Currently supports 'sdf', 'smi', and
            'pkl'. If not provided, the format is inferred from the
            filename.
        mode : str, optional (default 'wb')
            Mode used to open file.
        """
        return super(MolWriter, self).open(filename, mol_format, mode)

    def write(self, mols):
        """
        Write molecules to a file-like object.

        Parameters
        ----------
        mols : iterable
            Molecules to write.
        """
        if self.mol_format == 'sdf':
            self._write_sdf(mols)
        elif self.mol_format == 'smi':
            self._write_smiles(mols)
        elif self.mol_format == 'pkl':
            self._write_pickle(mols)
        self.f.flush()  # flush changes

    def _write_sdf(self, mols):
        """
        Write molecules in SDF format.

        Parameters
        ----------
        mols : iterable
            Molecules to write.
        """
        w = Chem.SDWriter(self.f)
        for mol in mols:
            if not self.stereo:
                mol = Chem.Mol(mol)  # create a copy
                Chem.RemoveStereochemistry(mol)
            if mol.GetNumConformers():
                for conf in mol.GetConformers():
                    w.write(mol, confId=conf.GetId())
            else:
                w.write(mol)
        w.close()

    def _write_smiles(self, mols):
        """
        Write molecules in SMILES format.

        Parameters
        ----------
        mols : iterable
            Molecules to write.
        """
        for mol in mols:
            smiles = Chem.MolToSmiles(mol, isomericSmiles=self.stereo,
                                      canonical=True)
            self.f.write(smiles)
            if mol.HasProp('_Name'):
                name = mol.GetProp('_Name')
                self.f.write('\t' + name)
            self.f.write('\n')

    def _write_pickle(self, mols):
        """
        Write molecules to a pickle.

        Parameters
        ----------
        mols : iterable
            Molecules to write.
        """
        cPickle.dump(mols, self.f, cPickle.HIGHEST_PROTOCOL)
<commit_msg>Remove hydrogens and salts by default<commit_after>"""
I/O functions: reading and writing molecules.
"""

__author__ = "Steven Kearnes"
__copyright__ = "Copyright 2014, Stanford University"
__license__ = "3-clause BSD"

import cPickle
import gzip
import numpy as np
import os
import warnings

from rdkit import Chem
from rdkit.Chem import AllChem
from rdkit.Chem.SaltRemover import SaltRemover

class MolIO(object):
    """
    Base class for molecule I/O.

    Parameters
    ----------
    f : file-like, optional
        File-like object.
    mol_format : str, optional
        Molecule file format. Currently supports 'sdf', 'smi', and 'pkl'.
    """
    def __init__(self, f=None, mol_format=None):
        self.f = f
        self.mol_format = mol_format

        # placeholder
        self.filename = None

    def __del__(self):
        self.close()

    def __enter__(self):
        """
        Context manager entrance. Returns this object so it can be closed
        after finishing the 'with' block.
        """
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        """
        Context manager exit. Closes any open file handles.

        Parameters
        ----------
        exc_type : class
            Exception class that caused the context to exit.
        exc_val : object
            Exception that caused the context to exit.
        exc_tb : traceback
            Exception traceback.

        Note that all arguments will be None on successful completion of
        the context. See https://docs.python.org/2/reference/datamodel.html
        #context-managers for more information. Any exception will be
        raised as normal after this method is finished (since it does not
        return True).
        """
        self.close()

    def open(self, filename, mol_format=None, mode='rb'):
        """
        Open a file for reading or writing.

        Parameters
        ----------
        filename : str
            Filename.
        mol_format : str, optional
            Molecule file format. Currently supports 'sdf', 'smi', and
            'pkl'. If not provided, the format is inferred from the
            filename.
        mode : str, optional (default 'rb')
            Mode used to open file.
        """
        self.filename = filename
        if filename.endswith('.gz'):
            self.f = gzip.open(filename, mode)
        else:
            self.f = open(filename, mode)
        if mol_format is not None:
            self.mol_format = mol_format
        else:
            self.mol_format = self.guess_mol_format(filename)
        return self

    def close(self):
        """
        Close output file (only if it was opened by this object).
        """
        if self.f is not None and self.filename is not None:
            self.f.close()

        # cleanup
        self.filename = None

    def guess_mol_format(self, filename):
        """
        Guess molecule file format from filename.

        Parameters
        ----------
        filename : str
            Filename.
        """

        # strip gzip suffix
        if filename.endswith('.gz'):
            filename = os.path.splitext(filename)[0]

        # guess format from extension
        if filename.endswith('.sdf'):
            mol_format = 'sdf'
        elif filename.endswith(('.smi', '.can', '.ism')):
            mol_format = 'smi'
        elif filename.endswith('.pkl'):
            mol_format = 'pkl'
        else:
            raise NotImplementedError('Unrecognized file format.')
        return mol_format

class MolReader(MolIO):
    """
    Read molecules from files and file-like objects. Supports SDF, SMILES,
    and RDKit binary format (via pickle).

    Parameters
    ----------
    f : file, optional
        File-like object.
    mol_format : str, optional
        Molecule file format. Currently supports 'sdf', 'smi', and 'pkl'.
    remove_hydrogens : bool, optional (default True)
        Remove hydrogens from molecules.
    remove_salts : bool, optional (default True)
        Remove salts from molecules. Note that this will remove any hydrogens
        present on the molecule.
    compute_2d_coords : bool, optional (default True)
        Compute 2D coordinates when reading SMILES. If molecules are written to
        SDF without 2D coordinates, stereochemistry information will be lost.
    """
    def __init__(self, f=None, mol_format=None, remove_hydrogens=True,
                 remove_salts=True, compute_2d_coords=True):
        if not remove_hydrogens and remove_salts:
            warnings.warn('Compounds with salts will have hydrogens removed')
        super(MolReader, self).__init__(f, mol_format)
        self.remove_hydrogens = remove_hydrogens
        self.remove_salts = remove_salts
        if remove_salts:
            self.salt_remover = SaltRemover()
        self.compute_2d_coords = compute_2d_coords

    def __iter__(self):
        """
        Iterate over molecules.
        """
        return self.get_mols()

    def get_mols(self):
        """
        Read molecules from a file-like object.

        Molecule conformers are grouped into a single molecule. Two
        molecules are considered conformers of the same molecule if they:
        * Are contiguous in the file
        * Have identical (canonical isomeric) SMILES strings
        * Have identical compound names (if set)

        Returns
        -------
        A generator yielding (possibly multi-conformer) RDKit Mol objects.
        """
        parent = None
        for mol in self._get_mols():
            if parent is None:
                parent = mol
                continue
            if self.are_same_molecule(parent, mol):
                if mol.GetNumConformers():
                    for conf in mol.GetConformers():
                        parent.AddConformer(conf, assignId=True)
                else:
                    continue  # skip duplicate molecules without conformers
            else:
                parent = self.clean_mol(parent)
                yield parent
                parent = mol
        if parent is not None:
            parent = self.clean_mol(parent)
            yield parent

    def _get_mols(self):
        """
        Read molecules from a file-like object.

        This method returns individual conformers from a file and does not
        attempt to combine them into multiconformer Mol objects.

        Returns
        -------
        A generator yielding RDKit Mol objects.
        """
        if self.mol_format == 'sdf':
            mols = self._get_mols_from_sdf()
        elif self.mol_format == 'smi':
            mols = self._get_mols_from_smiles()
        elif self.mol_format == 'pkl':
            mols = self._get_mols_from_pickle()
        else:
            raise NotImplementedError('Unrecognized molecule format ' +
                                      '"{}"'.format(self.mol_format))

        # skip read errors
        while True:
            try:
                mol = mols.next()
            except StopIteration:
                break
            except Exception:
                warnings.warn('Skipping molecule.')
                continue
            else:
                if mol is not None:
                    yield mol

    def _get_mols_from_sdf(self):
        """
        Read SDF molecules from a file-like object.
        """
        supplier = Chem.ForwardSDMolSupplier(self.f,
                                             removeHs=self.remove_hydrogens)
        for mol in supplier:
            yield mol

    def _get_mols_from_smiles(self):
        """
        Read SMILES molecules from a file-like object.
        """
        for line in self.f.readlines():
            line = line.strip()
            if not line:
                continue
            split_line = line.split()
            if len(split_line) > 1:
                smiles, name = split_line
            else:
                smiles, = split_line
                name = None

            # hydrogens are removed by default, which triggers sanitization
            try:
                if self.remove_hydrogens:
                    mol = Chem.MolFromSmiles(smiles)
                else:
                    mol = Chem.MolFromSmiles(smiles, sanitize=False)
                    Chem.SanitizeMol(mol)

                if self.compute_2d_coords:
                    AllChem.Compute2DCoords(mol)
            except Exception:
                warnings.warn('Skipping ' + line)
                continue
            else:
                if name is not None:
                    mol.SetProp('_Name', name)
                yield mol

    def _get_mols_from_pickle(self):
        """
        Read pickled molecules from a file-like object.

        Files that contain multiple pickles are supported by repeated calls
        to load.
        """
        while True:
            try:
                mols = cPickle.load(self.f)
                for mol in np.atleast_1d(mols):
                    yield mol
            except EOFError:
                break

    def are_same_molecule(self, a, b):
        """
        Test whether two molecules are conformers of the same molecule.

        Test for:
        * Identical (canonical isomeric) SMILES strings
        * Identical compound names (if set)

        Parameters
        ----------
        a, b : RDKit Mol
            Molecules to compare.
        """

        # get names, if available
        a_name = self._get_name(a)
        b_name = self._get_name(b)

        # get canonical isomeric SMILES
        a_smiles = self._get_isomeric_smiles(a)
        b_smiles = self._get_isomeric_smiles(b)
        assert a_smiles and b_smiles

        # test for same molecule
        return a_smiles == b_smiles and a_name == b_name

    def _get_name(self, mol):
        """
        Get molecule name, if available.

        Parameters
        ----------
        mol : RDKit Mol
            Molecule.
        """
        if mol.HasProp('_Name'):
            return mol.GetProp('_Name')
        else:
            return None

    def _get_isomeric_smiles(self, mol):
        """
        Get canonical isomeric SMILES for a molecule. Also sets the
        isomericSmiles property to avoid recomputing.

        Note that stereochemistry is not assigned from 3D coordinates; it
        must be explicitly present in the file or it will not show up in
        the SMILES conversion.

        Parameters
        ----------
        mol : RDKit Mol
            Molecule.
        """
        if mol.HasProp('isomericSmiles'):
            return mol.GetProp('isomericSmiles')
        else:
            smiles = Chem.MolToSmiles(mol, isomericSmiles=True, canonical=True)
            mol.SetProp('isomericSmiles', smiles, computed=True)
            return smiles

    def clean_mol(self, mol):
        """
        Clean a molecule.

        Parameters
        ----------
        mol : RDKit Mol
            Molecule.
        """
        if self.remove_salts:
            # hydrogens must be removed for pattern matching to work properly
            new = self.salt_remover.StripMol(Chem.RemoveHs(mol))
            if new.GetNumAtoms():
                mol = new  # the molecule may _be_ a salt
        return mol

class MolWriter(MolIO):
    """
    Write molecules to files or file-like objects. Supports SDF, SMILES,
    and RDKit binary format (via pickle).

    Parameters
    ----------
    f : file, optional
        File-like object.
    mol_format : str, optional
        Molecule file format. Currently supports 'sdf', 'smi', and 'pkl'.
    stereo : bool, optional (default True)
        Whether to preserve stereochemistry in output.
    """
    def __init__(self, f=None, mol_format=None, stereo=True):
        super(MolWriter, self).__init__(f, mol_format)
        self.stereo = stereo

    def open(self, filename, mol_format=None, mode='wb'):
        """
        Open output file.

        Parameters
        ----------
        filename : str
            Filename.
        mol_format : str, optional
            Molecule file format. Currently supports 'sdf', 'smi', and
            'pkl'. If not provided, the format is inferred from the
            filename.
        mode : str, optional (default 'wb')
            Mode used to open file.
        """
        return super(MolWriter, self).open(filename, mol_format, mode)

    def write(self, mols):
        """
        Write molecules to a file-like object.

        Parameters
        ----------
        mols : iterable
            Molecules to write.
        """
        if self.mol_format == 'sdf':
            self._write_sdf(mols)
        elif self.mol_format == 'smi':
            self._write_smiles(mols)
        elif self.mol_format == 'pkl':
            self._write_pickle(mols)
        self.f.flush()  # flush changes

    def _write_sdf(self, mols):
        """
        Write molecules in SDF format.

        Parameters
        ----------
        mols : iterable
            Molecules to write.
        """
        w = Chem.SDWriter(self.f)
        for mol in mols:
            if not self.stereo:
                mol = Chem.Mol(mol)  # create a copy
                Chem.RemoveStereochemistry(mol)
            if mol.GetNumConformers():
                for conf in mol.GetConformers():
                    w.write(mol, confId=conf.GetId())
            else:
                w.write(mol)
        w.close()

    def _write_smiles(self, mols):
        """
        Write molecules in SMILES format.

        Parameters
        ----------
        mols : iterable
            Molecules to write.
        """
        for mol in mols:
            smiles = Chem.MolToSmiles(mol, isomericSmiles=self.stereo,
                                      canonical=True)
            self.f.write(smiles)
            if mol.HasProp('_Name'):
                name = mol.GetProp('_Name')
                self.f.write('\t' + name)
            self.f.write('\n')

    def _write_pickle(self, mols):
        """
        Write molecules to a pickle.

        Parameters
        ----------
        mols : iterable
            Molecules to write.
        """
        cPickle.dump(mols, self.f, cPickle.HIGHEST_PROTOCOL)
<|endoftext|>


<commit_before># Copyright (c) 2015 Nicolas JOUANIN
#
# See the file license.txt for copying permission.
import unittest
import asyncio
import logging
from hbmqtt.plugins.manager import PluginManager
from hbmqtt.broker import Broker
from hbmqtt.mqtt.constants import *

formatter = "[%(asctime)s] %(name)s {%(filename)s:%(lineno)d} %(levelname)s - %(message)s"
logging.basicConfig(level=logging.DEBUG, format=formatter)
log = logging.getLogger(__name__)

class BrokerTest(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)
        self.plugin_manager = PluginManager("hbmqtt.test.plugins", context=None, loop=self.loop)

    def tearDown(self):
        self.loop.close()

    def test_start_stop(self):
        config = {
            'listeners': {
                'default': {
                    'type': 'tcp'
                },
                'tcp-mqtt': {
                    'bind': '0.0.0.0:1883',
                    'max_connections': 10
                },
            },
            'sys_interval': 0,
            'auth': {
                'allow-anonymous': True,
            }
        }

        def test_coro():
            broker = Broker(config)
            yield from broker.start()
            yield from broker.shutdown()

        self.loop.run_until_complete(test_coro())
<commit_msg>Add plugin calls assertions on broker start/shutdown<commit_after># Copyright (c) 2015 Nicolas JOUANIN
#
# See the file license.txt for copying permission.
import unittest
from unittest.mock import patch, call
import asyncio
import logging
from hbmqtt.broker import *
from hbmqtt.mqtt.constants import *

formatter = "[%(asctime)s] %(name)s {%(filename)s:%(lineno)d} %(levelname)s - %(message)s"
logging.basicConfig(level=logging.DEBUG, format=formatter)
log = logging.getLogger(__name__)

class BrokerTest(unittest.TestCase):
    def setUp(self):
        self.loop = asyncio.new_event_loop()
        asyncio.set_event_loop(self.loop)

    def tearDown(self):
        self.loop.close()

    @patch('hbmqtt.broker.PluginManager')
    def test_start_stop(self, MockPluginManager):
        config = {
            'listeners': {
                'default': {
                    'type': 'tcp',
                    'bind': '0.0.0.0:1883',
                    'max_connections': 10
                },
            },
            'sys_interval': 0,
            'auth': {
                'allow-anonymous': True,
            }
        }

        def test_coro():
            try:
                broker = Broker(config, plugin_namespace="hbmqtt.test.plugins")
                yield from broker.start()
                self.assertTrue(broker.transitions.is_started())
                self.assertIn('default', broker._servers)
                MockPluginManager.assert_has_calls(
                    [call().fire_event(EVENT_BROKER_PRE_START),
                     call().fire_event(EVENT_BROKER_POST_START)], any_order=True)
                MockPluginManager.reset_mock()
                yield from broker.shutdown()
                MockPluginManager.assert_has_calls(
                    [call().fire_event(EVENT_BROKER_PRE_SHUTDOWN),
                     call().fire_event(EVENT_BROKER_POST_SHUTDOWN)], any_order=True)
                self.assertTrue(broker.transitions.is_stopped())
                future.set_result(True)
            except Exception as ae:
                future.set_exception(ae)

        future = asyncio.Future(loop=self.loop)
        self.loop.run_until_complete(test_coro())
        if future.exception():
            raise future.exception()
<|endoftext|>


<commit_before># coding: utf-8
'''
Test pitools.camera module
'''
from __future__ import unicode_literals
import io
import imghdr
import unittest
import tempfile
import shutil

from flask import Flask
from pitools import camera

app = Flask(__name__)
app.register_blueprint(camera.blueprint)

class CameraTestCase(unittest.TestCase):

    def setUp(self):
        self.workspace = tempfile.mkdtemp()
        self.app = app.test_client()

    def tearDown(self):
        shutil.rmtree(self.workspace)

    def test_post_shot_api(self):
        '''
        Should fail with 405 with GET request
        '''
        rv = self.app.post('/camera/shot')
        assert 405 == rv.status_code

    def test_get_shot_api(self):
        '''
        Should return a image with MIME of image/*
        '''
        rv = self.app.get('/camera/shot')
        assert rv.content_type.startswith('image/')
        print dir(rv)
        with io.BytesIO() as photo:
            photo.write(rv.get_data())
            photo.flush()
            photo.seek(0)
            assert len(photo.read()) > 0
            photo.seek(0)
            assert 'jpeg' == imghdr.what('', photo.read())

if __name__ == '__main__':
    unittest.main()
<commit_msg>Add test for camera.setup_camera<commit_after># coding: utf-8
'''
Test pitools.camera module
'''
from __future__ import unicode_literals
import io
import imghdr
import unittest

from flask import Flask
from pitools import camera
from picamera import PiCamera

app = Flask(__name__)
app.register_blueprint(camera.blueprint)

class CameraTestCase(unittest.TestCase):

    def setUp(self):
        self.app = app.test_client()

    def tearDown(self):
        pass

    def test_setup_camera(self):
        '''
        setup_camera() shoud return an opened PiCamera instance
        '''
        with camera.setup_camera() as c:
            assert isinstance(camera.setup_camera(), PiCamera)
            assert not c.closed

    def test_post_shot_api(self):
        '''
        Should fail with 405 with GET request
        '''
        rv = self.app.post('/camera/shot')
        assert 405 == rv.status_code

    def test_get_shot_api(self):
        '''
        Should return a image with MIME of image/*
        '''
        rv = self.app.get('/camera/shot')
        assert rv.content_type.startswith('image/')
        print dir(rv)
        with io.BytesIO() as photo:
            photo.write(rv.get_data())
            photo.flush()
            photo.seek(0)
            assert len(photo.read()) > 0
            photo.seek(0)
            assert 'jpeg' == imghdr.what('', photo.read())

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
"""
    Basic CLexer Test
    ~~~~~~~~~~~~~~~~~

    :copyright: Copyright 2006-2015 by the Pygments team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

import unittest
import os
import textwrap

from pygments.token import Text, Number, Token
from pygments.lexers import CLexer

class CLexerTest(unittest.TestCase):

    def setUp(self):
        self.lexer = CLexer()

    def testNumbers(self):
        code = '42 23.42 23. .42 023 0xdeadbeef 23e+42 42e-23'
        wanted = []
        for item in zip([Number.Integer, Number.Float, Number.Float,
                         Number.Float, Number.Oct, Number.Hex,
                         Number.Float, Number.Float], code.split()):
            wanted.append(item)
            wanted.append((Text, ' '))
        wanted = wanted[:-1] + [(Text, '\n')]
        self.assertEqual(list(self.lexer.get_tokens(code)), wanted)

    def testSwitch(self):
        fragment = u'''\
        int main()
        {
            switch (0)
            {
                case 0:
                default:
                    ;
            }
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Keyword, u'switch'),
            (Token.Text, u' '),
            (Token.Punctuation, u'('),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Text, u'        '),
            (Token.Keyword, u'case'),
            (Token.Text, u' '),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Operator, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'        '),
            (Token.Keyword, u'default'),
            (Token.Operator, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'            '),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))

    def testSwitchSpaceBeforeColon(self):
        fragment = u'''\
        int main()
        {
            switch (0)
            {
                case 0 :
                default :
                    ;
            }
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Keyword, u'switch'),
            (Token.Text, u' '),
            (Token.Punctuation, u'('),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Text, u'        '),
            (Token.Keyword, u'case'),
            (Token.Text, u' '),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Text, u' '),
            (Token.Operator, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'        '),
            (Token.Keyword, u'default'),
            (Token.Text, u' '),
            (Token.Operator, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'            '),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))

    def testLabel(self):
        fragment = u'''\
        int main()
        {
        foo:
          goto foo;
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Name.Label, u'foo'),
            (Token.Punctuation, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'  '),
            (Token.Keyword, u'goto'),
            (Token.Text, u' '),
            (Token.Name, u'foo'),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))

    def testLabelSpaceBeforeColon(self):
        fragment = u'''\
        int main()
        {
        foo :
          goto foo;
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Name.Label, u'foo'),
            (Token.Text, u' '),
            (Token.Punctuation, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'  '),
            (Token.Keyword, u'goto'),
            (Token.Text, u' '),
            (Token.Name, u'foo'),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))

    def testLabelFollowedByStatement(self):
        fragment = u'''\
        int main()
        {
        foo:return 0;
          goto foo;
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Name.Label, u'foo'),
            (Token.Punctuation, u':'),
            (Token.Keyword, u'return'),
            (Token.Text, u' '),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Text, u'  '),
            (Token.Keyword, u'goto'),
            (Token.Text, u' '),
            (Token.Name, u'foo'),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))
<commit_msg>Add tests for c/cpp includes<commit_after># -*- coding: utf-8 -*-
"""
    Basic CLexer Test
    ~~~~~~~~~~~~~~~~~

    :copyright: Copyright 2006-2015 by the Pygments team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

import unittest
import os
import textwrap

from pygments.token import Text, Number, Token
from pygments.lexers import CLexer

class CLexerTest(unittest.TestCase):

    def setUp(self):
        self.lexer = CLexer()

    def testNumbers(self):
        code = '42 23.42 23. .42 023 0xdeadbeef 23e+42 42e-23'
        wanted = []
        for item in zip([Number.Integer, Number.Float, Number.Float,
                         Number.Float, Number.Oct, Number.Hex,
                         Number.Float, Number.Float], code.split()):
            wanted.append(item)
            wanted.append((Text, ' '))
        wanted = wanted[:-1] + [(Text, '\n')]
        self.assertEqual(list(self.lexer.get_tokens(code)), wanted)

    def testSwitch(self):
        fragment = u'''\
        int main()
        {
            switch (0)
            {
                case 0:
                default:
                    ;
            }
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Keyword, u'switch'),
            (Token.Text, u' '),
            (Token.Punctuation, u'('),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Text, u'        '),
            (Token.Keyword, u'case'),
            (Token.Text, u' '),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Operator, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'        '),
            (Token.Keyword, u'default'),
            (Token.Operator, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'            '),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))

    def testSwitchSpaceBeforeColon(self):
        fragment = u'''\
        int main()
        {
            switch (0)
            {
                case 0 :
                default :
                    ;
            }
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Keyword, u'switch'),
            (Token.Text, u' '),
            (Token.Punctuation, u'('),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Text, u'        '),
            (Token.Keyword, u'case'),
            (Token.Text, u' '),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Text, u' '),
            (Token.Operator, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'        '),
            (Token.Keyword, u'default'),
            (Token.Text, u' '),
            (Token.Operator, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'            '),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Text, u'    '),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))

    def testLabel(self):
        fragment = u'''\
        int main()
        {
        foo:
          goto foo;
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Name.Label, u'foo'),
            (Token.Punctuation, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'  '),
            (Token.Keyword, u'goto'),
            (Token.Text, u' '),
            (Token.Name, u'foo'),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))

    def testLabelSpaceBeforeColon(self):
        fragment = u'''\
        int main()
        {
        foo :
          goto foo;
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Name.Label, u'foo'),
            (Token.Text, u' '),
            (Token.Punctuation, u':'),
            (Token.Text, u'\n'),
            (Token.Text, u'  '),
            (Token.Keyword, u'goto'),
            (Token.Text, u' '),
            (Token.Name, u'foo'),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))

    def testLabelFollowedByStatement(self):
        fragment = u'''\
        int main()
        {
        foo:return 0;
          goto foo;
        }
        '''
        tokens = [
            (Token.Keyword.Type, u'int'),
            (Token.Text, u' '),
            (Token.Name.Function, u'main'),
            (Token.Punctuation, u'('),
            (Token.Punctuation, u')'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'{'),
            (Token.Text, u'\n'),
            (Token.Name.Label, u'foo'),
            (Token.Punctuation, u':'),
            (Token.Keyword, u'return'),
            (Token.Text, u' '),
            (Token.Literal.Number.Integer, u'0'),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Text, u'  '),
            (Token.Keyword, u'goto'),
            (Token.Text, u' '),
            (Token.Name, u'foo'),
            (Token.Punctuation, u';'),
            (Token.Text, u'\n'),
            (Token.Punctuation, u'}'),
            (Token.Text, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(textwrap.dedent(fragment))))

    def testPreprocFile(self):
        fragment = u'#include <foo>\n'
        tokens = [
            (Token.Comment.Preproc, u'#'),
            (Token.Comment.Preproc, u'include'),
            (Token.Text, u' '),
            (Token.Comment.PreprocFile, u'<foo>'),
            (Token.Comment.Preproc, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))

    def testPreprocFile2(self):
        fragment = u'#include "foo.h"\n'
        tokens = [
            (Token.Comment.Preproc, u'#'),
            (Token.Comment.Preproc, u'include'),
            (Token.Text, u' '),
            (Token.Comment.PreprocFile, u'"foo.h"'),
            (Token.Comment.Preproc, u'\n'),
        ]
        self.assertEqual(tokens, list(self.lexer.get_tokens(fragment)))

<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function

import sys
import uuid

if sys.version_info[:2] < (2, 7):
    import unittest2 as unittest
else:
    import unittest

from laterpay.compat import urlparse, parse_qs
from laterpay import (
    APIException,
    InvalidItemDefinition,
    ItemDefinition,
    LaterPayClient,
)

class TestItemDefinition(unittest.TestCase):

    def test_item_definition(self):
        with self.assertRaises(InvalidItemDefinition):
            ItemDefinition(1, '', '', '', 'title')
        with self.assertRaises(InvalidItemDefinition):
            ItemDefinition(1, 'EUR20', '', '', 'title')
        with self.assertRaises(InvalidItemDefinition):
            ItemDefinition(1, 'EUR20', 'DE19.0.123.44', '', 'title')
        with self.assertRaises(InvalidItemDefinition):
            ItemDefinition(1, 'EUR20', 'DE19.0', 'http://foo.invalid', 'title', expiry="illegal123")

class TestLaterPayClient(unittest.TestCase):

    def setUp(self):
        self.lp = LaterPayClient(
            1,
            'some-secret')

    def get_qs_dict(self, url):
        o = urlparse(url)
        d = parse_qs(o.query)
        o = urlparse(d['url'][0])
        d = parse_qs(o.query)
        return d

    def assertQueryString(self, url, key, value=None):
        d = self.get_qs_dict(url)
        if not value:
            return (key in d)
        return d.get(key, None) == value

    def test_transaction_reference(self):

        item = ItemDefinition(1, 'EUR20', 'DE19.0', 'http://foo.invalid', 'title')

        _u = str(uuid.uuid4())

        url = self.lp.get_add_url(
            item,
            product_key=123,
            dialog=True,
            use_jsevents=True,
            transaction_reference=_u)

        self.assertQueryString(url, 'tref', value=_u)

        url = self.lp.get_add_url(
            item,
            product_key=123,
            dialog=True,
            use_jsevents=True)

        d = self.get_qs_dict(url)
        self.assertFalse('tref' in d)

        with self.assertRaises(APIException):

            self.lp.get_add_url(
                item,
                product_key=123,
                dialog=True,
                use_jsevents=True,
                transaction_reference='123')

    def test_get_web_url_has_no_none_params(self):
        # item with expiry not set.
        item = ItemDefinition(1, 'EUR20', 'DE19.0', 'http://help.me/', 'title')
        url = self.lp.get_add_url(item)
        self.assertFalse(
            'expiry%3DNone' in url,
            'expiry url param is "None". Should be omitted.',
        )

if __name__ == '__main__':
    unittest.main()
<commit_msg>fixing tests<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import absolute_import, print_function

import sys
import uuid

if sys.version_info[:2] < (2, 7):
    import unittest2 as unittest
else:
    import unittest

from laterpay.compat import urlparse, parse_qs
from laterpay import (
    APIException,
    InvalidItemDefinition,
    ItemDefinition,
    LaterPayClient,
)

class TestItemDefinition(unittest.TestCase):

    def test_item_definition(self):
        with self.assertRaises(InvalidItemDefinition):
            ItemDefinition(1, '', '', 'title')
        with self.assertRaises(InvalidItemDefinition):
            ItemDefinition(1, 'EUR20', '', 'title')
        with self.assertRaises(InvalidItemDefinition):
            ItemDefinition(1, 'EUR20', '', 'title')
        with self.assertRaises(InvalidItemDefinition):
            ItemDefinition(1, 'EUR20', 'http://foo.invalid', 'title', expiry="illegal123")

class TestLaterPayClient(unittest.TestCase):

    def setUp(self):
        self.lp = LaterPayClient(
            1,
            'some-secret')

    def get_qs_dict(self, url):
        o = urlparse(url)
        d = parse_qs(o.query)
        o = urlparse(d['url'][0])
        d = parse_qs(o.query)
        return d

    def assertQueryString(self, url, key, value=None):
        d = self.get_qs_dict(url)
        if not value:
            return (key in d)
        return d.get(key, None) == value

    def test_transaction_reference(self):

        item = ItemDefinition(1, 'EUR20', 'http://foo.invalid', 'title')

        _u = str(uuid.uuid4())

        url = self.lp.get_add_url(
            item,
            product_key=123,
            dialog=True,
            use_jsevents=True,
            transaction_reference=_u)

        self.assertQueryString(url, 'tref', value=_u)

        url = self.lp.get_add_url(
            item,
            product_key=123,
            dialog=True,
            use_jsevents=True)

        d = self.get_qs_dict(url)
        self.assertFalse('tref' in d)

        with self.assertRaises(APIException):

            self.lp.get_add_url(
                item,
                product_key=123,
                dialog=True,
                use_jsevents=True,
                transaction_reference='123')

    def test_get_web_url_has_no_none_params(self):
        # item with expiry not set.
        item = ItemDefinition(1, 'EUR20', 'http://help.me/', 'title')
        url = self.lp.get_add_url(item)
        self.assertFalse(
            'expiry%3DNone' in url,
            'expiry url param is "None". Should be omitted.',
        )

if __name__ == '__main__':
    unittest.main()
<|endoftext|>


<commit_before>import copy
import json
import zipfile

import pytest
import requests_mock
import six
from requests.models import Request

from databasin.client import Client
from databasin.exceptions import DatasetImportError

try:
    from unittest import mock  # Py3
except ImportError:
    import mock  # Py2

try:
    import __builtin__ as builtins
except ImportError:
    import builtins

LOGIN_URL = 'https://databasin.org/auth/login_iframe/'

@pytest.fixture()
def dataset_import_data():
    return {
        'id': 'a1b2c3',
        'owner_id': 'user',
        'private': False,
        'title': 'Some Import',
        'description': 'This dataset is a dataset.',
        'create_date': '2015-11-17T22:42:06+00:00',
        'modify_date': '2015-11-17T22:42:06+00:00',
        'native': True,
        'tags': ['one', 'two'],
        'credits': None,
        'failed': False,
        'is_dataset_edit': False
    }

@pytest.fixture()
def dataset_data():
    return {
        'id': 'a1b2c3',
        'owner_id': 'user',
        'private': False,
        'title': 'Some Dataset',
        'snippet': 'This dataset is...',
        'create_date': '2015-11-17T22:42:06+00:00',
        'modify_date': '2015-11-17T22:42:06+00:00',
        'native': True,
        'tags': ['one', 'two'],
        'credits': None
    }

@pytest.fixture
def import_job_data():
    return {
        'id': '1234',
        'job_name': 'create_import_job',
        'status': 'succeeded',
        'progress': 100,
        'message': json.dumps({'next_uri': '/datasets/a1b2c3'})
    }

@pytest.fixture
def tmp_file_data():
    return {
        'uuid': 'abcd',
        'date': '2015-11-17T22:42:06+00:00',
        'is_image': False,
        'filename': '',
        'url': 'http://example.com/file.txt'
    }

def test_alternative_host():
    c = Client('example.com:81')

    assert c.base_url == 'http://example.com:81'
    assert c.base_url_https == 'https://example.com:81'

def test_https_referer():
    """Django requires all POST requests via HTTPS to have the Referer header set."""

    c = Client()
    r = c._session.prepare_request(Request('POST', LOGIN_URL))
    c._session.get_adapter(LOGIN_URL).add_headers(r)

    assert r.headers['Referer'] == LOGIN_URL

def test_login():
    with requests_mock.mock() as m:
        m.get(LOGIN_URL, cookies={'csrftoken': 'abcd'})
        m.post(LOGIN_URL, cookies={'sessionid': 'asdf'})

        c = Client()
        c.login('foo', 'bar')

        assert m.call_count == 2

def test_login_no_redirect():
    with requests_mock.mock() as m:
        m.get('http://databasin.org/')
        m.get(LOGIN_URL, cookies={'csrftoken': 'abcd'})
        m.post(
            LOGIN_URL, headers={'Location': 'http://databasin.org/'}, cookies={'sessionid': 'asdf'}, status_code=302
        )

        c = Client()
        c.login('foo', 'bar')

        assert m.call_count == 2
        assert not any(r.url for r in m.request_history if r.url == 'http://databasin.org/')

def test_import_netcdf_dataset_with_zip(import_job_data, dataset_data, tmp_file_data):
    with requests_mock.mock() as m:
        m.post('http://databasin.org/uploads/upload-temporary-file/', text=json.dumps({'uuid': 'abcd'}))
        m.get('http://databasin.org/api/v1/uploads/temporary-files/abcd/', text=json.dumps(tmp_file_data))
        m.post('http://databasin.org/api/v1/jobs/', headers={'Location': 'http://databasin.org/api/v1/jobs/1234/'})
        m.get('http://databasin.org/api/v1/jobs/1234/', text=json.dumps(import_job_data))
        m.get('http://databasin.org/api/v1/datasets/a1b2c3/', text=json.dumps(dataset_data))

        with six.BytesIO() as f:
            with zipfile.ZipFile(f, 'w') as zf:
                zf.writestr('test.nc', '')
                zf.writestr('style.json', '')
            f.seek(0)

            with mock.patch.object(builtins, 'open', mock.Mock(return_value=f)) as open_mock:
                c = Client()
                c._session.cookies['csrftoken'] = 'abcd'
                dataset = c.import_netcdf_dataset('test.zip')

                open_mock.assert_called_once_with('test.zip', 'a+b')
                assert m.call_count == 5
                assert dataset.id == 'a1b2c3'
                request_data = json.loads(m.request_history[2].text)
                assert request_data['job_name'] == 'create_import_job'
                assert request_data['job_args']['file'] == 'abcd'
                assert request_data['job_args']['dataset_type'] == 'NetCDF_Native'

def test_import_netcdf_dataset_with_nc(import_job_data, dataset_data, tmp_file_data):
    with requests_mock.mock() as m:
        m.post('http://databasin.org/uploads/upload-temporary-file/', text=json.dumps({'uuid': 'abcd'}))
        m.get('http://databasin.org/api/v1/uploads/temporary-files/abcd/', text=json.dumps(tmp_file_data))
        m.post('http://databasin.org/api/v1/jobs/', headers={'Location': 'http://databasin.org/api/v1/jobs/1234/'})
        m.get('http://databasin.org/api/v1/jobs/1234/', text=json.dumps(import_job_data))
        m.get('http://databasin.org/api/v1/datasets/a1b2c3/', text=json.dumps(dataset_data))

        with mock.patch.object(zipfile, 'ZipFile', mock.MagicMock()) as zf_mock:
            c = Client()
            c._session.cookies['csrftoken'] = 'abcd'
            dataset = c.import_netcdf_dataset('test.nc', style={'foo': 'bar'})

            zf_mock().write.assert_called_once_with('test.nc', 'test.nc')
            assert m.call_count == 5
            assert dataset.id == 'a1b2c3'
            request_data = json.loads(m.request_history[2].text)
            assert request_data['job_name'] == 'create_import_job'
            assert request_data['job_args']['file'] == 'abcd'
            assert request_data['job_args']['dataset_type'] == 'NetCDF_Native'

def test_import_netcdf_dataset_with_invalid_file():
    c = Client()
    with pytest.raises(ValueError):
        c.import_netcdf_dataset('test.foo')

def test_import_netcdf_dataset_with_no_style():
    with six.BytesIO() as f:
        with zipfile.ZipFile(f, 'w') as zf:
            zf.writestr('test.nc', '')
        f.seek(0)

        with mock.patch.object(builtins, 'open', mock.Mock(return_value=f)) as open_mock:
            c = Client()
            c._session.cookies['csrftoken'] = 'abcd'

            with pytest.raises(ValueError):
                c.import_netcdf_dataset('test.zip')

def test_import_netcdf_dataset_incomplete(import_job_data, tmp_file_data, dataset_import_data):
    import_job_data = copy.copy(import_job_data)
    import_job_data['message'] = json.dumps({'next_uri': '/datasets/import/a1b2c3/overview/'})

    with requests_mock.mock() as m:
        m.post('http://databasin.org/uploads/upload-temporary-file/', text=json.dumps({'uuid': 'abcd'}))
        m.get('http://databasin.org/api/v1/uploads/temporary-files/abcd/', text=json.dumps(tmp_file_data))
        m.post('http://databasin.org/api/v1/jobs/', headers={'Location': 'http://databasin.org/api/v1/jobs/1234/'})
        m.get('http://databasin.org/api/v1/jobs/1234/', text=json.dumps(import_job_data))
        m.get('http://databasin.org/api/v1/dataset_imports/a1b2c3/', text=json.dumps(dataset_import_data))
        m.delete('http://databasin.org/api/v1/dataset_imports/a1b2c3/')

        with six.BytesIO() as f:
            with zipfile.ZipFile(f, 'w') as zf:
                zf.writestr('test.nc', '')
                zf.writestr('style.json', '')
            f.seek(0)

            with mock.patch.object(builtins, 'open', mock.Mock(return_value=f)) as open_mock:
                c = Client()
                c._session.cookies['csrftoken'] = 'abcd'

                with pytest.raises(DatasetImportError):
                    c.import_netcdf_dataset('test.zip')

                assert m.call_count == 6
<commit_msg>Fix Py2 tests.<commit_after>import copy
import json
import zipfile

import pytest
import requests_mock
import six
from requests.models import Request

from databasin.client import Client
from databasin.exceptions import DatasetImportError

try:
    from unittest import mock  # Py3
except ImportError:
    import mock  # Py2

try:
    import __builtin__ as builtins
except ImportError:
    import builtins

LOGIN_URL = 'https://databasin.org/auth/login_iframe/'

@pytest.fixture()
def dataset_import_data():
    return {
        'id': 'a1b2c3',
        'owner_id': 'user',
        'private': False,
        'title': 'Some Import',
        'description': 'This dataset is a dataset.',
        'create_date': '2015-11-17T22:42:06+00:00',
        'modify_date': '2015-11-17T22:42:06+00:00',
        'native': True,
        'tags': ['one', 'two'],
        'credits': None,
        'failed': False,
        'is_dataset_edit': False
    }

@pytest.fixture()
def dataset_data():
    return {
        'id': 'a1b2c3',
        'owner_id': 'user',
        'private': False,
        'title': 'Some Dataset',
        'snippet': 'This dataset is...',
        'create_date': '2015-11-17T22:42:06+00:00',
        'modify_date': '2015-11-17T22:42:06+00:00',
        'native': True,
        'tags': ['one', 'two'],
        'credits': None
    }

@pytest.fixture
def import_job_data():
    return {
        'id': '1234',
        'job_name': 'create_import_job',
        'status': 'succeeded',
        'progress': 100,
        'message': json.dumps({'next_uri': '/datasets/a1b2c3'})
    }

@pytest.fixture
def tmp_file_data():
    return {
        'uuid': 'abcd',
        'date': '2015-11-17T22:42:06+00:00',
        'is_image': False,
        'filename': '',
        'url': 'http://example.com/file.txt'
    }

def test_alternative_host():
    c = Client('example.com:81')

    assert c.base_url == 'http://example.com:81'
    assert c.base_url_https == 'https://example.com:81'

def test_https_referer():
    """Django requires all POST requests via HTTPS to have the Referer header set."""

    c = Client()
    r = c._session.prepare_request(Request('POST', LOGIN_URL))
    c._session.get_adapter(LOGIN_URL).add_headers(r)

    assert r.headers['Referer'] == LOGIN_URL

def test_login():
    with requests_mock.mock() as m:
        m.get(LOGIN_URL, cookies={'csrftoken': 'abcd'})
        m.post(LOGIN_URL, cookies={'sessionid': 'asdf'})

        c = Client()
        c.login('foo', 'bar')

        assert m.call_count == 2

def test_login_no_redirect():
    with requests_mock.mock() as m:
        m.get('http://databasin.org/')
        m.get(LOGIN_URL, cookies={'csrftoken': 'abcd'})
        m.post(
            LOGIN_URL, headers={'Location': 'http://databasin.org/'}, cookies={'sessionid': 'asdf'}, status_code=302
        )

        c = Client()
        c.login('foo', 'bar')

        assert m.call_count == 2
        assert not any(r.url for r in m.request_history if r.url == 'http://databasin.org/')

def test_import_netcdf_dataset_with_zip(import_job_data, dataset_data, tmp_file_data):
    with requests_mock.mock() as m:
        m.post('http://databasin.org/uploads/upload-temporary-file/', text=json.dumps({'uuid': 'abcd'}))
        m.get('http://databasin.org/api/v1/uploads/temporary-files/abcd/', text=json.dumps(tmp_file_data))
        m.post('http://databasin.org/api/v1/jobs/', headers={'Location': 'http://databasin.org/api/v1/jobs/1234/'})
        m.get('http://databasin.org/api/v1/jobs/1234/', text=json.dumps(import_job_data))
        m.get('http://databasin.org/api/v1/datasets/a1b2c3/', text=json.dumps(dataset_data))

        f = six.BytesIO()
        with zipfile.ZipFile(f, 'w') as zf:
            zf.writestr('test.nc', '')
            zf.writestr('style.json', '')
        f.seek(0)

        with mock.patch.object(builtins, 'open', mock.Mock(return_value=f)) as open_mock:
            c = Client()
            c._session.cookies['csrftoken'] = 'abcd'
            dataset = c.import_netcdf_dataset('test.zip')

            open_mock.assert_called_once_with('test.zip', 'a+b')
            assert m.call_count == 5
            assert dataset.id == 'a1b2c3'
            request_data = json.loads(m.request_history[2].text)
            assert request_data['job_name'] == 'create_import_job'
            assert request_data['job_args']['file'] == 'abcd'
            assert request_data['job_args']['dataset_type'] == 'NetCDF_Native'

def test_import_netcdf_dataset_with_nc(import_job_data, dataset_data, tmp_file_data):
    with requests_mock.mock() as m:
        m.post('http://databasin.org/uploads/upload-temporary-file/', text=json.dumps({'uuid': 'abcd'}))
        m.get('http://databasin.org/api/v1/uploads/temporary-files/abcd/', text=json.dumps(tmp_file_data))
        m.post('http://databasin.org/api/v1/jobs/', headers={'Location': 'http://databasin.org/api/v1/jobs/1234/'})
        m.get('http://databasin.org/api/v1/jobs/1234/', text=json.dumps(import_job_data))
        m.get('http://databasin.org/api/v1/datasets/a1b2c3/', text=json.dumps(dataset_data))

        with mock.patch.object(zipfile, 'ZipFile', mock.MagicMock()) as zf_mock:
            c = Client()
            c._session.cookies['csrftoken'] = 'abcd'
            dataset = c.import_netcdf_dataset('test.nc', style={'foo': 'bar'})

            zf_mock().write.assert_called_once_with('test.nc', 'test.nc')
            assert m.call_count == 5
            assert dataset.id == 'a1b2c3'
            request_data = json.loads(m.request_history[2].text)
            assert request_data['job_name'] == 'create_import_job'
            assert request_data['job_args']['file'] == 'abcd'
            assert request_data['job_args']['dataset_type'] == 'NetCDF_Native'

def test_import_netcdf_dataset_with_invalid_file():
    c = Client()
    with pytest.raises(ValueError):
        c.import_netcdf_dataset('test.foo')

def test_import_netcdf_dataset_with_no_style():
    f = six.BytesIO()
    with zipfile.ZipFile(f, 'w') as zf:
        zf.writestr('test.nc', '')
    f.seek(0)

    with mock.patch.object(builtins, 'open', mock.Mock(return_value=f)) as open_mock:
        c = Client()
        c._session.cookies['csrftoken'] = 'abcd'

        with pytest.raises(ValueError):
            c.import_netcdf_dataset('test.zip')

def test_import_netcdf_dataset_incomplete(import_job_data, tmp_file_data, dataset_import_data):
    import_job_data = copy.copy(import_job_data)
    import_job_data['message'] = json.dumps({'next_uri': '/datasets/import/a1b2c3/overview/'})

    with requests_mock.mock() as m:
        m.post('http://databasin.org/uploads/upload-temporary-file/', text=json.dumps({'uuid': 'abcd'}))
        m.get('http://databasin.org/api/v1/uploads/temporary-files/abcd/', text=json.dumps(tmp_file_data))
        m.post('http://databasin.org/api/v1/jobs/', headers={'Location': 'http://databasin.org/api/v1/jobs/1234/'})
        m.get('http://databasin.org/api/v1/jobs/1234/', text=json.dumps(import_job_data))
        m.get('http://databasin.org/api/v1/dataset_imports/a1b2c3/', text=json.dumps(dataset_import_data))
        m.delete('http://databasin.org/api/v1/dataset_imports/a1b2c3/')

        f = six.BytesIO()
        with zipfile.ZipFile(f, 'w') as zf:
            zf.writestr('test.nc', '')
            zf.writestr('style.json', '')
        f.seek(0)

        with mock.patch.object(builtins, 'open', mock.Mock(return_value=f)) as open_mock:
            c = Client()
            c._session.cookies['csrftoken'] = 'abcd'

            with pytest.raises(DatasetImportError):
                c.import_netcdf_dataset('test.zip')

            assert m.call_count == 6
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Version module
"""
# pragma: no cover
__version__ = '0.5.1.dev0'
<commit_msg>Preparing release 0.6.0<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Version module
"""
# pragma: no cover
__version__ = '0.6.0'
<|endoftext|>


<commit_before>import pytest
from misuzu import Misuzu
from misuzu.config import *
from misuzu.utils import *

def test_get_env(tmpdir):
    app = Misuzu("test")
    t = tmpdir.mkdir("sub").join("config.toml")
    t.write("home = 'ENV::HOME::STR'")
    app.config.load(t)
    p = os.environ.get("HOME")
    assert app.config['home'] == p

def test_nested_dict(tmpdir):
    app = Misuzu("test")
    t = tmpdir.mkdir("sub").join("config.toml")
    t.write("[a]\naa = 1\n[a.b]\nbb = 2")
    app.config.load(t)
    p = {
        'a': {'aa': 1, 'b': {'bb': 2}}
    }
    assert app.config == p

def test_no_env(tmpdir):
    app = Misuzu("test")
    t = tmpdir.mkdir("sub").join("config.toml")
    t.write("home = 'ENV::HOMES::STR::/'")
    app.config.load(t)
    assert app.config['home'] == "/"

def test_no_type(tmpdir):
    with pytest.raises(ConfigException):
        app = Misuzu("test")
        t = tmpdir.mkdir("sub").join("config.toml")
        t.write("home = 'ENV::HOME::SSS::/'")
        app.config.load(t)

def test_no_capitalized(tmpdir):
    with pytest.raises(ConfigException):
        app = Misuzu("test")
        t = tmpdir.mkdir("sub").join("config.toml")
        t.write("home = 'ENV::Home::STR::/'")
        app.config.load(t)<commit_msg>test: add test for use func<commit_after>import pytest
from misuzu import Misuzu
from misuzu.config import *
from misuzu.utils import *

def test_get_env(tmpdir):
    app = Misuzu("test")
    t = tmpdir.mkdir("sub").join("config.toml")
    t.write("home = 'ENV::HOME::STR'")
    app.config.load(t)
    p = os.environ.get("HOME")
    assert app.config['home'] == p

def test_nested_dict(tmpdir):
    app = Misuzu("test")
    t = tmpdir.mkdir("sub").join("config.toml")
    t.write("[a]\naa = 1\n[a.b]\nbb = 2")
    app.config.load(t)
    p = {
        'a': {'aa': 1, 'b': {'bb': 2}}
    }
    assert app.config == p

def test_no_env(tmpdir):
    app = Misuzu("test")
    t = tmpdir.mkdir("sub").join("config.toml")
    t.write("home = 'ENV::HOMES::STR::/'")
    app.config.load(t)
    assert app.config['home'] == "/"

def test_no_type(tmpdir):
    with pytest.raises(ConfigException):
        app = Misuzu("test")
        t = tmpdir.mkdir("sub").join("config.toml")
        t.write("home = 'ENV::HOME::SSS::/'")
        app.config.load(t)

def test_no_capitalized(tmpdir):
    with pytest.raises(ConfigException):
        app = Misuzu("test")
        t = tmpdir.mkdir("sub").join("config.toml")
        t.write("home = 'ENV::Home::STR::/'")
        app.config.load(t)

def test_exist_type_func():
    with pytest.raises(ConfigException):
        app = Misuzu("test")

        def into():
            pass
        app.config.use("STR", into)

def test_add_type(tmpdir):
    def double(value):
        return False, value

    app = Misuzu("test")
    t = tmpdir.mkdir("sub").join("config.toml")
    t.write("home = 'ENV::HOME::DOUBLE'")
    app.config.use("DOUBLE", double)
    app.config.load(t)
    p = (False, os.environ.get("HOME"))
    assert app.config == {'home': p}<|endoftext|>


<commit_before>"""
Kerberos aware Requester
"""
from jenkinsapi.utils.requester import Requester
from requests_kerberos import HTTPKerberosAuth, OPTIONAL

# pylint: disable=W0222
class KrbRequester(Requester):

    """
    A class which carries out HTTP requests with Kerberos/GSSAPI authentication.
    """

    def __init__(self, ssl_verify=None, baseurl=None, mutual_auth=OPTIONAL):
        """
        :param ssl_verify: flag indicating if server certificate in HTTPS requests should be verified
        :param baseurl: Jenkins' base URL
        :param mutual_auth: type of mutual authentication, use one of REQUIRED, OPTIONAL or DISABLED
                            from requests_kerberos package
        """
        args = {}
        if ssl_verify:
            args["ssl_verify"] = ssl_verify
        if baseurl:
            args["baseurl"] = baseurl
        super(KrbRequester, self).__init__(**args)
        self.mutual_auth = mutual_auth

    def get_request_dict(self, params=None, data=None, files=None, headers=None):
      req_dict = super(KrbRequester, self).get_request_dict(params=params, data=data, files=files, headers=headers)
      if self.mutual_auth:
         auth = HTTPKerberosAuth(self.mutual_auth)
      else:
         auth = HTTPKerberosAuth()
      req_dict['auth'] = auth
      return req_dict
<commit_msg>Linter fixes<commit_after>"""
Kerberos aware Requester
"""
from jenkinsapi.utils.requester import Requester
from requests_kerberos import HTTPKerberosAuth, OPTIONAL

# pylint: disable=W0222
class KrbRequester(Requester):

    """
    A class which carries out HTTP requests with Kerberos/GSSAPI authentication.
    """

    def __init__(self, ssl_verify=None, baseurl=None, mutual_auth=OPTIONAL):
        """
        :param ssl_verify: flag indicating if server certificate in HTTPS requests should be
                           verified
        :param baseurl: Jenkins' base URL
        :param mutual_auth: type of mutual authentication, use one of REQUIRED, OPTIONAL or DISABLED
                            from requests_kerberos package
        """
        args = {}
        if ssl_verify:
            args["ssl_verify"] = ssl_verify
        if baseurl:
            args["baseurl"] = baseurl
        super(KrbRequester, self).__init__(**args)
        self.mutual_auth = mutual_auth

    def get_request_dict(self, params=None, data=None, files=None, headers=None):
      req_dict = super(KrbRequester, self).get_request_dict(params=params, data=data, files=files,
                                                            headers=headers)
      if self.mutual_auth:
         auth = HTTPKerberosAuth(self.mutual_auth)
      else:
         auth = HTTPKerberosAuth()
      req_dict['auth'] = auth
      return req_dict
<|endoftext|>


<commit_before>import unittest

import os
import shutil
import tempfile
import uuid

from sundara import config
from sundara import resources

class TestConfig(unittest.TestCase):

    def setUp(self):
        self.dir = tempfile.mktemp()
        os.makedirs(self.dir)
        self.config_file = os.path.join(self.dir, config.PROJECT_CONF)

    def tearDown(self):
        shutil.rmtree(self.dir)

    def test_creates_conf_if_not_exists(self):
        self.assertFalse(os.path.exists(self.config_file))
        config.Config(self.dir)
        self.assertTrue(os.path.isfile(self.config_file))

    def test_doesnt_overwrite_conf_if_exists(self):
        # Embed a unique string.
        unique_string = '[%s]' % str(uuid.uuid4())
        with open(self.config_file, "w+") as f:
            f.write(unique_string)
        self.assertTrue(os.path.isfile(self.config_file))
        # Run config again and check that the string is still there.
        config.Config(self.dir)
        with open(self.config_file, "r+") as f:
            self.assertEquals(unique_string, f.read())

    def test_copies_user_conf_if_exists(self):
        # Embed a unique string.
        os.mkdir(os.path.join(self.dir, 'USER'))
        config.USER_CONF = os.path.join(self.dir, 'USER',
                config.PROJECT_CONF)
        unique_string = '[%s]' % str(uuid.uuid4())
        with open(config.USER_CONF, "w+") as f:
            f.write(unique_string)
        # Run config and check that the file was copied.
        config.Config(self.dir)
        with open(self.config_file, "r+") as f:
            self.assertEquals(unique_string, f.read())

    def test_uses_resources_if_no_other_options(self):
        # Make sure user conf doesn't exist.
        os.mkdir(os.path.join(self.dir, 'USER'))
        config.USER_CONF = os.path.join(self.dir, 'USER',
                config.PROJECT_CONF)
        self.assertFalse(os.path.exists(config.USER_CONF))
        # Make sure project conf doesn't exist.
        self.assertFalse(os.path.exists(self.config_file))
        # Run config and check that it writes from resources.
        config.Config(self.dir)
        with open(self.config_file, "r+") as f:
            self.assertEquals(resources.CONFIG, f.read())

    def test_get_gets_config(self):
        # Embed a unique string.
        unique_section = str(uuid.uuid4())
        unique_option = str(uuid.uuid4())
        unique_value = str(uuid.uuid4())
        unique_string = '[%s]\n%s = %s' % (unique_section,
                unique_option, unique_value)
        with open(self.config_file, "w+") as f:
            f.write(unique_string)
        # Run config and check that it reads the correct value.
        c = config.Config(self.dir)
        self.assertEquals(unique_value, c.get(unique_section,
            unique_option))
<commit_msg>Test Config raises exceptions.<commit_after>import unittest

import os
import shutil
import tempfile
import uuid

from sundara import config
from sundara import resources
from sundara import exceptions

class TestConfig(unittest.TestCase):

    def setUp(self):
        self.dir = tempfile.mktemp()
        os.makedirs(self.dir)
        self.config_file = os.path.join(self.dir, config.PROJECT_CONF)

    def tearDown(self):
        shutil.rmtree(self.dir)

    def test_creates_conf_if_not_exists(self):
        self.assertFalse(os.path.exists(self.config_file))
        config.Config(self.dir)
        self.assertTrue(os.path.isfile(self.config_file))

    def test_doesnt_overwrite_conf_if_exists(self):
        # Embed a unique string.
        unique_string = '[%s]' % str(uuid.uuid4())
        with open(self.config_file, "w+") as f:
            f.write(unique_string)
        self.assertTrue(os.path.isfile(self.config_file))
        # Run config again and check that the string is still there.
        config.Config(self.dir)
        with open(self.config_file, "r+") as f:
            self.assertEquals(unique_string, f.read())

    def test_copies_user_conf_if_exists(self):
        # Embed a unique string.
        os.mkdir(os.path.join(self.dir, 'USER'))
        config.USER_CONF = os.path.join(self.dir, 'USER',
                config.PROJECT_CONF)
        unique_string = '[%s]' % str(uuid.uuid4())
        with open(config.USER_CONF, "w+") as f:
            f.write(unique_string)
        # Run config and check that the file was copied.
        config.Config(self.dir)
        with open(self.config_file, "r+") as f:
            self.assertEquals(unique_string, f.read())

    def test_uses_resources_if_no_other_options(self):
        # Make sure user conf doesn't exist.
        os.mkdir(os.path.join(self.dir, 'USER'))
        config.USER_CONF = os.path.join(self.dir, 'USER',
                config.PROJECT_CONF)
        self.assertFalse(os.path.exists(config.USER_CONF))
        # Make sure project conf doesn't exist.
        self.assertFalse(os.path.exists(self.config_file))
        # Run config and check that it writes from resources.
        config.Config(self.dir)
        with open(self.config_file, "r+") as f:
            self.assertEquals(resources.CONFIG, f.read())

    def test_get_gets_config(self):
        # Embed a unique string.
        unique_section = str(uuid.uuid4())
        unique_option = str(uuid.uuid4())
        unique_value = str(uuid.uuid4())
        unique_string = '[%s]\n%s = %s' % (unique_section,
                unique_option, unique_value)
        with open(self.config_file, "w+") as f:
            f.write(unique_string)
        # Run config and check that it reads the correct value.
        c = config.Config(self.dir)
        self.assertEquals(unique_value, c.get(unique_section,
            unique_option))

    def test_raises_ConfigError_on_exception(self):
        c = config.Config(self.dir)
        self.assertRaises(exceptions.ConfigError, c.get, 'badsection', 'option')
        self.assertRaises(exceptions.ConfigError, c.get, 'sundara', 'badoption')
<|endoftext|>


<commit_before>"""
Eidos is an open-domain machine reading system which uses a cascade of grammars
to extract causal events from free text. It is ideal for modeling applications
that are not specific to a given domain like molecular biology.

To cover a wide range of use cases and scenarios, there are currently 4
different ways in which INDRA can use Eidos.

In all cases for Eidos to provide grounding information to be included in
INDRA Statements, it needs to be configured explicitly to do so.
Please follow instructions at https://github.com/clulab/eidos#configuring to
download and configure Eidos grounding resources.

1. INDRA communicating with a separately running Eidos webapp (:py:mod:`indra.sources.eidos.client`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setup and usage: Clone and run the Eidos web server.

.. code-block:: bash

    git clone https://github.com/clulab/eidos.git
    cd eidos
    sbt webapp/run

Then read text by specifying the webserver parameter when using
`indra.sources.eidos.process_text`.

.. code-block:: python

   from indra.sources import eidos
   ep = eidos.process_text('rainfall causes floods',
                            webservice='http://localhost:9000')

Advantages:

* Does not require setting up the pyjnius Python-Java bridge
* Does not require assembling an Eidos JAR file

Disadvantages:

* Not all Eidos functionalities are immediately exposed through its webapp.

2. INDRA using an Eidos JAR directly through a Python-Java bridge (:py:mod:`indra.sources.eidos.reader`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setup and usage:

First, the Eidos system and its dependencies need to be packaged as a fat JAR:

.. code-block:: bash

    git clone https://github.com/clulab/eidos.git
    cd eidos
    sbt assembly

This creates a JAR file in eidos/target/scala[version]/eidos-[version].jar.
Set the absolute path to this file on the EIDOSPATH environmental variable
and then append EIDOSPATH to the CLASSPATH environmental variable (entries
are separated by colons).

The `pyjnius` package needs to be set up and be operational. For more details,
see :ref:`pyjniussetup` setup instructions in the documentation.

Then, reading can be done simply using the `indra.sources.eidos.process_text`
function.

.. code-block:: python

   from indra.sources import eidos
   ep = eidos.process_text('rainfall causes floods')

Advantages:

* Doesn't require running a separate process for Eidos and INDRA
* Having a single Eidos JAR file makes this solution portable

Disadvantages:

* Requires configuring pyjnius which is often difficult
* Requires building a large Eidos JAR file which can be time consuming
* The EidosReader instance needs to be instantiated every time a new INDRA
  session is started which is time consuming.

3. INDRA using a Flask sever wrapping an Eidos JAR in a separate process (:py:mod:`indra.sources.eidos.server`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setup and usage: Requires building an Eidos JAR and setting up pyjnius --
see above.

First, run the server using

.. code-block:: bash

    python -m indra.sources.eidos.server

Then point to the running server with the webservice parameter when calling
`indra.sources.eidos.process_text`.

.. code-block:: python

   from indra.sources import eidos
   ep = eidos.process_text('rainfall causes floods',
                            webservice='http://localhost:6665')

Advantages:

* EidosReader is instantiated by the Flask server in a separate process,
  therefore it isn't reloaded each time a new INDRA session is started
* Having a single Eidos JAR file makes this solution portable

Disadvantages:

* Currently does not offer any additional functionality compared to running
  the Eidos webapp directly
* Requires configuring pyjnius which is often difficult
* Requires building a large Eidos JAR file which can be time consuming

4. INDRA calling the Eidos CLI using java through the command line (:py:mod:`indra.sources.eidos.cli`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setup and usage: Requires building an Eidos JAR and setting EIDOSPATH but does
not require setting up pyjnius -- see above. To use, call any of the
functions exposed in :py:mod:`indra.sources.eidos.cli`.

Advantages:

* Provides a Python-interface for running Eidos on "large scale" jobs, e.g.,
  a large number of input files.
* Does not require setting up pyjnius since it uses Eidos via the command line.
* Provides a way to use any available entrypoint of Eidos.

Disadvantages:

* Requires building an Eidos JAR which can be time consuming.
"""

from .api import process_text, process_json_str, process_json_file, \
    process_json, initialize_reader
<commit_msg>Fix default port in documentation<commit_after>"""
Eidos is an open-domain machine reading system which uses a cascade of grammars
to extract causal events from free text. It is ideal for modeling applications
that are not specific to a given domain like molecular biology.

To cover a wide range of use cases and scenarios, there are currently 4
different ways in which INDRA can use Eidos.

In all cases for Eidos to provide grounding information to be included in
INDRA Statements, it needs to be configured explicitly to do so.
Please follow instructions at https://github.com/clulab/eidos#configuring to
download and configure Eidos grounding resources.

1. INDRA communicating with a separately running Eidos webapp (:py:mod:`indra.sources.eidos.client`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setup and usage: Clone and run the Eidos web server.

.. code-block:: bash

    git clone https://github.com/clulab/eidos.git
    cd eidos
    sbt webapp/run

Then read text by specifying the webserver parameter when using
`indra.sources.eidos.process_text`.

.. code-block:: python

   from indra.sources import eidos
   ep = eidos.process_text('rainfall causes floods',
                            webservice='http://localhost:9000')

Advantages:

* Does not require setting up the pyjnius Python-Java bridge
* Does not require assembling an Eidos JAR file

Disadvantages:

* Not all Eidos functionalities are immediately exposed through its webapp.

2. INDRA using an Eidos JAR directly through a Python-Java bridge (:py:mod:`indra.sources.eidos.reader`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setup and usage:

First, the Eidos system and its dependencies need to be packaged as a fat JAR:

.. code-block:: bash

    git clone https://github.com/clulab/eidos.git
    cd eidos
    sbt assembly

This creates a JAR file in eidos/target/scala[version]/eidos-[version].jar.
Set the absolute path to this file on the EIDOSPATH environmental variable
and then append EIDOSPATH to the CLASSPATH environmental variable (entries
are separated by colons).

The `pyjnius` package needs to be set up and be operational. For more details,
see :ref:`pyjniussetup` setup instructions in the documentation.

Then, reading can be done simply using the `indra.sources.eidos.process_text`
function.

.. code-block:: python

   from indra.sources import eidos
   ep = eidos.process_text('rainfall causes floods')

Advantages:

* Doesn't require running a separate process for Eidos and INDRA
* Having a single Eidos JAR file makes this solution portable

Disadvantages:

* Requires configuring pyjnius which is often difficult
* Requires building a large Eidos JAR file which can be time consuming
* The EidosReader instance needs to be instantiated every time a new INDRA
  session is started which is time consuming.

3. INDRA using a Flask sever wrapping an Eidos JAR in a separate process (:py:mod:`indra.sources.eidos.server`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setup and usage: Requires building an Eidos JAR and setting up pyjnius --
see above.

First, run the server using

.. code-block:: bash

    python -m indra.sources.eidos.server

Then point to the running server with the webservice parameter when calling
`indra.sources.eidos.process_text`.

.. code-block:: python

   from indra.sources import eidos
   ep = eidos.process_text('rainfall causes floods',
                            webservice='http://localhost:6666')

Advantages:

* EidosReader is instantiated by the Flask server in a separate process,
  therefore it isn't reloaded each time a new INDRA session is started
* Having a single Eidos JAR file makes this solution portable

Disadvantages:

* Currently does not offer any additional functionality compared to running
  the Eidos webapp directly
* Requires configuring pyjnius which is often difficult
* Requires building a large Eidos JAR file which can be time consuming

4. INDRA calling the Eidos CLI using java through the command line (:py:mod:`indra.sources.eidos.cli`)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setup and usage: Requires building an Eidos JAR and setting EIDOSPATH but does
not require setting up pyjnius -- see above. To use, call any of the
functions exposed in :py:mod:`indra.sources.eidos.cli`.

Advantages:

* Provides a Python-interface for running Eidos on "large scale" jobs, e.g.,
  a large number of input files.
* Does not require setting up pyjnius since it uses Eidos via the command line.
* Provides a way to use any available entrypoint of Eidos.

Disadvantages:

* Requires building an Eidos JAR which can be time consuming.
"""

from .api import process_text, process_json_str, process_json_file, \
    process_json, initialize_reader
<|endoftext|>