def test_functions(): assert formatDuration(1) == '1 second' assert formatDuration(4) == '4 seconds' assert formatDuration(154, precise=False) == '3 min' assert formatDuration(154, precise=True) == '2 min, 34 sec' assert formatDuration(7199) == '2 h, 0 min' assert formatDuration(3700) == '1 h, 2 min' assert formatDuration(24 * 3600 + 7240, precise=False) == '1 day, 2 h' assert formatDuration(48 * 3600 - 1) == '2 days, 0 h' assert bitDescription(0x5, (0, 'a'), (1, 'b', 'c'), (2, 'd', 'e')) == 'a, c, d' assert parseConnectionString('[email protected]:pass@host:1301', 1302) == \ {'user': '******', 'password': '******', 'host': 'host', 'port': 1301} assert parseConnectionString('user:@host', 1302) == \ {'user': '******', 'password': '', 'host': 'host', 'port': 1302} assert parseConnectionString('user@host:1301', 1302) == \ {'user': '******', 'password': None, 'host': 'host', 'port': 1301} assert parseConnectionString('user@ho-st:1301', 1302) == \ {'user': '******', 'password': None, 'host': 'ho-st', 'port': 1301} assert parseConnectionString('', 1302) is None assert parseConnectionString('host?', 1302) is None # pylint: disable=range-builtin-not-iterating assert [tuple(x) for x in chunks(range(10), 3)] == \ [(0, 1, 2), (3, 4, 5), (6, 7, 8), (9,)]
def adminclient(daemon): """Create a nicos admin client session and log in""" adminclient = TestClient() parsed = parseConnectionString('admin:admin@' + daemon_addr, 0) adminclient.connect(ConnectionData(**parsed)) assert ('connected', None, None) in adminclient._signals # wait until initial setup is done adminclient.wait_idle() yield adminclient if adminclient.isconnected: adminclient._disconnecting = True adminclient.disconnect()
def main(argv): server = user = via = command = '' password = None # to automatically close an SSH tunnel, we execute something on the remote # server that takes long enough for the client to connect to the daemon; # SSH then keeps the session open until the tunnel is unused, i.e. the # client has disconnected -- normally, "sleep" should be available as a # dummy remote command, but e.g. on erebos.frm2.tum.de it isn't, so we # allow configuring this (but only in the config file, not on the cmdline) viacommand = 'sleep 10' # a connection "profile" can be given by invoking this executable # under a different name (via symlink) ... configsection = 'connect' if not argv[0].endswith('nicos-client'): configsection = path.basename(argv[0]) config = configparser.RawConfigParser() config.read([path.expanduser('~/.nicos-client')]) # check for "command to run" switch if '-c' in argv: n = argv.index('-c') if len(argv) >= n: command = argv[n + 1] del argv[n:n + 2] # ... or by "profile" on the command line (other arguments are # interpreted as a connection data string) if argv[1:]: if config.has_section(argv[1]): configsection = argv[1] else: cd = parseConnectionString(argv[1], DEFAULT_PORT) server = '%s:%s' % (cd['host'], cd['port']) user = cd['user'] password = cd['password'] if argv[3:] and argv[2] == 'via': via = argv[3] # check for profile name as a config section (given by argv0 or on the # command line); if not present, fall back to default if not config.has_section(configsection): configsection = 'connect' # take all connection parameters from the config file if not defined # on the command line if not server and config.has_option(configsection, 'server'): server = config.get(configsection, 'server') if not user and config.has_option(configsection, 'user'): user = config.get(configsection, 'user') if not password and config.has_option(configsection, 'passwd'): password = config.get(configsection, 'passwd') if not via and config.has_option(configsection, 'via'): via = config.get(configsection, 'via') if config.has_option(configsection, 'viacommand'): viacommand = config.get(configsection, 'viacommand') # split server in host:port components try: host, port = server.split(':', 1) port = int(port) except ValueError: host = server port = DEFAULT_PORT # if SSH tunneling is requested, stop here and re-exec after tunnel is # set up and running if via: # use a random (hopefully free) high numbered port on our side nport = random.randint(10000, 20000) os.execvp('sh', [ 'sh', '-c', 'ssh -f -L "%s:%s:%s" "%s" %s && %s "%s%s@localhost:%s"' % (nport, host, port, via, viacommand, argv[0], user, (':%s' % password if password is not None else ''), nport) ]) # don't interrupt event thread's system calls signal.siginterrupt(signal.SIGINT, False) conndata = ConnectionData(host, port, user, password) client = NicosCmdClient(conndata) if command: return client.main_with_command(command) else: return client.main()
def main(argv): global log # pylint: disable=global-statement userpath = path.join(path.expanduser('~'), '.config', 'nicos') # Set up logging for the GUI instance. initLoggers() log = NicosLogger('gui') log.parent = None log.setLevel(logging.INFO) log.addHandler(ColoredConsoleHandler()) log.addHandler( NicosLogfileHandler(path.join(userpath, 'log'), 'gui', use_subdir=False)) # set up logging for unhandled exceptions in Qt callbacks def log_unhandled(*exc_info): traceback.print_exception(*exc_info) log.exception('unhandled exception in QT callback', exc_info=exc_info) sys.excepthook = log_unhandled app = QApplication(argv, organizationName='nicos', applicationName='gui') opts = parseargs() if opts.configfile is None: try: config.apply() except RuntimeError: pass # If "demo" is detected automatically, let the user choose their # instrument configuration. need_dialog = config.instrument is None or \ (config.setup_package == 'nicos_demo' and config.instrument == 'demo' and 'INSTRUMENT' not in os.environ) if need_dialog: opts.configfile = InstrSelectDialog.select( 'Your instrument could not be automatically detected.') if opts.configfile is None: return else: opts.configfile = path.join(config.setup_package_path, config.instrument, 'guiconfig.py') with open(opts.configfile, 'rb') as fp: configcode = fp.read() gui_conf = processGuiConfig(configcode) gui_conf.stylefile = '' if gui_conf.options.get('facility') in ['ess', 'sinq']: gui_conf.stylefile = f"{config.nicos_root}" \ f"/nicos/clients/flowui/guiconfig.qss" stylefiles = [ path.join(userpath, 'style-%s.qss' % sys.platform), path.join(userpath, 'style.qss'), path.splitext(opts.configfile)[0] + '-%s.qss' % sys.platform, path.splitext(opts.configfile)[0] + '.qss', ] for stylefile in [gui_conf.stylefile] or stylefiles: if path.isfile(stylefile): try: with open(stylefile, 'r', encoding='utf-8') as fd: app.setStyleSheet(fd.read()) gui_conf.stylefile = stylefile break except Exception: log.warning('Error setting user style sheet from %s', stylefile, exc=1) mainwindow_cls = _mainwindow_cls.get( gui_conf.options.get('facility', 'default')) mainwindow = mainwindow_cls(log, gui_conf, opts.viewonly, opts.tunnel) log.addHandler(DebugHandler(mainwindow)) if opts.connect: parsed = parseConnectionString(opts.connect, DEFAULT_PORT) if parsed: cdata = ConnectionData(**parsed) cdata.viewonly = opts.viewonly mainwindow.setConnData(cdata) if cdata.password is not None: # we have a password, connect right away mainwindow.client.connect(mainwindow.conndata) else: # we need to ask for password, override last preset (uses given # connection data) and force showing connect window mainwindow.lastpreset = '' mainwindow.autoconnect = True mainwindow.startup() return app.exec_()