示例#1
0
    def test_config_file_is_unicode_clean(self):
        self.__files.create({
            self.__config_name: textwrap.dedent("""\
                # -*- coding: utf-8 -*-
                from shinysdr.i.test_config import StubDevice
                config.devices.add(u'•', StubDevice())
            """),
        })

        execute_config(self.__config, self.__config_name)
        self.assertEqual({u'•'}, set(self.__config.devices._values.keys()))
示例#2
0
 def test_db_content_warning(self):
     self.__files.create({
         self.__config_name: {
             'config.py': '',
             'dbs-read-only': {
                 'foo.csv': 'Name\na',
             },
         },
     })
     execute_config(self.__config, self.__config_name)
     self.__config.devices.add(u'stub_for_completion', StubDevice())
     yield self.__config._wait_and_validate()
     self.log_tester.check(
         dict(log_format='{path}: {db_diagnostic}', path='foo.csv'),
         NO_NETWORK)
示例#3
0
 def test_default_config(self):
     write_default_config(self.__config_name)
     self.assertTrue(os.path.isdir(self.__config_name))
     
     # Don't try to open a real device
     with open(self.__dirpath('config.py'), 'r') as f:
         conf_text = f.read()
     DEFAULT_DEVICE = "OsmoSDRDevice('')"
     self.assertIn(DEFAULT_DEVICE, conf_text)
     conf_text = conf_text.replace(DEFAULT_DEVICE, "OsmoSDRDevice('file=/dev/null,rate=100000')")
     with open(self.__dirpath('config.py'), 'w') as f:
         f.write(conf_text)
     
     execute_config(self.__config, self.__config_name)
     
     self.assertTrue(os.path.isdir(self.__dirpath('dbs-read-only')))
     return self.__config._wait_and_validate()
示例#4
0
 def test_config_directory(self):
     self.__files.create({
         self.__config_name: {
             'config.py': 'config.features.enable("_test_disabled_feature")',
             'dbs-read-only': {
                 'foo.csv': 'Frequency,Name',
             },
         },
     })
     execute_config(self.__config, self.__config_name)
     
     # Config python was executed
     self.assertTrue(self.__config.features._get('_test_disabled_feature'))
     
     # Config-directory-related defaults were set
     self.assertEqual(self.__dirpath('state.json'), self.__config._state_filename)
     self.assertIn('foo.csv', self.__config.databases._get_read_only_databases())
示例#5
0
    def test_config_file(self):
        self.__files.create({
            self.__config_name: 'config.features.enable("_test_disabled_feature")',
            'dbs': {
                # DB CSV file we expect NOT to be loaded
                'foo.csv': 'Frequency,Name',
            },
        })

        execute_config(self.__config, self.__config_name)
        
        # Config python was executed
        self.assertTrue(self.__config.features._get('_test_disabled_feature'))
        
        # Config-directory-related defaults were not set
        self.assertEqual(None, self.__config._state_filename)
        self.assertEqual(six.viewkeys(get_default_dbs()), six.viewkeys(self.__config.databases._get_read_only_databases()))
示例#6
0
 def test_traceback_processing(self):
     self.maxDiff = 1000
     self.__files.create({
         self.__config_name: 'config.devices.add("will-fail")'
     })
     file_obj = six.StringIO()
     try:
         execute_config(self.__config, self.__config_name)
         self.fail('did not raise')
     except ConfigException:
         print_config_exception(sys.exc_info(), file_obj)
     self.assertEqual(
         file_obj.getvalue()
         .replace(self.__files.dir, '<tempdir>')
         .replace(__file__, '<config.py>'),
         textwrap.dedent("""\
             An error occurred while executing the ShinySDR configuration file:
               File "<tempdir>/config", line 1, in <module>
                 config.devices.add("will-fail")
             ConfigException: config.devices.add: no device(s) specified
         """))
示例#7
0
def _main_async(reactor, argv=None, _abort_for_test=False):
    if argv is None:
        argv = sys.argv

    if not _abort_for_test:
        # Some log messages would be discarded if we did not set up things early.
        configure_logging()

    # Option parsing is done before importing the main modules so as to avoid the cost of initializing gnuradio if we are aborting early. TODO: Make that happen for createConfig too.
    argParser = argparse.ArgumentParser(prog=argv[0])
    argParser.add_argument('config_path',
                           metavar='CONFIG',
                           help='path of configuration directory or file')
    argParser.add_argument(
        '--create',
        dest='createConfig',
        action='store_true',
        help='write template configuration file to CONFIG and exit')
    argParser.add_argument('-g, --go',
                           dest='openBrowser',
                           action='store_true',
                           help='open the UI in a web browser')
    argParser.add_argument(
        '--force-run',
        dest='force_run',
        action='store_true',
        help='Run DSP even if no client is connected (for debugging).')
    args = argParser.parse_args(args=argv[1:])

    # Verify we can actually run.
    # Note that this must be done before we actually load core modules, because we might get an import error then.
    version_report = yield _check_versions()
    if version_report:
        print(version_report, file=sys.stderr)
        sys.exit(1)

    # Write config file and exit if asked ...
    if args.createConfig:
        write_default_config(args.config_path)
        _log.info('Created default configuration at: {config_path}',
                  config_path=args.config_path)
        sys.exit(0)  # TODO: Consider using a return value or something instead

    # ... else read config file
    config_obj = Config(reactor=reactor, log=_log)
    try:
        execute_config(config_obj, args.config_path)
        yield config_obj._wait_and_validate()
    except ConfigException:
        print_config_exception(sys.exc_info(), sys.stderr)
        defer.returnValue(None)
        return

    _log.info('Constructing...')
    app = config_obj._create_app()

    reactor.addSystemEventTrigger('during', 'shutdown', app.close_all_devices)

    _log.info('Restoring state...')
    pfg = PersistenceFileGlue(reactor=reactor,
                              root_object=app,
                              filename=config_obj._state_filename,
                              get_defaults=_app_defaults)

    _log.info('Starting web server...')
    services = MultiService()
    for maker in config_obj._service_makers:
        IService(maker(app)).setServiceParent(services)
    services.startService()

    _log.info('ShinySDR is ready.')

    for service in services:
        # TODO: should have an interface (currently no proper module to put it in)
        service.announce(args.openBrowser)

    if args.force_run:
        _log.debug('force_run')
        # TODO kludge, make this less digging into guts
        app.get_receive_flowgraph().get_monitor().state()['fft'].subscribe2(
            lambda v: None, the_subscription_context)

    if _abort_for_test:
        services.stopService()
        yield pfg.sync()
        defer.returnValue(app)
    else:
        yield defer.Deferred()  # never fires