예제 #1
0
def dome():
    set_config('dome', {
        'brand': 'Simulacrum',
        'driver': 'simulator',
    })

    return create_dome_simulator()
예제 #2
0
파일: __init__.py 프로젝트: ASTROGBAE/POCS
def create_mount_simulator(mount_info=None,
                           earth_location=None,
                           *args, **kwargs):
    # Remove mount simulator
    current_simulators = get_config('simulator', default=[])
    logger.warning(f'Current simulators: {current_simulators}')
    with suppress(ValueError):
        current_simulators.remove('mount')

    mount_config = mount_info or {
        'model': 'Mount Simulator',
        'driver': 'simulator',
        'serial': {
            'port': '/dev/FAKE'
        }
    }

    # Set mount device info to simulator
    set_config('mount', mount_config)

    earth_location = earth_location or create_location_from_config()['earth_location']

    logger.debug(f"Loading mount driver: pocs.mount.{mount_config['driver']}")
    try:
        module = load_module(f"panoptes.pocs.mount.{mount_config['driver']}")
    except error.NotFound as e:
        raise error.MountNotFound(f'Error loading mount module: {e!r}')

    mount = module.Mount(earth_location, *args, **kwargs)

    logger.success(f"{mount_config['driver'].title()} mount created")

    return mount
예제 #3
0
def test_bad_scheduler_fields_file(config_host, config_port):
    set_config('scheduler.fields_file', 'foobar')
    site_details = create_location_from_config()
    with pytest.raises(error.NotFound):
        create_scheduler_from_config(observer=site_details['observer'])

    reset_conf(config_host, config_port)
예제 #4
0
    def do_setup_pocs(self, *arg):
        """Setup and initialize a POCS instance."""
        args, kwargs = string_to_params(*arg)

        simulator = kwargs.get('simulator', list())
        if isinstance(simulator, str):
            simulator = [simulator]

        # Set whatever simulators were passed during setup
        client.set_config('simulator', simulator)
        # Retrieve what was set
        simulators = client.get_config('simulator', default=list())
        if len(simulators):
            print_warning(f'Using simulators: {simulators}')

        if 'POCSTIME' in os.environ:
            print_warning("Clearing POCSTIME variable")
            del os.environ['POCSTIME']

        try:
            mount = create_mount_from_config()
            cameras = create_cameras_from_config()
            scheduler = create_scheduler_from_config()

            observatory = Observatory(mount=mount, cameras=cameras, scheduler=scheduler)
            self.pocs = POCS(observatory)
            self.pocs.initialize()
        except error.PanError as e:
            print_warning('Problem setting up POCS: {}'.format(e))
예제 #5
0
def test_create_mount_without_mount_info(config_host, config_port):
    # Set the mount config to none and then don't pass anything for error.
    set_config('mount', None)
    set_config('simulator', hardware.get_all_names(without=['mount']))
    with pytest.raises(error.MountNotFound):
        create_mount_from_config(mount_info=None)

    reset_conf(config_host, config_port)
예제 #6
0
def test_create_mount_simulator_with_config(config_host, config_port):
    # Remove mount from list of simulators.
    set_config('simulator', hardware.get_all_names(without=['mount']))
    # But setting the driver to `simulator` should return simulator.
    set_config('mount.driver', 'simulator')

    mount = create_mount_from_config()
    assert isinstance(mount, AbstractMount) is True
    reset_conf(config_host, config_port)
예제 #7
0
def test_camera_wrong_type():
    # Remove mount simulator
    set_config('simulator', hardware.get_all_names(without='camera'))

    with pytest.raises(AttributeError):
        Observatory(cameras=[Time.now()])

    with pytest.raises(AssertionError):
        Observatory(cameras={'Cam00': Time.now()})
예제 #8
0
def test_create_mount_with_earth_location(config_host, config_port):
    # Get location to pass manually.
    loc = create_location_from_config()
    # Set config to not have a location.
    set_config('location', None)
    set_config('simulator', hardware.get_all_names())
    assert isinstance(create_mount_from_config(earth_location=loc['earth_location']), AbstractMount) is True

    reset_conf(config_host, config_port)
예제 #9
0
def test_loading_target_file_check_file(observer,
                                        simple_fields_file,
                                        constraints):
    set_config('scheduler.check_file', False)
    scheduler = Scheduler(observer,
                          fields_file=simple_fields_file,
                          constraints=constraints)
    # Check the hidden property as the public one
    # will populate if not found.
    assert len(scheduler._observations)
예제 #10
0
def test_create_mount_with_mount_info(config_host, config_port):
    # Pass the mount info directly with nothing in config.
    mount_info = get_config('mount', default=dict())
    mount_info['driver'] = 'simulator'

    # Remove info from config.
    set_config('mount', None)
    set_config('simulator', hardware.get_all_names(without=['mount']))
    assert isinstance(create_mount_from_config(mount_info=mount_info), AbstractMount) is True

    reset_conf(config_host, config_port)
예제 #11
0
def mount(location):
    with suppress(KeyError):
        del os.environ['POCSTIME']

    set_config('mount',
               {
                   'brand': 'bisque',
                   'template_dir': 'resources/bisque',
               })

    return Mount(location=location)
예제 #12
0
def test_bad_mount_driver(config_host, config_port):
    # Remove the mount from the list of simulators so it thinks we have a real one.
    simulators = get_config('simulator')
    with suppress(KeyError, AttributeError):
        simulators.pop('mount')
    set_config('simulator', simulators)

    # Set a bad port, which should cause a fail before actual mount creation.
    set_config('mount.serial.driver', 'foobar')
    with pytest.raises(error.MountNotFound):
        create_mount_from_config()
    reset_conf(config_host, config_port)
예제 #13
0
def dynamic_config_server(config_host, config_port, config_server_args, images_dir, db_name):
    """If a test requires changing the configuration we use a function-scoped testing
    server. We only do this on tests that require it so we are not constantly starting and stopping
    the config server unless necessary.  To use this, each test that requires it must use the
    `dynamic_config_server` and `config_port` fixtures and must pass the `config_port` to all
    instances that are created (propogated through PanBase).
    """

    logger = get_root_logger()
    logger.critical(f'Starting config_server for testing function')

    def start_config_server():
        # Load the config items into the app config.
        for k, v in config_server_args.items():
            app.config[k] = v

        # Start the actual flask server.
        app.run(host=config_host, port=config_port)

    proc = Process(target=start_config_server)
    proc.start()

    logger.info(f'config_server started with PID={proc.pid}')

    # Give server time to start
    time.sleep(1)

    # Adjust various config items for testing
    unit_name = 'Generic PANOPTES Unit'
    unit_id = 'PAN000'
    logger.info(f'Setting testing name and unit_id to {unit_id}')
    set_config('name', unit_name, port=config_port)
    set_config('pan_id', unit_id, port=config_port)

    logger.info(f'Setting testing database to {db_name}')
    set_config('db.name', db_name, port=config_port)

    fields_file = 'simulator.yaml'
    logger.info(f'Setting testing scheduler fields_file to {fields_file}')
    set_config('scheduler.fields_file', fields_file, port=config_port)

    # TODO(wtgee): determine if we need separate directories for each module.
    logger.info(f'Setting temporary image directory for testing')
    set_config('directories.images', images_dir, port=config_port)

    yield
    logger.critical(f'Killing config_server started with PID={proc.pid}')
    proc.terminate()
예제 #14
0
    def set_config(self, key, new_value, *args, **kwargs):
        """Thin-wrapper around client based set_config that sets default port.

        See `panoptes.utils.config.client.set_config` for more information.

        Args:
            key (str): The key name to use, can be namespaced with dots.
            new_value (any): The value to store.
            *args: Passed to set_config
            **kwargs: Passed to set_config
        """
        config_value = None

        if key == 'simulator' and new_value == 'all':
            # Don't use hardware.get_simulator_names because it checks config.
            new_value = hardware.ALL_NAMES

        try:
            self.logger.trace(f'Setting config key={key!r} new_value={new_value!r}')
            config_value = client.set_config(key, new_value,
                                             host=self._config_host,
                                             port=self._config_port,
                                             *args, **kwargs)
            self.logger.trace(f'Config set config_value={config_value!r}')
        except ConnectionError as e:  # pragma: no cover
            self.logger.critical(f'Cannot connect to config_server from {self.__class__}: {e!r}')

        return config_value
예제 #15
0
def test_config_reset(config_host, config_port):
    # Reset config via url
    url = f'http://{config_host}:{config_port}/reset-config'

    def reset_conf():
        response = requests.post(url,
                                 data=serializers.to_json({'reset': True}),
                                 headers={'Content-Type': 'application/json'})
        assert response.ok

    reset_conf()

    # Check we are at default value.
    assert get_config('location.horizon') == 30 * u.degree

    # Set to new value.
    set_config_return = set_config('location.horizon', 3 * u.degree)
    assert set_config_return == {'location.horizon': 3 * u.degree}

    # Check we have changed.
    assert get_config('location.horizon') == 3 * u.degree

    reset_conf()

    # Check we are at default again.
    assert get_config('location.horizon') == 30 * u.degree
예제 #16
0
def test_config_client():
    assert isinstance(get_config(), dict)

    assert get_config('location.horizon') == 30 * u.degree
    assert set_config('location.horizon', 47 * u.degree) == {
        'location.horizon': 47 * u.degree
    }
    assert get_config('location.horizon') == 47 * u.degree

    # Without parsing the result contains the double-quotes since that's what the raw
    # response has.
    assert get_config('location.horizon', parse=False) == '"47.0 deg"'

    assert set_config('location.horizon', 42 * u.degree, parse=False) == {
        'location.horizon': '42.0 deg'
    }
예제 #17
0
def dynamic_config_server(config_host, config_port, config_path, images_dir,
                          db_name):
    """If a test requires changing the configuration we use a function-scoped testing
    server. We only do this on tests that require it so we are not constantly starting and stopping
    the config server unless necessary.  To use this, each test that requires it must use the
    `dynamic_config_server` and `config_port` fixtures and must pass the `config_port` to all
    instances that are created (propogated through PanBase).
    """

    print(f'Starting config_server for testing function')

    proc = config_server(
        host=config_host,
        port=config_port,
        config_file=config_path,
        ignore_local=True,
    )

    print(f'config_server started with PID={proc.pid}')

    # Give server time to start
    time.sleep(1)

    # Adjust various config items for testing
    unit_name = 'Generic PANOPTES Unit'
    unit_id = 'PAN000'
    print(f'Setting testing name and unit_id to {unit_id}')
    set_config('name', unit_name, port=config_port)
    set_config('pan_id', unit_id, port=config_port)

    print(f'Setting testing database to {db_name}')
    set_config('db.name', db_name, port=config_port)

    fields_file = 'simulator.yaml'
    print(f'Setting testing scheduler fields_file to {fields_file}')
    set_config('scheduler.fields_file', fields_file, port=config_port)

    # TODO(wtgee): determine if we need separate directories for each module.
    print(f'Setting temporary image directory for testing')
    set_config('directories.images', images_dir, port=config_port)

    yield
    print(f'Killing config_server started with PID={proc.pid}')
    proc.terminate()
예제 #18
0
def test_set_dome():
    set_config('dome', {
        'brand': 'Simulacrum',
        'driver': 'simulator',
    })
    dome = create_dome_simulator()

    obs = Observatory(dome=dome)
    assert obs.has_dome is True
    obs.set_dome(dome=None)
    assert obs.has_dome is False
    obs.set_dome(dome=dome)
    assert obs.has_dome is True
    err_msg = 'Dome is not an instance of .*AbstractDome'
    with pytest.raises(TypeError, match=err_msg):
        obs.set_dome('dome')
    err_msg = ".*missing 1 required positional argument.*"
    with pytest.raises(TypeError, match=err_msg):
        obs.set_dome()
예제 #19
0
def test_config_client_bad(dynamic_config_server, config_port, caplog):
    # Bad host will return `None` but also throw error
    assert set_config('foo', 42, host='foobaz') is None
    assert caplog.records[-1].levelname == "INFO"
    assert caplog.records[-1].message.startswith("Problem with set_config")

    # Bad host will return `None` but also throw error
    assert get_config('foo', host='foobaz') is None
    assert caplog.records[-1].levelname == "INFO"
    assert caplog.records[-1].message.startswith("Problem with get_config")
예제 #20
0
def static_config_server(config_host, static_config_port, config_server_args, images_dir, db_name):

    logger = get_root_logger()
    logger.critical(f'Starting config_server for testing session')

    def start_config_server():
        # Load the config items into the app config.
        for k, v in config_server_args.items():
            app.config[k] = v

        # Start the actual flask server.
        app.run(host=config_host, port=static_config_port)

    proc = Process(target=start_config_server)
    proc.start()

    logger.info(f'config_server started with PID={proc.pid}')

    # Give server time to start
    time.sleep(1)

    # Adjust various config items for testing
    unit_name = 'Generic PANOPTES Unit'
    unit_id = 'PAN000'
    logger.info(f'Setting testing name and unit_id to {unit_id}')
    set_config('name', unit_name, port=static_config_port)
    set_config('pan_id', unit_id, port=static_config_port)

    logger.info(f'Setting testing database to {db_name}')
    set_config('db.name', db_name, port=static_config_port)

    fields_file = 'simulator.yaml'
    logger.info(f'Setting testing scheduler fields_file to {fields_file}')
    set_config('scheduler.fields_file', fields_file, port=static_config_port)

    # TODO(wtgee): determine if we need separate directories for each module.
    logger.info(f'Setting temporary image directory for testing')
    set_config('directories.images', images_dir, port=static_config_port)

    yield
    logger.critical(f'Killing config_server started with PID={proc.pid}')
    proc.terminate()
예제 #21
0
def dome():
    # Install our test handlers for the duration.
    serial.protocol_handler_packages.append('panoptes.pocs.dome')

    # Modify the config so that the dome uses the right controller and port.
    set_config('simulator', hardware.get_all_names(without=['dome']))
    set_config(
        'dome', {
            'brand': 'Astrohaven',
            'driver': 'astrohaven',
            'port': 'astrohaven_simulator://',
        })
    the_dome = create_dome_simulator()

    yield the_dome
    with suppress(Exception):
        the_dome.disconnect()

    # Remove our test handlers.
    serial.protocol_handler_packages.remove('panoptes.pocs.dome')
예제 #22
0
def test_operate_dome():
    # Remove dome and night simulator
    set_config('simulator', hardware.get_all_names(without=['dome', 'night']))

    set_config('dome', {
        'brand': 'Simulacrum',
        'driver': 'simulator',
    })

    set_config('dome', {
        'brand': 'Simulacrum',
        'driver': 'simulator',
    })
    dome = create_dome_simulator()
    observatory = Observatory(dome=dome)

    assert observatory.has_dome
    assert observatory.open_dome()
    assert observatory.dome.is_open
    assert not observatory.dome.is_closed
    assert observatory.open_dome()
    assert observatory.dome.is_open
    assert not observatory.dome.is_closed
    assert observatory.close_dome()
    assert observatory.dome.is_closed
    assert not observatory.dome.is_open
    assert observatory.close_dome()
    assert observatory.dome.is_closed
    assert not observatory.dome.is_open
    assert observatory.open_dome()
    assert observatory.dome.is_open
    assert not observatory.dome.is_closed
예제 #23
0
def test_config_client(dynamic_config_server, config_port):
    assert isinstance(get_config(port=config_port), dict)

    assert set_config('location.horizon', 47 * u.degree, port=config_port) == {
        'location.horizon': 47 * u.degree
    }

    # With parsing
    assert get_config('location.horizon', port=config_port) == 47 * u.degree

    # Without parsing
    assert get_config('location.horizon', port=config_port,
                      parse=False) == '47.0 deg'
예제 #24
0
def static_config_server(config_host, static_config_port, config_path,
                         images_dir, db_name):

    logger = get_root_logger()
    logger.critical(f'Starting config_server for testing session')

    proc = config_server(
        host=config_host,
        port=static_config_port,
        config_file=config_path,
        ignore_local=True,
    )

    logger.info(f'config_server started with PID={proc.pid}')

    # Give server time to start
    time.sleep(1)

    # Adjust various config items for testing
    unit_name = 'Generic PANOPTES Unit'
    unit_id = 'PAN000'
    logger.info(f'Setting testing name and unit_id to {unit_id}')
    set_config('name', unit_name, port=static_config_port)
    set_config('pan_id', unit_id, port=static_config_port)

    logger.info(f'Setting testing database to {db_name}')
    set_config('db.name', db_name, port=static_config_port)

    fields_file = 'simulator.yaml'
    logger.info(f'Setting testing scheduler fields_file to {fields_file}')
    set_config('scheduler.fields_file', fields_file, port=static_config_port)

    # TODO(wtgee): determine if we need separate directories for each module.
    logger.info(f'Setting temporary image directory for testing')
    set_config('directories.images', images_dir, port=static_config_port)

    yield
    logger.critical(f'Killing config_server started with PID={proc.pid}')
    proc.terminate()
예제 #25
0
def config_setter(context, key, new_value, parse=True):
    """Set an item in the config server. """
    host = context.obj.get('host')
    port = context.obj.get('port')

    logger.debug(
        f'Setting config key={key!r}  new_value={new_value!r} on {host}:{port}'
    )
    config_entry = set_config(key,
                              new_value,
                              host=host,
                              port=port,
                              parse=parse)
    click.echo(config_entry)
예제 #26
0
def test_set_mount():
    obs = Observatory()
    assert obs.mount is None

    obs.set_mount(mount=None)
    assert obs.mount is None

    set_config(
        'mount', {
            'brand': 'Simulacrum',
            'driver': 'simulator',
            'model': 'panoptes.pocs.camera.simulator.dslr',
        })
    mount = create_mount_from_config()
    obs.set_mount(mount=mount)
    assert isinstance(obs.mount, AbstractMount) is True

    err_msg = 'Mount is not an instance of .*AbstractMount'
    with pytest.raises(TypeError, match=err_msg):
        obs.set_mount(mount='mount')
    err_msg = ".*missing 1 required positional argument.*"
    with pytest.raises(TypeError, match=err_msg):
        obs.set_mount()
예제 #27
0
def test_config_client_bad(caplog):
    # Bad host will return `None` but also throw error
    assert set_config('foo', 42, host='foobaz') is None
    assert caplog.records[-1].levelname == "WARNING"
    assert caplog.records[-1].message.startswith("Problem with set_config")

    # Bad host will return `None` but also throw error
    assert get_config('foo', host='foobaz') is None
    found_log = False
    for rec in caplog.records[-5:]:
        if rec.levelname == 'WARNING' and rec.message.startswith(
                'Problem with get_config'):
            found_log = True

    assert found_log
예제 #28
0
def test_config_reset(dynamic_config_server, config_port, config_host):
    # Check we are at default.
    assert get_config('location.horizon', port=config_port) == 30 * u.degree

    # Set to new value.
    set_config_return = set_config('location.horizon',
                                   47 * u.degree,
                                   port=config_port)
    assert set_config_return == {'location.horizon': 47 * u.degree}

    # Check we have changed.
    assert get_config('location.horizon', port=config_port) == 47 * u.degree

    # Reset config
    url = f'http://{config_host}:{config_port}/reset-config'
    response = requests.post(url,
                             data=serializers.to_json({'reset': True}),
                             headers={'Content-Type': 'application/json'})
    assert response.ok

    # Check we are at default again.
    assert get_config('location.horizon', port=config_port) == 30 * u.degree
예제 #29
0
def test_bad_site(config_host, config_port):
    set_config('location', {})
    with pytest.raises(error.PanError):
        Observatory()

    reset_conf(config_host, config_port)
예제 #30
0
파일: conftest.py 프로젝트: ASTROGBAE/POCS
def images_dir(tmpdir_factory):
    directory = tmpdir_factory.mktemp('images')
    set_config('directories.images', str(directory))
    return str(directory)