Source code for gwsumm.tests.test_config

# -*- coding: utf-8 -*-
# Copyright (C) Duncan Macleod (2013)
#
# This file is part of GWSumm.
#
# GWSumm is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GWSumm is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GWSumm.  If not, see <http://www.gnu.org/licenses/>.

"""Tests for :mod:`gwsumm.config`
"""

import os
import tempfile
from io import StringIO
from collections import OrderedDict
from configparser import (DEFAULTSECT, ConfigParser)

import pytest

from matplotlib import rcParams

from astropy import units

from .. import (state, config, html)
from ..channels import get_channel

__author__ = 'Duncan Macleod <duncan.macleod@ligo.org>'

TEST_CONFIG = StringIO("""
[DEFAULT]
defaultoption = defaultvalue

[section]
option1 = value1
option2 = True
option3 = 4

[plugins]
tempfile = ''

[units]
myunit = meter
cochrane = dimensionless

[%(IFO)s]
""")


[docs] def assert_configparser_equal(a, b): for sect in set([DEFAULTSECT] + list(a.sections()) + list(b.sections())): assert list(a.items(sect)) == list(b.items(sect))
[docs] class TestGWSummConfigParser(object): PARSER = config.GWSummConfigParser
[docs] @classmethod def new(cls): TEST_CONFIG.seek(0) cp = cls.PARSER() cp.read_file(TEST_CONFIG) TEST_CONFIG.seek(0) return cp
[docs] @classmethod @pytest.fixture() def cnfg(cls): return cls.new()
# -- test creation --------------------------
[docs] def test_init(self): cp = self.new() assert cp.optionxform is str assert cp._dict is OrderedDict
[docs] def test_configdir(self): assert set(os.listdir(config.CONFIGDIR)) >= { 'defaults.ini', 'matplotlib.ini', }
# -- test methods ---------------------------
[docs] def test_ndoptions(self, cnfg): ndopts = cnfg.ndoptions('section') assert isinstance(ndopts, list) assert 'defaultoption' not in ndopts
[docs] def test_nditems(self, cnfg): nditms = cnfg.nditems('section') assert isinstance(nditms, list) assert ('defaultoption', 'defaultvalue') not in nditms
[docs] def test_read(self): cp = self.new() # read config from file with tempfile.NamedTemporaryFile(mode='w') as f: f.write(TEST_CONFIG.read()) TEST_CONFIG.seek(0) # rewind for other users read_ = cp.read(f.name) assert read_ == [f.name] assert cp.files == [os.path.abspath(f.name)] # check error gets raised when file isn't read with pytest.raises(IOError): cp.read('does-not-exist.ini')
[docs] def test_from_configparser(self, cnfg): # check that GWSummConfigParser gets returned as is copy = self.PARSER.from_configparser(cnfg) assert copy is cnfg # check that base ConfigParser gets converted to GWSummConfigParser cp = ConfigParser() try: cp.read_file(TEST_CONFIG) except AttributeError: cp.readfp(TEST_CONFIG) TEST_CONFIG.seek(0) copy = self.PARSER.from_configparser(cp) assert isinstance(copy, self.PARSER) assert_configparser_equal(copy, cnfg)
[docs] def test_interpolate_section_names(self, cnfg): assert 'X1' not in cnfg.sections() assert '%(IFO)s' in cnfg.sections() cnfg.interpolate_section_names(IFO='X1') assert 'X1' in cnfg.sections() assert '%(IFO)s' not in cnfg.sections()
[docs] @pytest.mark.parametrize('ifo, obs, exp', [ ('L1', None, 'LIGO Livingston'), ('X1', 'Einstein Telescope', 'Einstein Telescope'), ]) def test_set_ifo_options(self, ifo, obs, exp): cp = self.new() cp.set_ifo_options(ifo, observatory=obs) assert cp.get(DEFAULTSECT, 'IFO') == ifo.upper() assert cp.get(DEFAULTSECT, 'ifo') == ifo.lower() assert cp.get(DEFAULTSECT, 'SITE') == ifo[0].upper() assert cp.get(DEFAULTSECT, 'site') == ifo[0].lower() assert cp.get(DEFAULTSECT, 'observatory') == exp
[docs] def test_set_date_options(self): cp = self.new() cp.set_date_options(0, 100) assert cp.get(DEFAULTSECT, 'gps-start-time') == '0' assert cp.get(DEFAULTSECT, 'gps-end-time') == '100' assert cp.get(DEFAULTSECT, 'yyyy') == '1980' assert cp.get(DEFAULTSECT, 'duration') == '100'
[docs] def test_load_rcParams(self): # check empty config doesn't cause havoc cp = self.PARSER() assert cp.load_rcParams() == {} cp = self.new() cp.add_section('rcParams') cp.set('rcParams', 'axes.labelsize', '100') new = cp.load_rcParams() assert new == {'axes.labelsize': 100} assert rcParams['axes.labelsize'] == 100
[docs] def test_load_states(self): cp = self.new() cp.set_date_options(0, 100) cp.add_section('states') cp.set('states', 'locked', 'X1:TEST-STATE:1') cp.load_states() states = state.get_states() assert len(states) == 2 assert 'locked' in states assert states['locked'].definition == 'X1:TEST-STATE:1' assert state.ALLSTATE in states
[docs] def test_load_plugins(self, cnfg): # check that empty section doesn't cause havoc cp = self.PARSER() assert cp.load_plugins() == [] # check plugins get laoded plugins = cnfg.load_plugins() assert plugins == [tempfile]
[docs] def test_load_units(self, cnfg): # check that empty section doesn't cause havoc cp = self.PARSER() assert cp.load_units() == [] newunits = cnfg.load_units() assert newunits == [units.meter, units.dimensionless_unscaled]
[docs] def test_load_channels(self): # test simple channel section cp = self.PARSER() cp.add_section('X1:TEST-CHANNEL') cp.set('X1:TEST-CHANNEL', 'frametype', 'X1_TEST') cp.load_channels() c = get_channel('X1:TEST-CHANNEL') assert c.frametype == 'X1_TEST' # test with interpolation cp.set(DEFAULTSECT, 'IFO', 'X1') cp.add_section('%(IFO)s:TEST-CHANNEL_2') cp.set('%(IFO)s:TEST-CHANNEL_2', 'resample', '128') cp.interpolate_section_names(IFO='X1') cp.load_channels() c = get_channel('X1:TEST-CHANNEL_2') assert c.resample == 128 # test bit parsing cp.set('X1:TEST-CHANNEL', '0', 'Bit 0') cp.set('X1:TEST-CHANNEL', '1', 'A_B') cp.load_channels() c = get_channel('X1:TEST-CHANNEL') assert c.bits == ['Bit 0', 'A_B'] # test channels section cp.add_section('channels-test') cp.set('channels-test', 'channels', 'X1:TEST-CHANNEL,X1:TEST-CHANNEL_2') cp.set('channels-test', 'unit', 'urad') cp.load_channels() assert c.unit == units.microradian
[docs] def test_finalize(self): cp = self.new() cp.set_date_options(0, 100) cp.finalize()
[docs] def test_get_css(self): # check empty result returns defaults cp = self.PARSER() css = cp.get_css() assert css == list(html.get_css().values()) # check overrides cp.add_section('html') cp.set('html', 'gwbootstrap-css', 'test.css') css = cp.get_css() assert 'test.css' in css assert html.get_css()['gwbootstrap'] not in css # check custom files cp.set('html', 'extra-css', '"extra.css","/static/extra2.css"') css = cp.get_css() assert 'test.css' in css # still finds overrides assert 'extra.css' in css and '/static/extra2.css' in css
[docs] def test_get_javascript(self): # check empty result returns defaults cp = self.PARSER() js = cp.get_javascript() assert js == list(html.get_js().values()) # check overrides cp.add_section('html') cp.set('html', 'gwbootstrap-js', 'test.js') js = cp.get_javascript() assert 'test.js' in js assert html.get_js()['gwbootstrap'] not in js # check custom files cp.set('html', 'extra-js', '"extra.js","/static/extra2.js"') js = cp.get_javascript() assert 'test.js' in js # still finds overrides assert 'extra.js' in js and '/static/extra2.js' in js