mirror of
https://github.com/powerline/powerline.git
synced 2025-07-31 01:35:40 +02:00
Merge pull request #1642 from ZyX-I/wm-daemon
Use powerline daemon for running awesome bindings
This commit is contained in:
commit
5fa504118e
@ -215,6 +215,13 @@ Common configuration is a subdictionary that is a value of ``ext`` key in
|
|||||||
|
|
||||||
All components are enabled by default.
|
All components are enabled by default.
|
||||||
|
|
||||||
|
.. _config-ext-update_interval:
|
||||||
|
|
||||||
|
``update_interval``
|
||||||
|
Determines how often WM status bars need to be updated, in seconds. Only
|
||||||
|
valid for WM extensions which use ``powerline-daemon``. Defaults to
|
||||||
|
2 seconds.
|
||||||
|
|
||||||
.. _config-colors:
|
.. _config-colors:
|
||||||
|
|
||||||
Color definitions
|
Color definitions
|
||||||
|
@ -419,6 +419,11 @@ def _get_log_keys(common_config):
|
|||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_UPDATE_INTERVAL = 2
|
||||||
|
'''Default value for :ref:`update_interval <config-ext-update_interval>`
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
class Powerline(object):
|
class Powerline(object):
|
||||||
'''Main powerline class, entrance point for all powerline uses. Sets
|
'''Main powerline class, entrance point for all powerline uses. Sets
|
||||||
powerline up and loads the configuration.
|
powerline up and loads the configuration.
|
||||||
@ -514,6 +519,7 @@ class Powerline(object):
|
|||||||
self.setup_args = ()
|
self.setup_args = ()
|
||||||
self.setup_kwargs = {}
|
self.setup_kwargs = {}
|
||||||
self.imported_modules = set()
|
self.imported_modules = set()
|
||||||
|
self.update_interval = DEFAULT_UPDATE_INTERVAL
|
||||||
|
|
||||||
get_encoding = staticmethod(get_preferred_output_encoding)
|
get_encoding = staticmethod(get_preferred_output_encoding)
|
||||||
'''Get encoding used by the current application
|
'''Get encoding used by the current application
|
||||||
@ -638,6 +644,7 @@ class Powerline(object):
|
|||||||
or self.ext_config.get('local_themes') != self.prev_ext_config.get('local_themes')
|
or self.ext_config.get('local_themes') != self.prev_ext_config.get('local_themes')
|
||||||
):
|
):
|
||||||
self.renderer_options['local_themes'] = self.get_local_themes(self.ext_config.get('local_themes'))
|
self.renderer_options['local_themes'] = self.get_local_themes(self.ext_config.get('local_themes'))
|
||||||
|
self.update_interval = self.ext_config.get('update_interval', 2)
|
||||||
load_colorscheme = (
|
load_colorscheme = (
|
||||||
load_colorscheme
|
load_colorscheme
|
||||||
or not self.prev_ext_config
|
or not self.prev_ext_config
|
||||||
|
@ -4,38 +4,17 @@ from __future__ import (unicode_literals, division, absolute_import, print_funct
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from time import sleep
|
from powerline.bindings.wm import DEFAULT_UPDATE_INTERVAL
|
||||||
from subprocess import Popen, PIPE
|
from powerline.bindings.wm.awesome import run
|
||||||
|
|
||||||
from powerline import Powerline
|
|
||||||
from powerline.lib.monotonic import monotonic
|
|
||||||
|
|
||||||
powerline = Powerline('wm', renderer_module='pango_markup')
|
|
||||||
powerline.update_renderer()
|
|
||||||
|
|
||||||
try:
|
|
||||||
interval = float(sys.argv[1])
|
|
||||||
except IndexError:
|
|
||||||
interval = 2
|
|
||||||
|
|
||||||
|
|
||||||
def read_to_log(pl, client):
|
def main():
|
||||||
for line in client.stdout:
|
try:
|
||||||
if line:
|
interval = float(sys.argv[1])
|
||||||
pl.info(line, prefix='awesome-client')
|
except IndexError:
|
||||||
for line in client.stderr:
|
interval = DEFAULT_UPDATE_INTERVAL
|
||||||
if line:
|
run(interval=interval)
|
||||||
pl.error(line, prefix='awesome-client')
|
|
||||||
if client.wait():
|
|
||||||
pl.error('Client exited with {0}', client.returncode, prefix='awesome')
|
|
||||||
|
|
||||||
|
|
||||||
while True:
|
if __name__ == '__main__':
|
||||||
start_time = monotonic()
|
main()
|
||||||
s = powerline.render(side='right')
|
|
||||||
request = 'powerline_widget:set_markup(\'' + s.replace('\\', '\\\\').replace('\'', '\\\'') + '\')\n'
|
|
||||||
client = Popen(['awesome-client'], shell=False, stdout=PIPE, stderr=PIPE, stdin=PIPE)
|
|
||||||
client.stdin.write(request.encode('utf-8'))
|
|
||||||
client.stdin.close()
|
|
||||||
read_to_log(powerline.pl, client)
|
|
||||||
sleep(max(interval - (monotonic() - start_time), 0.1))
|
|
||||||
|
@ -6,6 +6,5 @@ powerline_widget:set_align('right')
|
|||||||
|
|
||||||
function powerline(mode, widget) end
|
function powerline(mode, widget) end
|
||||||
|
|
||||||
bindings_path = string.gsub(debug.getinfo(1).source:match('@(.*)$'), '/[^/]+$', '')
|
awful.util.spawn_with_shell('powerline-daemon -q')
|
||||||
powerline_cmd = bindings_path .. '/powerline-awesome.py'
|
awful.util.spawn_with_shell('powerline wm.awesome')
|
||||||
awful.util.spawn_with_shell('ps -C powerline-awesome.py || ' .. powerline_cmd)
|
|
||||||
|
@ -11,6 +11,7 @@ from argparse import ArgumentParser
|
|||||||
|
|
||||||
from powerline.lemonbar import LemonbarPowerline
|
from powerline.lemonbar import LemonbarPowerline
|
||||||
from powerline.lib.encoding import get_unicode_writer
|
from powerline.lib.encoding import get_unicode_writer
|
||||||
|
from powerline.bindings.wm import DEFAULT_UPDATE_INTERVAL
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
@ -29,7 +30,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
def render(reschedule=False):
|
def render(reschedule=False):
|
||||||
if reschedule:
|
if reschedule:
|
||||||
Timer(0.5, render, kwargs={'reschedule': True}).start()
|
Timer(DEFAULT_UPDATE_INTERVAL, render, kwargs={'reschedule': True}).start()
|
||||||
|
|
||||||
global lock
|
global lock
|
||||||
with lock:
|
with lock:
|
||||||
|
@ -99,7 +99,7 @@ class EmptyArgs(object):
|
|||||||
def init_tmux_environment(pl, args, set_tmux_environment=set_tmux_environment):
|
def init_tmux_environment(pl, args, set_tmux_environment=set_tmux_environment):
|
||||||
'''Initialize tmux environment from tmux configuration
|
'''Initialize tmux environment from tmux configuration
|
||||||
'''
|
'''
|
||||||
powerline = ShellPowerline(finish_args(os.environ, EmptyArgs('tmux', args.config_path)))
|
powerline = ShellPowerline(finish_args(None, os.environ, EmptyArgs('tmux', args.config_path)))
|
||||||
# TODO Move configuration files loading out of Powerline object and use it
|
# TODO Move configuration files loading out of Powerline object and use it
|
||||||
# directly
|
# directly
|
||||||
powerline.update_renderer()
|
powerline.update_renderer()
|
||||||
|
@ -5,6 +5,10 @@ import re
|
|||||||
|
|
||||||
from powerline.theme import requires_segment_info
|
from powerline.theme import requires_segment_info
|
||||||
from powerline.lib.shell import run_cmd
|
from powerline.lib.shell import run_cmd
|
||||||
|
from powerline.bindings.wm.awesome import AwesomeThread
|
||||||
|
|
||||||
|
|
||||||
|
DEFAULT_UPDATE_INTERVAL = 0.5
|
||||||
|
|
||||||
|
|
||||||
conn = None
|
conn = None
|
||||||
@ -36,3 +40,8 @@ def get_connected_xrandr_outputs(pl):
|
|||||||
return (match.groupdict() for match in XRANDR_OUTPUT_RE.finditer(
|
return (match.groupdict() for match in XRANDR_OUTPUT_RE.finditer(
|
||||||
run_cmd(pl, ['xrandr', '-q'])
|
run_cmd(pl, ['xrandr', '-q'])
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
wm_threads = {
|
||||||
|
'awesome': AwesomeThread,
|
||||||
|
}
|
||||||
|
59
powerline/bindings/wm/awesome.py
Normal file
59
powerline/bindings/wm/awesome.py
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
# vim:fileencoding=utf-8:noet
|
||||||
|
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from threading import Thread, Event
|
||||||
|
from time import sleep
|
||||||
|
from subprocess import Popen, PIPE
|
||||||
|
|
||||||
|
from powerline import Powerline
|
||||||
|
from powerline.lib.monotonic import monotonic
|
||||||
|
|
||||||
|
|
||||||
|
def read_to_log(pl, client):
|
||||||
|
for line in client.stdout:
|
||||||
|
if line:
|
||||||
|
pl.info(line, prefix='awesome-client')
|
||||||
|
for line in client.stderr:
|
||||||
|
if line:
|
||||||
|
pl.error(line, prefix='awesome-client')
|
||||||
|
if client.wait():
|
||||||
|
pl.error('Client exited with {0}', client.returncode, prefix='awesome')
|
||||||
|
|
||||||
|
|
||||||
|
def run(thread_shutdown_event=None, pl_shutdown_event=None, pl_config_loader=None,
|
||||||
|
interval=None):
|
||||||
|
powerline = Powerline(
|
||||||
|
'wm',
|
||||||
|
renderer_module='pango_markup',
|
||||||
|
shutdown_event=pl_shutdown_event,
|
||||||
|
config_loader=pl_config_loader,
|
||||||
|
)
|
||||||
|
powerline.update_renderer()
|
||||||
|
|
||||||
|
if not thread_shutdown_event:
|
||||||
|
thread_shutdown_event = powerline.shutdown_event
|
||||||
|
|
||||||
|
while not thread_shutdown_event.is_set():
|
||||||
|
# powerline.update_interval may change over time
|
||||||
|
used_interval = interval or powerline.update_interval
|
||||||
|
start_time = monotonic()
|
||||||
|
s = powerline.render(side='right')
|
||||||
|
request = 'powerline_widget:set_markup(\'' + s.translate({'\'': '\\\'', '\\': '\\\\'}) + '\')\n'
|
||||||
|
client = Popen(['awesome-client'], shell=False, stdout=PIPE, stderr=PIPE, stdin=PIPE)
|
||||||
|
client.stdin.write(request.encode('utf-8'))
|
||||||
|
client.stdin.close()
|
||||||
|
read_to_log(powerline.pl, client)
|
||||||
|
thread_shutdown_event.wait(max(used_interval - (monotonic() - start_time), 0.1))
|
||||||
|
|
||||||
|
|
||||||
|
class AwesomeThread(Thread):
|
||||||
|
__slots__ = ('powerline_shutdown_event',)
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super(AwesomeThread, self).__init__()
|
||||||
|
self.powerline_run_kwargs = kwargs
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
run(**self.powerline_run_kwargs)
|
@ -25,6 +25,11 @@ _powerline_tmux_pane() {
|
|||||||
echo "${TMUX_PANE:-`tmux display -p "#D"`}" | tr -d ' %'
|
echo "${TMUX_PANE:-`tmux display -p "#D"`}" | tr -d ' %'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_powerline_tmux_pane() {
|
||||||
|
local -x TMUX="$_POWERLINE_TMUX"
|
||||||
|
echo "${TMUX_PANE:-`tmux display -p "#D"`}" | tr -d ' %'
|
||||||
|
}
|
||||||
|
|
||||||
_powerline_init_tmux_support() {
|
_powerline_init_tmux_support() {
|
||||||
emulate -L zsh
|
emulate -L zsh
|
||||||
if test -n "$TMUX" && tmux refresh -S &>/dev/null ; then
|
if test -n "$TMUX" && tmux refresh -S &>/dev/null ; then
|
||||||
|
@ -11,6 +11,7 @@ from powerline.lib.overrides import parsedotval, parse_override_var
|
|||||||
from powerline.lib.dict import mergeargs
|
from powerline.lib.dict import mergeargs
|
||||||
from powerline.lib.encoding import get_preferred_arguments_encoding
|
from powerline.lib.encoding import get_preferred_arguments_encoding
|
||||||
from powerline.lib.unicode import u, unicode
|
from powerline.lib.unicode import u, unicode
|
||||||
|
from powerline.bindings.wm import wm_threads
|
||||||
|
|
||||||
|
|
||||||
if sys.version_info < (3,):
|
if sys.version_info < (3,):
|
||||||
@ -23,7 +24,7 @@ else:
|
|||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def finish_args(environ, args):
|
def finish_args(parser, environ, args, is_daemon=False):
|
||||||
'''Do some final transformations
|
'''Do some final transformations
|
||||||
|
|
||||||
Transforms ``*_override`` arguments into dictionaries, adding overrides from
|
Transforms ``*_override`` arguments into dictionaries, adding overrides from
|
||||||
@ -61,7 +62,13 @@ def finish_args(environ, args):
|
|||||||
[path for path in environ.get('POWERLINE_CONFIG_PATHS', '').split(':') if path]
|
[path for path in environ.get('POWERLINE_CONFIG_PATHS', '').split(':') if path]
|
||||||
+ (args.config_path or [])
|
+ (args.config_path or [])
|
||||||
)
|
)
|
||||||
args.side = args.side[0]
|
if args.ext[0].startswith('wm.'):
|
||||||
|
if not is_daemon:
|
||||||
|
parser.error('WM bindings must be used with daemon only')
|
||||||
|
elif args.ext[0][3:] not in wm_threads:
|
||||||
|
parser.error('WM binding not found')
|
||||||
|
elif not args.side:
|
||||||
|
parser.error('expected one argument')
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
|
||||||
@ -77,15 +84,16 @@ def get_argparser(ArgumentParser=argparse.ArgumentParser):
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'ext', nargs=1,
|
'ext', nargs=1,
|
||||||
help='Extension: application for which powerline command is launched '
|
help='Extension: application for which powerline command is launched '
|
||||||
'(usually `shell\' or `tmux\').'
|
'(usually `shell\' or `tmux\'). Also supports `wm.\' extensions: '
|
||||||
|
+ ', '.join(('`wm.' + key + '\'' for key in wm_threads.keys())) + '.'
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'side', nargs=1, choices=('left', 'right', 'above', 'aboveleft'),
|
'side', nargs='?', choices=('left', 'right', 'above', 'aboveleft'),
|
||||||
help='Side: `left\' and `right\' represent left and right side '
|
help='Side: `left\' and `right\' represent left and right side '
|
||||||
'respectively, `above\' emits lines that are supposed to be printed '
|
'respectively, `above\' emits lines that are supposed to be printed '
|
||||||
'just above the prompt and `aboveleft\' is like concatenating '
|
'just above the prompt and `aboveleft\' is like concatenating '
|
||||||
'`above\' with `left\' with the exception that only one Python '
|
'`above\' with `left\' with the exception that only one Python '
|
||||||
'instance is used in this case.'
|
'instance is used in this case. May be omitted for `wm.*\' extensions.'
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'-r', '--renderer-module', metavar='MODULE', type=str,
|
'-r', '--renderer-module', metavar='MODULE', type=str,
|
||||||
|
@ -46,7 +46,8 @@
|
|||||||
},
|
},
|
||||||
"wm": {
|
"wm": {
|
||||||
"colorscheme": "default",
|
"colorscheme": "default",
|
||||||
"theme": "default"
|
"theme": "default",
|
||||||
|
"update_interval": 2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,8 @@ main_spec = (Spec(
|
|||||||
local_themes=Spec().unknown_spec(
|
local_themes=Spec().unknown_spec(
|
||||||
Spec().re('^[0-9A-Za-z-]+$'),
|
Spec().re('^[0-9A-Za-z-]+$'),
|
||||||
ext_theme_spec()
|
ext_theme_spec()
|
||||||
).optional()
|
).optional(),
|
||||||
|
update_interval=Spec().cmp('gt', 0.0).optional(),
|
||||||
).optional(),
|
).optional(),
|
||||||
).unknown_spec(
|
).unknown_spec(
|
||||||
check_ext,
|
check_ext,
|
||||||
|
@ -6,6 +6,9 @@ import socket
|
|||||||
import os
|
import os
|
||||||
import errno
|
import errno
|
||||||
import sys
|
import sys
|
||||||
|
import fcntl
|
||||||
|
import atexit
|
||||||
|
import stat
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
from select import select
|
from select import select
|
||||||
@ -13,21 +16,21 @@ from signal import signal, SIGTERM
|
|||||||
from time import sleep
|
from time import sleep
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
from threading import Event
|
||||||
|
from itertools import chain
|
||||||
|
from logging import StreamHandler
|
||||||
|
|
||||||
from powerline.shell import ShellPowerline
|
from powerline.shell import ShellPowerline
|
||||||
from powerline.commands.main import finish_args, write_output
|
from powerline.commands.main import finish_args, write_output
|
||||||
from powerline.lib.monotonic import monotonic
|
from powerline.lib.monotonic import monotonic
|
||||||
from powerline.lib.encoding import get_preferred_output_encoding, get_preferred_arguments_encoding, get_unicode_writer
|
from powerline.lib.encoding import get_preferred_output_encoding, get_preferred_arguments_encoding, get_unicode_writer
|
||||||
|
from powerline.bindings.wm import wm_threads
|
||||||
|
|
||||||
from powerline.commands.main import get_argparser as get_main_argparser
|
from powerline.commands.main import get_argparser as get_main_argparser
|
||||||
from powerline.commands.daemon import get_argparser as get_daemon_argparser
|
from powerline.commands.daemon import get_argparser as get_daemon_argparser
|
||||||
|
|
||||||
|
|
||||||
is_daemon = False
|
USE_FILESYSTEM = not sys.platform.lower().startswith('linux')
|
||||||
use_filesystem = not sys.platform.lower().startswith('linux')
|
|
||||||
|
|
||||||
address = None
|
|
||||||
pidfile = None
|
|
||||||
|
|
||||||
|
|
||||||
class NonInteractiveArgParser(ArgumentParser):
|
class NonInteractiveArgParser(ArgumentParser):
|
||||||
@ -44,31 +47,48 @@ class NonInteractiveArgParser(ArgumentParser):
|
|||||||
raise Exception(self.format_usage())
|
raise Exception(self.format_usage())
|
||||||
|
|
||||||
|
|
||||||
parser = get_main_argparser(NonInteractiveArgParser)
|
|
||||||
|
|
||||||
EOF = b'EOF\0\0'
|
EOF = b'EOF\0\0'
|
||||||
|
|
||||||
powerlines = {}
|
|
||||||
logger = None
|
class State(object):
|
||||||
config_loader = None
|
__slots__ = ('powerlines', 'logger', 'config_loader', 'started_wm_threads',
|
||||||
home = os.path.expanduser('~')
|
'ts_shutdown_event')
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
self.logger = None
|
||||||
|
self.config_loader = None
|
||||||
|
self.started_wm_threads = {}
|
||||||
|
self.powerlines = {}
|
||||||
|
self.ts_shutdown_event = Event()
|
||||||
|
|
||||||
|
|
||||||
class PowerlineDaemon(ShellPowerline):
|
HOME = os.path.expanduser('~')
|
||||||
|
|
||||||
|
|
||||||
|
class NonDaemonShellPowerline(ShellPowerline):
|
||||||
def get_log_handler(self):
|
def get_log_handler(self):
|
||||||
if not is_daemon:
|
return StreamHandler()
|
||||||
import logging
|
|
||||||
return logging.StreamHandler()
|
|
||||||
return super(PowerlineDaemon, self).get_log_handler()
|
|
||||||
|
|
||||||
|
|
||||||
def render(args, environ, cwd):
|
def start_wm(args, environ, cwd, is_daemon, state):
|
||||||
global logger
|
wm_name = args.ext[0][3:]
|
||||||
global config_loader
|
if wm_name in state.started_wm_threads:
|
||||||
cwd = cwd or environ.get('PWD', '/')
|
return b''
|
||||||
|
thread_shutdown_event = Event()
|
||||||
|
thread = wm_threads[wm_name](
|
||||||
|
thread_shutdown_event=thread_shutdown_event,
|
||||||
|
pl_shutdown_event=state.ts_shutdown_event,
|
||||||
|
pl_config_loader=state.config_loader,
|
||||||
|
)
|
||||||
|
thread.start()
|
||||||
|
state.started_wm_threads[wm_name] = (thread, thread_shutdown_event)
|
||||||
|
return b''
|
||||||
|
|
||||||
|
|
||||||
|
def render(args, environ, cwd, is_daemon, state):
|
||||||
segment_info = {
|
segment_info = {
|
||||||
'getcwd': lambda: cwd,
|
'getcwd': lambda: cwd,
|
||||||
'home': environ.get('HOME', home),
|
'home': environ.get('HOME', HOME),
|
||||||
'environ': environ,
|
'environ': environ,
|
||||||
'args': args,
|
'args': args,
|
||||||
}
|
}
|
||||||
@ -82,22 +102,24 @@ def render(args, environ, cwd):
|
|||||||
environ.get('POWERLINE_CONFIG_OVERRIDES', ''),
|
environ.get('POWERLINE_CONFIG_OVERRIDES', ''),
|
||||||
environ.get('POWERLINE_CONFIG_PATHS', ''),
|
environ.get('POWERLINE_CONFIG_PATHS', ''),
|
||||||
)
|
)
|
||||||
finish_args(environ, args)
|
|
||||||
|
PowerlineClass = ShellPowerline if is_daemon else NonDaemonShellPowerline
|
||||||
powerline = None
|
powerline = None
|
||||||
try:
|
try:
|
||||||
powerline = powerlines[key]
|
powerline = state.powerlines[key]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
try:
|
try:
|
||||||
powerline = powerlines[key] = PowerlineDaemon(
|
powerline = state.powerlines[key] = PowerlineClass(
|
||||||
args,
|
args,
|
||||||
logger=logger,
|
logger=state.logger,
|
||||||
config_loader=config_loader,
|
config_loader=state.config_loader,
|
||||||
run_once=False,
|
run_once=False,
|
||||||
|
shutdown_event=state.ts_shutdown_event,
|
||||||
)
|
)
|
||||||
if logger is None:
|
if state.logger is None:
|
||||||
logger = powerline.logger
|
state.logger = powerline.logger
|
||||||
if config_loader is None:
|
if state.config_loader is None:
|
||||||
config_loader = powerline.config_loader
|
state.config_loader = powerline.config_loader
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
# Somebody thought raising system exit was a good idea,
|
# Somebody thought raising system exit was a good idea,
|
||||||
return ''
|
return ''
|
||||||
@ -168,23 +190,30 @@ def safe_bytes(o, encoding=get_preferred_output_encoding()):
|
|||||||
return safe_bytes(str(e), encoding)
|
return safe_bytes(str(e), encoding)
|
||||||
|
|
||||||
|
|
||||||
def parse_args(req, encoding=get_preferred_arguments_encoding()):
|
def parse_args(req, parser, encoding=get_preferred_arguments_encoding()):
|
||||||
args = [x.decode(encoding) for x in req.split(b'\0') if x]
|
args = [x.decode(encoding) for x in req.split(b'\0') if x]
|
||||||
numargs = int(args[0], 16)
|
numargs = int(args[0], 16)
|
||||||
shell_args = parser.parse_args(args[1:numargs + 1])
|
shell_args = parser.parse_args(args[1:numargs + 1])
|
||||||
cwd = args[numargs + 1]
|
cwd = args[numargs + 1]
|
||||||
environ = dict(((k, v) for k, v in (x.partition('=')[0::2] for x in args[numargs + 2:])))
|
environ = dict(((k, v) for k, v in (x.partition('=')[0::2] for x in args[numargs + 2:])))
|
||||||
|
cwd = cwd or environ.get('PWD', '/')
|
||||||
return shell_args, environ, cwd
|
return shell_args, environ, cwd
|
||||||
|
|
||||||
|
|
||||||
def do_render(req):
|
def get_answer(req, is_daemon, argparser, state):
|
||||||
try:
|
try:
|
||||||
return safe_bytes(render(*parse_args(req)))
|
args, environ, cwd = parse_args(req, argparser)
|
||||||
|
finish_args(argparser, environ, args, is_daemon=True)
|
||||||
|
if args.ext[0].startswith('wm.'):
|
||||||
|
return safe_bytes(start_wm(args, environ, cwd, is_daemon, state))
|
||||||
|
else:
|
||||||
|
return safe_bytes(render(args, environ, cwd, is_daemon, state))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return safe_bytes(str(e))
|
return safe_bytes(str(e))
|
||||||
|
|
||||||
|
|
||||||
def do_one(sock, read_sockets, write_sockets, result_map):
|
def do_one(sock, read_sockets, write_sockets, result_map, is_daemon, argparser,
|
||||||
|
state):
|
||||||
r, w, e = select(
|
r, w, e = select(
|
||||||
tuple(read_sockets) + (sock,),
|
tuple(read_sockets) + (sock,),
|
||||||
tuple(write_sockets),
|
tuple(write_sockets),
|
||||||
@ -214,7 +243,7 @@ def do_one(sock, read_sockets, write_sockets, result_map):
|
|||||||
if req == EOF:
|
if req == EOF:
|
||||||
raise SystemExit(0)
|
raise SystemExit(0)
|
||||||
elif req:
|
elif req:
|
||||||
ans = do_render(req)
|
ans = get_answer(req, is_daemon, argparser, state)
|
||||||
result_map[s] = ans
|
result_map[s] = ans
|
||||||
write_sockets.add(s)
|
write_sockets.add(s)
|
||||||
else:
|
else:
|
||||||
@ -230,17 +259,61 @@ def do_one(sock, read_sockets, write_sockets, result_map):
|
|||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
|
|
||||||
def main_loop(sock):
|
def shutdown(sock, read_sockets, write_sockets, state):
|
||||||
|
'''Perform operations necessary for nicely shutting down daemon
|
||||||
|
|
||||||
|
Specifically it
|
||||||
|
|
||||||
|
#. Closes all sockets.
|
||||||
|
#. Notifies segments based on
|
||||||
|
:py:class:`powerline.lib.threaded.ThreadedSegment` and WM-specific
|
||||||
|
threads that daemon is shutting down.
|
||||||
|
#. Waits for threads to finish, but no more then 2 seconds total.
|
||||||
|
#. Waits so that total execution time of this function is 2 seconds in order
|
||||||
|
to allow ThreadedSegments to finish.
|
||||||
|
'''
|
||||||
|
total_wait_time = 2
|
||||||
|
shutdown_start_time = monotonic()
|
||||||
|
|
||||||
|
for s in chain((sock,), read_sockets, write_sockets):
|
||||||
|
s.close()
|
||||||
|
|
||||||
|
# Notify ThreadedSegments
|
||||||
|
state.ts_shutdown_event.set()
|
||||||
|
for thread, shutdown_event in state.started_wm_threads.values():
|
||||||
|
shutdown_event.set()
|
||||||
|
|
||||||
|
for thread, shutdown_event in state.started_wm_threads.values():
|
||||||
|
wait_time = total_wait_time - (monotonic() - shutdown_start_time)
|
||||||
|
if wait_time > 0:
|
||||||
|
thread.join(wait_time)
|
||||||
|
|
||||||
|
wait_time = total_wait_time - (monotonic() - shutdown_start_time)
|
||||||
|
sleep(wait_time)
|
||||||
|
|
||||||
|
|
||||||
|
def main_loop(sock, is_daemon):
|
||||||
sock.listen(128)
|
sock.listen(128)
|
||||||
sock.setblocking(0)
|
sock.setblocking(0)
|
||||||
|
|
||||||
read_sockets, write_sockets = set(), set()
|
read_sockets, write_sockets = set(), set()
|
||||||
result_map = {}
|
result_map = {}
|
||||||
|
parser = get_main_argparser(NonInteractiveArgParser)
|
||||||
|
state = State()
|
||||||
try:
|
try:
|
||||||
while True:
|
try:
|
||||||
do_one(sock, read_sockets, write_sockets, result_map)
|
while True:
|
||||||
except KeyboardInterrupt:
|
do_one(
|
||||||
raise SystemExit(0)
|
sock, read_sockets, write_sockets, result_map,
|
||||||
|
is_daemon=is_daemon,
|
||||||
|
argparser=parser,
|
||||||
|
state=state,
|
||||||
|
)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
raise SystemExit(0)
|
||||||
|
except SystemExit as e:
|
||||||
|
shutdown(sock, read_sockets, write_sockets, state)
|
||||||
|
raise e
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
|
|
||||||
@ -249,10 +322,10 @@ def daemonize(stdin=os.devnull, stdout=os.devnull, stderr=os.devnull):
|
|||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
if pid > 0:
|
if pid > 0:
|
||||||
# exit first parent
|
# exit first parent
|
||||||
sys.exit(0)
|
raise SystemExit(0)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
|
sys.stderr.write("fork #1 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||||
sys.exit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
# decouple from parent environment
|
# decouple from parent environment
|
||||||
os.chdir("/")
|
os.chdir("/")
|
||||||
@ -264,10 +337,10 @@ def daemonize(stdin=os.devnull, stdout=os.devnull, stderr=os.devnull):
|
|||||||
pid = os.fork()
|
pid = os.fork()
|
||||||
if pid > 0:
|
if pid > 0:
|
||||||
# exit from second parent
|
# exit from second parent
|
||||||
sys.exit(0)
|
raise SystemExit(0)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
|
sys.stderr.write("fork #2 failed: %d (%s)\n" % (e.errno, e.strerror))
|
||||||
sys.exit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
# Redirect standard file descriptors.
|
# Redirect standard file descriptors.
|
||||||
si = open(stdin, 'rb')
|
si = open(stdin, 'rb')
|
||||||
@ -276,12 +349,11 @@ def daemonize(stdin=os.devnull, stdout=os.devnull, stderr=os.devnull):
|
|||||||
os.dup2(si.fileno(), sys.stdin.fileno())
|
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||||
os.dup2(so.fileno(), sys.stdout.fileno())
|
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||||
os.dup2(se.fileno(), sys.stderr.fileno())
|
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||||
global is_daemon
|
return True
|
||||||
is_daemon = True
|
|
||||||
|
|
||||||
|
|
||||||
def check_existing():
|
def check_existing(address):
|
||||||
if use_filesystem:
|
if USE_FILESYSTEM:
|
||||||
# We cannot bind if the socket file already exists so remove it, we
|
# We cannot bind if the socket file already exists so remove it, we
|
||||||
# already have a lock on pidfile, so this should be safe.
|
# already have a lock on pidfile, so this should be safe.
|
||||||
try:
|
try:
|
||||||
@ -299,7 +371,7 @@ def check_existing():
|
|||||||
return sock
|
return sock
|
||||||
|
|
||||||
|
|
||||||
def kill_daemon():
|
def kill_daemon(address):
|
||||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
@ -313,7 +385,7 @@ def kill_daemon():
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def cleanup_lockfile(fd, *args):
|
def cleanup_lockfile(pidfile, fd, *args):
|
||||||
try:
|
try:
|
||||||
# Remove the directory entry for the lock file
|
# Remove the directory entry for the lock file
|
||||||
os.unlink(pidfile)
|
os.unlink(pidfile)
|
||||||
@ -326,10 +398,7 @@ def cleanup_lockfile(fd, *args):
|
|||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
|
|
||||||
def lockpidfile():
|
def lockpidfile(pidfile):
|
||||||
import fcntl
|
|
||||||
import atexit
|
|
||||||
import stat
|
|
||||||
fd = os.open(
|
fd = os.open(
|
||||||
pidfile,
|
pidfile,
|
||||||
os.O_WRONLY | os.O_CREAT,
|
os.O_WRONLY | os.O_CREAT,
|
||||||
@ -344,24 +413,25 @@ def lockpidfile():
|
|||||||
os.ftruncate(fd, 0)
|
os.ftruncate(fd, 0)
|
||||||
os.write(fd, ('%d' % os.getpid()).encode('ascii'))
|
os.write(fd, ('%d' % os.getpid()).encode('ascii'))
|
||||||
os.fsync(fd)
|
os.fsync(fd)
|
||||||
cleanup = partial(cleanup_lockfile, fd)
|
cleanup = partial(cleanup_lockfile, pidfile, fd)
|
||||||
signal(SIGTERM, cleanup)
|
signal(SIGTERM, cleanup)
|
||||||
atexit.register(cleanup)
|
atexit.register(cleanup)
|
||||||
return fd
|
return fd
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
global address
|
|
||||||
global pidfile
|
|
||||||
parser = get_daemon_argparser()
|
parser = get_daemon_argparser()
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
is_daemon = False
|
||||||
|
address = None
|
||||||
|
pidfile = None
|
||||||
|
|
||||||
if args.socket:
|
if args.socket:
|
||||||
address = args.socket
|
address = args.socket
|
||||||
if not use_filesystem:
|
if not USE_FILESYSTEM:
|
||||||
address = '\0' + address
|
address = '\0' + address
|
||||||
else:
|
else:
|
||||||
if use_filesystem:
|
if USE_FILESYSTEM:
|
||||||
address = '/tmp/powerline-ipc-%d'
|
address = '/tmp/powerline-ipc-%d'
|
||||||
else:
|
else:
|
||||||
# Use the abstract namespace for sockets rather than the filesystem
|
# Use the abstract namespace for sockets rather than the filesystem
|
||||||
@ -370,13 +440,13 @@ def main():
|
|||||||
|
|
||||||
address = address % os.getuid()
|
address = address % os.getuid()
|
||||||
|
|
||||||
if use_filesystem:
|
if USE_FILESYSTEM:
|
||||||
pidfile = address + '.pid'
|
pidfile = address + '.pid'
|
||||||
|
|
||||||
if args.kill:
|
if args.kill:
|
||||||
if args.foreground or args.replace:
|
if args.foreground or args.replace:
|
||||||
parser.error('--kill and --foreground/--replace cannot be used together')
|
parser.error('--kill and --foreground/--replace cannot be used together')
|
||||||
if kill_daemon():
|
if kill_daemon(address):
|
||||||
if not args.quiet:
|
if not args.quiet:
|
||||||
print ('Kill command sent to daemon, if it does not die in a couple of seconds use kill to kill it')
|
print ('Kill command sent to daemon, if it does not die in a couple of seconds use kill to kill it')
|
||||||
raise SystemExit(0)
|
raise SystemExit(0)
|
||||||
@ -386,19 +456,19 @@ def main():
|
|||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
if args.replace:
|
if args.replace:
|
||||||
while kill_daemon():
|
while kill_daemon(address):
|
||||||
if not args.quiet:
|
if not args.quiet:
|
||||||
print ('Kill command sent to daemon, waiting for daemon to exit, press Ctrl-C to terminate wait and exit')
|
print ('Kill command sent to daemon, waiting for daemon to exit, press Ctrl-C to terminate wait and exit')
|
||||||
sleep(2)
|
sleep(2)
|
||||||
|
|
||||||
if use_filesystem and not args.foreground:
|
if USE_FILESYSTEM and not args.foreground:
|
||||||
# We must daemonize before creating the locked pidfile, unfortunately,
|
# We must daemonize before creating the locked pidfile, unfortunately,
|
||||||
# this means further print statements are discarded
|
# this means further print statements are discarded
|
||||||
daemonize()
|
is_daemon = daemonize()
|
||||||
|
|
||||||
if use_filesystem:
|
if USE_FILESYSTEM:
|
||||||
# Create a locked pid file containing the daemon’s PID
|
# Create a locked pid file containing the daemon’s PID
|
||||||
if lockpidfile() is None:
|
if lockpidfile(pidfile) is None:
|
||||||
if not args.quiet:
|
if not args.quiet:
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
'The daemon is already running. Use %s -k to kill it.\n' % (
|
'The daemon is already running. Use %s -k to kill it.\n' % (
|
||||||
@ -406,7 +476,7 @@ def main():
|
|||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
# Bind to address or bail if we cannot bind
|
# Bind to address or bail if we cannot bind
|
||||||
sock = check_existing()
|
sock = check_existing(address)
|
||||||
if sock is None:
|
if sock is None:
|
||||||
if not args.quiet:
|
if not args.quiet:
|
||||||
sys.stderr.write(
|
sys.stderr.write(
|
||||||
@ -414,14 +484,11 @@ def main():
|
|||||||
os.path.basename(sys.argv[0])))
|
os.path.basename(sys.argv[0])))
|
||||||
raise SystemExit(1)
|
raise SystemExit(1)
|
||||||
|
|
||||||
if args.foreground:
|
if not USE_FILESYSTEM and not args.foreground:
|
||||||
return main_loop(sock)
|
|
||||||
|
|
||||||
if not use_filesystem:
|
|
||||||
# We daemonize on linux
|
# We daemonize on linux
|
||||||
daemonize()
|
is_daemon = daemonize()
|
||||||
|
|
||||||
main_loop(sock)
|
return main_loop(sock, is_daemon)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -23,8 +23,9 @@ else:
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
args = get_argparser().parse_args()
|
parser = get_argparser()
|
||||||
finish_args(os.environ, args)
|
args = parser.parse_args()
|
||||||
|
finish_args(parser, os.environ, args)
|
||||||
powerline = ShellPowerline(args, run_once=True)
|
powerline = ShellPowerline(args, run_once=True)
|
||||||
segment_info = {'args': args, 'environ': os.environ}
|
segment_info = {'args': args, 'environ': os.environ}
|
||||||
write_output(args, powerline, segment_info, get_unicode_writer())
|
write_output(args, powerline, segment_info, get_unicode_writer())
|
||||||
|
193
tests/run_awesome_tests.sh
Executable file
193
tests/run_awesome_tests.sh
Executable file
@ -0,0 +1,193 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
. tests/common.sh
|
||||||
|
|
||||||
|
enter_suite awesome
|
||||||
|
|
||||||
|
TEST_ROOT="$ROOT/tests/awesome"
|
||||||
|
TEST_PATH="$TEST_ROOT/path"
|
||||||
|
TEST_STATIC_ROOT="$ROOT/tests/test_awesome"
|
||||||
|
|
||||||
|
test -d "$TEST_ROOT" && rm -r "$TEST_ROOT"
|
||||||
|
mkdir "$TEST_ROOT"
|
||||||
|
cp -r "$TEST_STATIC_ROOT/path" "$TEST_ROOT"
|
||||||
|
cp -r "$TEST_STATIC_ROOT/powerline" "$TEST_ROOT"
|
||||||
|
|
||||||
|
export PYTHONPATH="$ROOT${PYTHONPATH:+:}$PYTHONPATH"
|
||||||
|
|
||||||
|
ln -s "$(which "${PYTHON}")" "$TEST_PATH"/python
|
||||||
|
ln -s "$(which cat)" "$TEST_PATH"
|
||||||
|
ln -s "$(which sh)" "$TEST_PATH"
|
||||||
|
ln -s "$(which env)" "$TEST_PATH"
|
||||||
|
if which socat ; then
|
||||||
|
ln -s "$(which socat)" "$TEST_PATH"
|
||||||
|
fi
|
||||||
|
for pexe in powerline powerline.sh powerline.py ; do
|
||||||
|
if test -e scripts/$pexe ; then
|
||||||
|
ln -s "$PWD/scripts/$pexe" $TEST_ROOT/path
|
||||||
|
elif test -e client/$pexe ; then
|
||||||
|
ln -s "$PWD/client/$pexe" $TEST_ROOT/path
|
||||||
|
elif which $pexe ; then
|
||||||
|
ln -s "$(which $pexe)" $TEST_ROOT/path
|
||||||
|
else
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
if test "x$pexe" != 'xpowerline.sh' || test -e "$TEST_PATH/socat" ; then
|
||||||
|
POWERLINE_COMMAND="$pexe"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
DEPRECATED_SCRIPT="$ROOT/powerline/bindings/awesome/powerline-awesome.py"
|
||||||
|
POWERLINE_DAEMON="scripts/powerline-daemon"
|
||||||
|
|
||||||
|
run() {
|
||||||
|
env -i \
|
||||||
|
LANG=C \
|
||||||
|
PATH="$TEST_PATH" \
|
||||||
|
XDG_CONFIG_HOME="$TEST_ROOT" \
|
||||||
|
XDG_CONFIG_DIRS="$TEST_ROOT/dummy" \
|
||||||
|
PYTHONPATH="$PYTHONPATH" \
|
||||||
|
TEST_ROOT="$TEST_ROOT" \
|
||||||
|
LD_LIBRARY_PATH="$LD_LIBRARY_PATH" \
|
||||||
|
"$@" || true
|
||||||
|
}
|
||||||
|
|
||||||
|
display_log() {
|
||||||
|
local log_file="$1"
|
||||||
|
echo "$log_file:"
|
||||||
|
echo '============================================================'
|
||||||
|
cat -v "$log_file"
|
||||||
|
echo
|
||||||
|
echo '____________________________________________________________'
|
||||||
|
}
|
||||||
|
|
||||||
|
check_log() {
|
||||||
|
local args_file="$TEST_ROOT/results/args"
|
||||||
|
local log_file="$TEST_ROOT/results/requests"
|
||||||
|
local line="$(head -n1 "$log_file")"
|
||||||
|
local linenum="$(cat "$log_file" | wc -l)"
|
||||||
|
echo "Number of runs: $linenum (expected approx 5 / 0.5 = 10 runs)"
|
||||||
|
if test $linenum -lt 5 ; then
|
||||||
|
fail "log:lt" F "Script was run not enough times: $linenum < 5"
|
||||||
|
return 1
|
||||||
|
elif test $linenum -gt 15 ; then
|
||||||
|
fail "log:gt" E "Script was run too many times: $linenum > 15"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local expline="powerline_widget:set_markup('<span foreground=\"#303030\"> </span><span foreground=\"#d0d0d0\" background=\"#303030\" font_weight=\"bold\"> default-right </span>')"
|
||||||
|
if test "x$expline" != "x$line" ; then
|
||||||
|
echo "Line: '$line'"
|
||||||
|
echo "Expected: '$expline'"
|
||||||
|
fail "log:line" F "Unexpected line"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
local ret=0
|
||||||
|
while test $linenum -gt 0 ; do
|
||||||
|
echo "$line" >> "$TEST_ROOT/ok"
|
||||||
|
linenum=$(( linenum - 1 ))
|
||||||
|
done
|
||||||
|
if ! diff "$TEST_ROOT/ok" "$log_file" ; then
|
||||||
|
fail "log:diff" F "Unexpected output"
|
||||||
|
ret=1
|
||||||
|
fi
|
||||||
|
rm "$TEST_ROOT/ok"
|
||||||
|
return $ret
|
||||||
|
}
|
||||||
|
|
||||||
|
killscript() {
|
||||||
|
kill -KILL $1 || true
|
||||||
|
}
|
||||||
|
|
||||||
|
if ! test -e "$DEPRECATED_SCRIPT" ; then
|
||||||
|
# TODO: uncomment when skip is available
|
||||||
|
# skip "deprecated" "Missing deprecated bar bindings script"
|
||||||
|
:
|
||||||
|
else
|
||||||
|
enter_suite "deprecated"
|
||||||
|
for args in "" "0.5"; do
|
||||||
|
rm -rf "$TEST_ROOT/results"
|
||||||
|
mkdir "$TEST_ROOT/results"
|
||||||
|
DEPRECATED_LOG="$TEST_ROOT/deprecated.log"
|
||||||
|
run env \
|
||||||
|
DEPRECATED_SCRIPT="$DEPRECATED_SCRIPT" \
|
||||||
|
args="$args" \
|
||||||
|
DEPRECATED_LOG="$DEPRECATED_LOG" \
|
||||||
|
TEST_ROOT="$TEST_ROOT" \
|
||||||
|
sh -c '
|
||||||
|
echo $$ > "$TEST_ROOT/$args-pid"
|
||||||
|
exec "$DEPRECATED_SCRIPT" $args > "$DEPRECATED_LOG" 2>&1
|
||||||
|
' &
|
||||||
|
sleep 5
|
||||||
|
killscript "$(cat "$TEST_ROOT/$args-pid")"
|
||||||
|
rm "$TEST_ROOT/$args-pid"
|
||||||
|
if test "x$(cat "$DEPRECATED_LOG")" != "x" ; then
|
||||||
|
display_log "$DEPRECATED_LOG"
|
||||||
|
fail "output" E "Nonempty $DEPRECATED_SCRIPT output"
|
||||||
|
fi
|
||||||
|
rm "$DEPRECATED_LOG"
|
||||||
|
if ! check_log ; then
|
||||||
|
display_log "$TEST_ROOT/results/args"
|
||||||
|
fail "log" F "Checking log failed"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
exit_suite --continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
enter_suite "awesome"
|
||||||
|
ADDRESS="powerline-ipc-test-$$"
|
||||||
|
echo "Powerline address: $ADDRESS"
|
||||||
|
rm -rf "$TEST_ROOT/results"
|
||||||
|
mkdir "$TEST_ROOT/results"
|
||||||
|
run env \
|
||||||
|
POWERLINE_DAEMON="$POWERLINE_DAEMON" \
|
||||||
|
TEST_ROOT="$TEST_ROOT" \
|
||||||
|
ADDRESS="$ADDRESS" \
|
||||||
|
sh -c '
|
||||||
|
echo $$ > "$TEST_ROOT/dpid"
|
||||||
|
exec python "$POWERLINE_DAEMON" --socket $ADDRESS --foreground > "$TEST_ROOT/daemon.log" 2>&1
|
||||||
|
' &
|
||||||
|
DPID=$!
|
||||||
|
sleep 2
|
||||||
|
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.1" 2>&1
|
||||||
|
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.2" 2>&1
|
||||||
|
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.3" 2>&1
|
||||||
|
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.4" 2>&1
|
||||||
|
run "$POWERLINE_COMMAND" --socket $ADDRESS wm.awesome > "$TEST_ROOT/output.log.5" 2>&1
|
||||||
|
for log_file in "$TEST_ROOT"/output.log.* ; do
|
||||||
|
if test "x$(cat "$log_file")" != "x" ; then
|
||||||
|
display_log "$log_file"
|
||||||
|
fail "output" E "Nonempty $POWERLINE_COMMAND output at run ${log_file#*.}"
|
||||||
|
fi
|
||||||
|
rm "$log_file"
|
||||||
|
done
|
||||||
|
sleep 5
|
||||||
|
run python "$POWERLINE_DAEMON" --socket $ADDRESS --quiet --kill > "$TEST_ROOT/kill.log" 2>&1
|
||||||
|
if test "x$(cat "$TEST_ROOT/kill.log")" != "x" ; then
|
||||||
|
display_log "$TEST_ROOT/kill.log"
|
||||||
|
fail "daemonlog" E "Nonempty kill log"
|
||||||
|
fi
|
||||||
|
rm "$TEST_ROOT/kill.log"
|
||||||
|
wait $DPID
|
||||||
|
if test "x$(cat "$TEST_ROOT/daemon.log")" != "x" ; then
|
||||||
|
display_log "$TEST_ROOT/daemon.log"
|
||||||
|
fail "daemonlog" E "Nonempty daemon log"
|
||||||
|
fi
|
||||||
|
rm "$TEST_ROOT/daemon.log"
|
||||||
|
if ! check_log ; then
|
||||||
|
display_log "$TEST_ROOT/results/args"
|
||||||
|
fail "log" F "Checking log failed"
|
||||||
|
fi
|
||||||
|
exit_suite --continue
|
||||||
|
|
||||||
|
if ! powerline-lint \
|
||||||
|
-p "$ROOT/powerline/config_files" \
|
||||||
|
-p "$TEST_STATIC_ROOT/powerline"
|
||||||
|
then
|
||||||
|
fail "lint" F "Checking test config failed"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if test $FAILED -eq 0 ; then
|
||||||
|
rm -r "$TEST_ROOT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exit_suite
|
3
tests/test_awesome/path/awesome-client
Executable file
3
tests/test_awesome/path/awesome-client
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
echo "$@" >> "$TEST_ROOT/results/args"
|
||||||
|
cat >> "$TEST_ROOT/results/requests"
|
7
tests/test_awesome/powerline/config.json
Normal file
7
tests/test_awesome/powerline/config.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"ext": {
|
||||||
|
"wm": {
|
||||||
|
"update_interval": 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
18
tests/test_awesome/powerline/themes/wm/default.json
Normal file
18
tests/test_awesome/powerline/themes/wm/default.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"segments": {
|
||||||
|
"left": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"highlight_groups": ["time"],
|
||||||
|
"contents": "default-left"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"right": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"highlight_groups": ["time"],
|
||||||
|
"contents": "default-right"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
18
tests/test_awesome/powerline/themes/wm/dvi.json
Normal file
18
tests/test_awesome/powerline/themes/wm/dvi.json
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"segments": {
|
||||||
|
"left": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"highlight_groups": ["time"],
|
||||||
|
"contents": "dvi-left"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"right": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"highlight_groups": ["time"],
|
||||||
|
"contents": "dvi-right"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
@ -127,7 +127,7 @@ class TestParser(TestCase):
|
|||||||
}),
|
}),
|
||||||
]:
|
]:
|
||||||
args = parser.parse_args(argv)
|
args = parser.parse_args(argv)
|
||||||
finish_args({}, args)
|
finish_args(parser, {}, args)
|
||||||
for key, val in expargs.items():
|
for key, val in expargs.items():
|
||||||
self.assertEqual(getattr(args, key), val)
|
self.assertEqual(getattr(args, key), val)
|
||||||
for key, val in args.__dict__.items():
|
for key, val in args.__dict__.items():
|
||||||
|
@ -311,7 +311,7 @@ if test -z "${ONLY_SHELL}" || test "x${ONLY_SHELL%sh}" != "x${ONLY_SHELL}" || te
|
|||||||
if test $TEST_TYPE = daemon ; then
|
if test $TEST_TYPE = daemon ; then
|
||||||
sh -c '
|
sh -c '
|
||||||
echo $$ > tests/shell/daemon_pid
|
echo $$ > tests/shell/daemon_pid
|
||||||
$PYTHON ./scripts/powerline-daemon -s$ADDRESS -f >tests/shell/daemon_log 2>&1
|
exec $PYTHON ./scripts/powerline-daemon -s$ADDRESS -f >tests/shell/daemon_log 2>&1
|
||||||
' &
|
' &
|
||||||
fi
|
fi
|
||||||
echo "> Testing $TEST_TYPE"
|
echo "> Testing $TEST_TYPE"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user