Example #1
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
Example #2
0
def pytest_addoption(parser):
    hw_names = ",".join(hardware.get_all_names()) + ' (or all for all hardware)'
    db_names = ",".join(_all_databases) + ' (or all for all databases)'
    group = parser.getgroup("PANOPTES pytest options")
    group.addoption(
        "--with-hardware",
        nargs='+',
        default=[],
        help=f"A comma separated list of hardware to test. List items can include: {hw_names}")
    group.addoption(
        "--without-hardware",
        nargs='+',
        default=[],
        help=f"A comma separated list of hardware to NOT test.  List items can include: {hw_names}")
    group.addoption(
        "--test-databases",
        nargs="+",
        default=['file'],
        help=f"Test databases in the list. List items can include: {db_names}. Note that "
             f"travis-ci will test all of "
             f"them by default.")
    group.addoption(
        "--theskyx",
        action='store_true',
        default=False,
        help=f"Test TheSkyX commands, default False -- CURRENTLY NOT WORKING!")
Example #3
0
def test_no_ac_power(pocs):
    # Simulator makes AC power safe
    assert pocs.has_ac_power() is True

    # Remove 'power' from simulator
    pocs.set_config('simulator', hardware.get_all_names(without=['power']))

    pocs.initialize()

    # With simulator removed the power should fail
    assert pocs.has_ac_power() is False

    for v in [True, 12.4, 0., False]:
        has_power = bool(v)

        # Add a fake power entry in data base
        pocs.db.insert_current('power', {'main': v})

        # Check for safe entry in database
        assert pocs.has_ac_power() == has_power
        assert pocs.is_safe() == has_power

        # Check for stale entry in database
        assert pocs.has_ac_power(stale=0.1) is False

        # But double check it still matches longer entry
        assert pocs.has_ac_power() == has_power

        # Remove entry and try again
        pocs.db.clear_current('power')
        assert pocs.has_ac_power() is False
Example #4
0
def test_run_wait_until_safe(observatory, valid_observation_day, pocstime_day,
                             pocstime_night):
    os.environ['POCSTIME'] = pocstime_day

    # Remove weather simulator, else it would always be safe.
    observatory.set_config('simulator',
                           hardware.get_all_names(without=['night']))

    pocs = POCS(observatory)
    pocs.set_config('wait_delay', 5)  # Check safety every 5 seconds.

    pocs.observatory.scheduler.clear_available_observations()
    pocs.observatory.scheduler.add_observation(valid_observation_day)

    assert pocs.connected is True
    assert pocs.is_initialized is False
    pocs.initialize()
    pocs.logger.info('Starting observatory run')

    # Not dark and unit is is connected but not set.
    assert not pocs.is_dark()
    assert pocs.is_initialized
    assert pocs.connected
    assert pocs.do_states
    assert pocs.next_state is None

    pocs.set_config('wait_delay', 1)

    def start_pocs():
        # Start running, BLOCKING.
        pocs.logger.info(f'start_pocs ENTER')
        pocs.run(run_once=True, exit_when_done=True)

        # After done running.
        assert pocs.is_weather_safe() is True
        pocs.power_down()
        observatory.logger.info('start_pocs EXIT')

    pocs_thread = threading.Thread(target=start_pocs, daemon=True)
    pocs_thread.start()

    assert pocs.is_safe(park_if_not_safe=False) is False

    # Wait to pretend we're waiting for horizon
    time.sleep(5)
    os.environ['POCSTIME'] = pocstime_night
    assert pocs.is_dark()

    pocs.logger.warning(f'Waiting to get to slewing state...')
    while pocs.next_state != 'slewing':
        time.sleep(1)

    pocs.logger.warning(f'Stopping states via pocs.DO_STATES')
    observatory.set_config('pocs.DO_STATES', False)

    observatory.logger.warning(f'Waiting on pocs_thread')
    pocs_thread.join(timeout=300)

    assert pocs_thread.is_alive() is False
Example #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)
Example #6
0
    def help_setup_pocs(self):
        print('''Setup and initialize a POCS instance.

    setup_pocs [simulate]

simulate is a space-separated list of hardware to simulate.
Hardware names: {}   (or all for all hardware)'''.format(
            ','.join(hardware.get_all_names())))
Example #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()})
Example #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)
Example #9
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)
Example #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)
Example #11
0
def test_is_weather_safe_no_simulator(pocs):
    pocs.initialize()
    pocs.set_config('simulator', hardware.get_all_names(without=['weather']))

    # Set a specific time
    os.environ['POCSTIME'] = '2020-01-01 18:00:00'

    # Insert a dummy weather record
    pocs.db.insert_current('weather', {'safe': True})
    assert pocs.is_weather_safe() is True

    # Set a time 181 seconds later
    os.environ['POCSTIME'] = '2020-01-01 18:05:01'
    assert pocs.is_weather_safe() is False
Example #12
0
def test_is_weather_and_dark_simulator(pocs, pocstime_night, pocstime_day):
    pocs.initialize()

    # Night simulator
    pocs.set_config('simulator', 'all')
    os.environ['POCSTIME'] = pocstime_night  # is dark
    assert pocs.is_dark() is True
    os.environ['POCSTIME'] = pocstime_day  # is day
    assert pocs.is_dark() is True

    # No night simulator
    pocs.set_config('simulator', hardware.get_all_names(without=['night']))
    os.environ['POCSTIME'] = pocstime_night  # is dark
    assert pocs.is_dark() is True
    os.environ['POCSTIME'] = pocstime_day  # is day
    assert pocs.is_dark() is False

    pocs.set_config('simulator', ['camera', 'mount', 'weather', 'night'])
    assert pocs.is_weather_safe() is True
Example #13
0
def pytest_collection_modifyitems(config, items):
    """Modify tests to skip or not based on cli options.
    Certain tests should only be run when the appropriate hardware is attached.
    Other tests fail if real hardware is attached (e.g. they expect there is no
    hardware). The names of the types of hardware are in hardware.py, but
    include 'mount' and 'camera'. For a test that requires a mount, for
    example, the test should be marked as follows:
    `@pytest.mark.with_mount`
    And the same applies for the names of other types of hardware.
    For a test that requires that there be no cameras attached, mark the test
    as follows:
    `@pytest.mark.without_camera`
    """

    # without_hardware is a list of hardware names whose tests we don't want to run.
    without_hardware = hardware.get_simulator_names(
        simulator=config.getoption('--without-hardware'))

    # with_hardware is a list of hardware names for which we have that hardware attached.
    with_hardware = hardware.get_simulator_names(simulator=config.getoption('--with-hardware'))

    for name in without_hardware:  # noqa
        # User does not want to run tests that interact with hardware called name,
        # whether it is marked as with_name or without_name.
        if name in with_hardware:
            print(f'Warning: {name} in both --with-hardware and --without-hardware')
            with_hardware.remove(name)
        skip = pytest.mark.skip(reason=f"--without-hardware={name} specified")
        with_keyword = f'with_{name}'
        without_keyword = f'without_{name}'
        for item in items:
            if with_keyword in item.keywords or without_keyword in item.keywords:
                item.add_marker(skip)

    for name in hardware.get_all_names(without=with_hardware):
        # We don't have hardware called name, so find all tests that need that
        # hardware and mark it to be skipped.
        skip = pytest.mark.skip(reason=f"Test needs --with-hardware={name} option to run")
        keyword = 'with_' + name
        for item in items:
            if keyword in item.keywords:
                item.add_marker(skip)
Example #14
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')
Example #15
0
def test_unsafe_park(observatory, valid_observation, pocstime_night):
    os.environ['POCSTIME'] = pocstime_night

    # Remove weather simulator, else it would always be safe.
    observatory.set_config(
        'simulator', hardware.get_all_names(without=['night', 'weather']))

    pocs = POCS(observatory)
    pocs.set_config('wait_delay', 5)  # Check safety every 5 seconds.

    pocs.observatory.scheduler.clear_available_observations()
    pocs.observatory.scheduler.add_observation(valid_observation)
    observatory.logger.warning(f'Inserting safe weather reading')
    observatory.db.insert_current('weather', {'safe': True})

    assert pocs.connected is True
    assert pocs.is_initialized is False
    pocs.initialize()
    pocs.logger.info('Starting observatory run')

    # Weather is bad and unit is is connected but not set.
    assert pocs.is_safe()
    assert pocs.is_initialized
    assert pocs.connected
    assert pocs.do_states
    assert pocs.next_state is None

    pocs.set_config('wait_delay', 1)

    def start_pocs():
        # Start running, BLOCKING.
        pocs.logger.info(f'start_pocs ENTER')
        pocs.run(run_once=True, exit_when_done=True)

        # After done running.
        assert pocs.is_weather_safe() is True
        pocs.power_down()
        observatory.logger.info('start_pocs EXIT')

    pocs_thread = threading.Thread(target=start_pocs, daemon=True)
    pocs_thread.start()

    # Insert bad weather report while slewing
    pocs.logger.info(f'Waiting to get to slewing state...')
    while pocs.state != "slewing":
        pass
    pocs.logger.info("Inserting bad weather record.")
    observatory.db.insert_current('weather', {'safe': False})

    # No longer safe, so should transition to parking
    pocs.logger.info(f'Waiting to get to parked state...')
    while True:
        if pocs.state in ['parking', 'parked']:
            break
        assert pocs.state in ["slewing", "parking",
                              "parked"]  # Should be one of these states
        time.sleep(0.5)

    pocs.logger.warning(f'Stopping states via pocs.DO_STATES')
    observatory.set_config('pocs.DO_STATES', False)

    observatory.logger.warning(f'Waiting on pocs_thread')
    pocs_thread.join(timeout=300)

    assert pocs_thread.is_alive() is False
Example #16
0
 def complete_setup_pocs(self, text, line, begidx, endidx):
     """Provide completions for simulator names."""
     names = ['all'] + hardware.get_all_names()
     return [name for name in names if name.startswith(text)]