def test_parse(self): self.assertEqual(CommandLine.parse('cmd 1', Meta()), CommandLine('cmd 1', Meta())) self.assertEqual( CommandLine.parse({'cmd 2': { 'work_dir': '/path/to/work_dir' }}, Meta()), CommandLine('cmd 2', Meta('/path/to/work_dir'))) self.assertEqual( CommandLine.parse({'cmd 3': { 'env': { 'xxx': '123', 'yyy': '234' } }}, Meta()), CommandLine('cmd 3', Meta(env={ 'xxx': '123', 'yyy': '234' }))) self.assertEqual( CommandLine.parse( { 'cmd 3': { 'env': { 'xxx': '123', 'yyy': '234' }, 'work_dir': '/work' } }, Meta()), CommandLine('cmd 3', Meta('/work', { 'xxx': '123', 'yyy': '234' }))) self.assertEqual(CommandLine.parse('cmd 4', Meta(lock=True)), CommandLine('cmd 4', Meta(lock=True)))
def test_updated(self): m1 = Meta() m2 = m1.updated({'work_dir': '/path/to/work_dir', 'env': {'xxx': '123', 'yyy': '234'}, 'lock': True}, 'utf-8') m3 = m2.updated({'work_dir': '/tmp2', 'env': {'xxx': '789', 'zzz': '345'}, 'lock': False}, 'utf-8') self.assertEqual(m1, Meta(None, {})) self.assertEqual(m2, Meta('/path/to/work_dir', {'xxx': '123', 'yyy': '234'}, True)) self.assertEqual(m3, Meta('/tmp2', {'xxx': '789', 'yyy': '234', 'zzz': '345'}, False))
def test_is_running(self): tempdir = tempfile.mkdtemp() try: sleep_cmd = 'python -c "import time;time.sleep(1)"' if os.name == 'nt' else 'sleep 1' cmd = Command('cmd 1', [ CommandLine(sleep_cmd, Meta(lock=True)), CommandLine(sleep_cmd, Meta(lock=True)), ]) exe = CommandExecutor(MockLogger(), 'utf-8', sys.stdin, sys.stdout, sys.stderr, tempdir) class RunSleep(threading.Thread): def run(self): exe.execute(cmd) th = RunSleep() th.start() time.sleep(0.5) self.assertTrue(exe.is_running(cmd)) time.sleep(1) self.assertTrue(exe.is_running(cmd)) time.sleep(1) self.assertFalse(exe.is_running(cmd)) finally: for child in os.listdir(tempdir): os.removedirs(os.path.join(tempdir, child)) if os.path.exists(tempdir): os.removedirs(tempdir)
def test_formatted(self): self.assertEqual( CommandLine('cmd 1', Meta()).formatted(), '- cmd: cmd 1\n cwd: %s' % os.path.abspath(os.path.curdir)) self.assertEqual( CommandLine( 'cmd 1', Meta('/path/to/work', { 'xxx': '111', 'yyy': '222', 'zzz': '333' }, True)).formatted(), '- cmd: cmd 1\n cwd: /path/to/work\n env: {xxx: 111, yyy: 222, zzz: 333}\n lock: True' )
def test_wait_input_menu(self): self.maxDiff = None _in = FakeInput('a\n9\n0\n') expected = '\n'.join([ 'Host: host User: user', '================================================================================', ' ', '--------------------------------------------------------------------------------', '------+-------------------------------------------------------------------------', ' [0] | Quit', '================================================================================', 'Press menu number (0-0): ', ]) * 3 with self.withAssertOutput(expected, '') as (out, err): t = Terminal(Menu('', [], Meta()), 'host', 'user', self.get_exec(encoding='utf-8', stdout=out, stderr=err), handler=TerminalHandler(stdin=_in, stdout=out, stderr=err, keep_input_clean=False, getch_enabled=False), _input=_in, _output=out, encoding='utf-8', lang='en_US', width=80, timing=False) t.loop()
def test_load_config(self): meta = Meta( to_unicode( os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources'))) with self.withAssertOutput( 'Reading file: %s\n' % self._testfile('minimum.yml'), '') as (out, err): self.assertEqual( Setting(config_path=self._testfile('minimum.yml'), encoding='utf-8', stdout=out, stderr=err).load_config().root_menu, Menu('', [], meta)) path = os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources', 'flat.yml') with self.withAssertOutput('Reading file: %s\n' % path, '') as (out, err): self.assertEqual( Setting(config_path=self._testfile('flat.yml'), encoding='utf-8', stdout=out, stderr=err).load_config().root_menu, Menu('Main Menu', [ Command('Menu 1', [CommandLine('echo 1', meta)]), Command('Menu 2', [CommandLine('echo 2', meta)]), Command('Menu 3', [CommandLine('echo 3', meta)]), Command('Menu 4', [CommandLine('echo 4', meta)]), Command('Menu 5', [CommandLine('echo 5', meta)]), Command('Menu 6', [CommandLine('echo 6', meta)]), ], meta))
def __init__(self, title, items, meta=Meta()): """ :param title: :param items: :param meta: :return: """ Item.__init__(self, ('title', title), ('items', items), ('meta', meta))
def test_print_source_ja(self): self.maxDiff = None root_meta = Meta('/path/to/work', {'ENV1': '値1', 'ENV2': '値2'}) sub_meta = Meta('/tmp2', {'ENV1': '値1', 'ENV2': '値2'}) special_meta = Meta('/path/to/work2', { 'ENV1': '値9', 'ENV2': '値2', 'ENV3': '値3' }) root_menu = Menu('メイン メニュー', [ Command('メニュー 1', [CommandLine('コマンド 1', root_meta)]), Command('メニュー 2', [CommandLine('コマンド 2', root_meta)]), Command('メニュー 3', [ CommandLine('コマンド 3', special_meta), CommandLine('command 4', root_meta) ]), Menu('サブ メニュー', [Command('メニュー s1', [CommandLine('コマンド 5', sub_meta)])], sub_meta), Command('メニュー 9', [CommandLine('コマンド 9', root_meta)]), ], root_meta) _in = FakeInput('s\nx\n0\n') path = os.path.join('tests', 'resources', 'expect', 'terminal_test_print_source_ja.txt') with self.withAssertOutputFile(path, {'': ''}) as out: t = Terminal(root_menu, 'host', 'user', self.get_exec(encoding='utf-8', stdout=out, stderr=out), handler=TerminalHandler(stdin=_in, stdout=out, stderr=out, keep_input_clean=False, getch_enabled=False), _input=_in, _output=out, encoding='utf-8', lang='ja_JP', width=80, timing=False) t.loop()
def test_print_source(self): self.maxDiff = None root_meta = Meta('/path/to/work', {'ENV1': 'VAL1', 'ENV2': 'VAL2'}) sub_meta = Meta('/tmp2', {'ENV1': 'VAL1', 'ENV2': 'VAL2'}) special_meta = Meta('/path/to/work2', { 'ENV1': 'VAL9', 'ENV2': 'VAL2', 'ENV3': 'VAL3' }) root_menu = Menu('Main menu', [ Command('label 1', [CommandLine('command 1', root_meta)]), Command('label 2', [CommandLine('command 2', root_meta)]), Command('label 3', [ CommandLine('command 3', special_meta), CommandLine('command 4', root_meta) ]), Menu('sub menu', [Command('label s1', [CommandLine('command 5', sub_meta)])], sub_meta), Command('label 9', [CommandLine('command 9', root_meta)]), ], root_meta) _in = FakeInput('s\nx\n0\n') path = os.path.join('tests', 'resources', 'expect', 'terminal_test_print_source.txt') with self.withAssertOutputFile(path, {'': ''}) as out: t = Terminal(root_menu, 'host', 'user', self.get_exec(encoding='utf-8', stdout=out, stderr=out), handler=TerminalHandler(stdin=_in, stdout=out, stderr=out, keep_input_clean=False, getch_enabled=False), _input=_in, _output=out, encoding='utf-8', lang='en_US', width=80, timing=False) t.loop()
def test_parse_utf8(self): self.assertEqual(CommandLine.parse('あいうえお', Meta()), CommandLine('あいうえお', Meta())) self.assertEqual( CommandLine.parse( { 'あいうえお': { 'env': { 'かきく': 'けこ', 'さしす': 'せそ' }, 'work_dir': 'たちつてと' } }, Meta()), CommandLine('あいうえお', Meta('たちつてと', { 'かきく': 'けこ', 'さしす': 'せそ' })))
def test_parse_sjis(self): self.assertEqual( CommandLine.parse('あいうえお'.encode('sjis'), Meta(), 'sjis'), CommandLine('あいうえお', Meta(), 'sjis')) self.assertEqual( CommandLine.parse( { 'あいうえお'.encode('sjis'): { 'env': { 'かきく'.encode('sjis'): 'けこ'.encode('sjis'), 'さしす'.encode('sjis'): 'せそ'.encode('sjis') }, 'work_dir': 'たちつてと'.encode('sjis'), } }, Meta(), 'sjis'), CommandLine('あいうえお', Meta('たちつてと', { 'かきく': 'けこ', 'さしす': 'せそ' }), 'sjis'))
def test_updated(self): m1 = Meta() m2 = m1.updated( { 'work_dir': '/path/to/work_dir', 'env': { 'xxx': '123', 'yyy': '234' }, 'lock': True }, 'utf-8') m3 = m2.updated( { 'work_dir': '/tmp2', 'env': { 'xxx': '789', 'zzz': '345' }, 'lock': False }, 'utf-8') self.assertEqual(m1, Meta(None, {})) self.assertEqual( m2, Meta('/path/to/work_dir', { 'xxx': '123', 'yyy': '234' }, True)) self.assertEqual( m3, Meta('/tmp2', { 'xxx': '789', 'yyy': '234', 'zzz': '345' }, False))
def test_loop_sjis(self): self.maxDiff = None root_menu = Menu( 'メインメニュー', [Command('メニュー 1', [CommandLine("echo 'あいうえお'", Meta())])], Meta()) _in = FakeInput(''.join(['1yx', '0'])) # We use a temporary file due to capture the output of subprocess#call. path = os.path.join('tests', 'resources', 'expect', 'terminal_test_loop_sjis.txt') with self.withAssertOutputFile(path, expect_file_encoding='sjis', output_encoding='sjis') as out: t = Terminal(root_menu, 'ホスト', 'ユーザ', self.get_exec(encoding='sjis', stdout=out, stderr=out), handler=TerminalHandler(stdin=_in, stdout=out, stderr=out, keep_input_clean=False), _input=_in, _output=out, encoding='sjis', lang='ja_JP', width=80, timing=False) t.loop() # out.seek(0) # print(out.read()) self.assertEqual(t.executor.logger.buffer, [ (6, "[INFO] Command started: echo 'あいうえお'"), (6, "[INFO] Command ended with return code: 0"), ])
def load_config(self): """ Load the configuration file or url. If it contains 'include' sections, load them recursively. :return: updated Setting instance """ if self.config_path is None: raise SettingError('Not found configuration file.') loader = Loader(self.work_dir, self.cache_dir, self.encoding, self.stdout, self.clear_cache) data = loader.load(False, self.config_path) try: root_menu = Menu.parse(data, Meta(self.work_dir), loader, self.encoding, 0) except (AssertionError, ValueError, TypeError) as e: raise ConfigError(self.config_path, e) return self.copy(root_menu=root_menu)
def test_load_config_dynamic(self): meta = Meta( to_unicode( os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources'))) path = os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources', 'with_dynamic.yml') expect = '\n'.join([ 'Reading file: %s' % path, """Executing: echo '{"Sub Menu": [{"Menu 2": "echo 2"}, {"Menu 3": "echo 3"}]}'\n""" ]) with self.withAssertOutput(expect, '') as (out, err): self.assertEqual( Setting(config_path=self._testfile('with_dynamic.yml'), encoding='utf-8', stdout=out, stderr=err).load_config().root_menu, Menu('Main Menu', [ Command('Menu 1', [CommandLine('echo 1', meta)]), Menu('Sub Menu', [ Command('Menu 2', [CommandLine('echo 2', meta)]), Command('Menu 3', [CommandLine('echo 3', meta)]), ], meta) ], meta))
def test_loop_multiple_commands(self): self.maxDiff = None root_menu = Menu('Main Menu', [ Menu('Sub Menu 1', [ Command('Menu 1', [ CommandLine('echo 1', Meta()), CommandLine('echo 2', Meta()), ]) ], Meta()), Menu('Sub Menu 2', [ Menu('Sub Menu 3', [ Command('Menu 3', [CommandLine('echo 3', Meta())]), Command('Menu 4', [CommandLine('echo 4', Meta())]), ], Meta()), Command('Menu 5', [CommandLine('echo 5', Meta())]) ], Meta()), Command('Menu 6', [ CommandLine('echo 6', Meta()), CommandLine('echo 7', Meta()), CommandLine('false', Meta()), CommandLine('echo 8', Meta()), ]) ], Meta()) _in = FakeInput(''.join( ['1', '.1yx', '0', '21.1yx', '0.0', '3yx', '0'])) # We use a temporary file due to capture the output of subprocess#call. with self.withAssertOutputFile( 'tests/resources/expect/terminal_test_loop_multiple_commands.txt' ) as out: t = Terminal(root_menu, 'host', 'user', self.get_exec(encoding='utf-8', stdout=out, stderr=out), handler=TerminalHandler(stdin=_in, stdout=out, stderr=out, keep_input_clean=False), _input=_in, _output=out, encoding='utf-8', lang='en_US', width=80, timing=False) t.loop() self.assertEqual(t.executor.logger.buffer, [ (6, '[INFO] Command started: echo 1'), (6, '[INFO] Command ended with return code: 0'), (6, '[INFO] Command started: echo 2'), (6, '[INFO] Command ended with return code: 0'), (6, '[INFO] Command started: echo 3'), (6, '[INFO] Command ended with return code: 0'), (6, '[INFO] Command started: echo 6'), (6, '[INFO] Command ended with return code: 0'), (6, '[INFO] Command started: echo 7'), (6, '[INFO] Command ended with return code: 0'), (6, '[INFO] Command started: false'), (6, '[INFO] Command ended with return code: 1'), ])
def test_load_config_dynamic_cache(self): self.maxDiff = None meta = Meta( to_unicode( os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources'))) path = os.path.join(os.path.abspath(os.path.curdir), 'tests', 'resources', 'with_dynamic_cache.yml') cache_dir = os.path.join(os.path.curdir, 'tests', 'work') cache_path = os.path.join(cache_dir, '57', '8f2d1550c1fad02f46409db2b538c9') def clear_files(): if os.path.exists(cache_path): os.remove(cache_path) if os.path.exists(os.path.dirname(cache_path)): os.removedirs(os.path.dirname(cache_path)) if os.path.exists(cache_dir): os.removedirs(cache_dir) expect = '\n'.join([ 'Reading file: %s' % path, """Executing: echo '{"Sub Menu": [{"Menu 2": "echo 2"}, {"Menu 3": "echo 3"}]}'""", 'Writing eval cache: %s' % cache_path, 'Reading file: %s' % path, 'Reading eval cache: %s' % cache_path, '' ]) clear_files() try: with self.withAssertOutput(expect, '') as (out, err): self.assertEqual( Setting( config_path=self._testfile('with_dynamic_cache.yml'), encoding='utf-8', stdout=out, stderr=err, cache_dir=cache_dir).load_config().root_menu, Menu('Main Menu', [ Command('Menu 1', [CommandLine('echo 1', meta)]), Menu('Sub Menu', [ Command('Menu 2', [CommandLine('echo 2', meta)]), Command('Menu 3', [CommandLine('echo 3', meta)]), ], meta) ], meta)) # read twice to use cache self.assertEqual( Setting( config_path=self._testfile('with_dynamic_cache.yml'), encoding='utf-8', stdout=out, stderr=err, cache_dir=cache_dir).load_config().root_menu, Menu('Main Menu', [ Command('Menu 1', [CommandLine('echo 1', meta)]), Menu('Sub Menu', [ Command('Menu 2', [CommandLine('echo 2', meta)]), Command('Menu 3', [CommandLine('echo 3', meta)]), ], meta) ], meta)) finally: clear_files()
def test_get_page(self): self.maxDiff = None t = Terminal({'': []}, 'host', 'user', self.get_exec(), handler=self.handler, encoding='utf-8', lang='C', width=80) self.assertEqual( t.get_page(['title'], [], 0, 1), '\n'.join([ 'Host: host User: user', '================================================================================', ' title', '--------------------------------------------------------------------------------', '------+-------------------------------------------------------------------------', ' [0] | Quit', '================================================================================', 'Press menu number (0-0): ' ])) self.assertEqual( t.get_page(['Main Menu', 'title'], [ Command('menu a', [CommandLine('command a', Meta())]), Command('menu b', [CommandLine('command b', Meta())]), Command('menu c', [CommandLine('command c', Meta())]), ], 0, 1), '\n'.join([ 'Host: host User: user', '================================================================================', ' Main Menu > title', '--------------------------------------------------------------------------------', ' [1] | menu a', ' [2] | menu b', ' [3] | menu c', '------+-------------------------------------------------------------------------', ' [0] | Return to Main Menu', '================================================================================', 'Press menu number (0-3): ' ])) self.assertEqual( t.get_page(['title'], [ Command('menu a', [CommandLine('command a', Meta())]), Command('menu b', [CommandLine('command b', Meta())]), Command('menu c', [CommandLine('command c', Meta())]), Command('menu d', [CommandLine('command d', Meta())]), Command('menu e', [CommandLine('command e', Meta())]), Command('menu f', [CommandLine('command f', Meta())]), Command('menu g', [CommandLine('command g', Meta())]), Command('menu h', [CommandLine('command h', Meta())]), Command('menu i', [CommandLine('command i', Meta())]), ], 0, 100), '\n'.join([ 'Host: host User: user', '================================================================================', ' title', '--------------------------------------------------------------------------------', ' Page 1 / 100 [N] =>', '--------------------------------------------------------------------------------', ' [1] | menu a', ' [2] | menu b', ' [3] | menu c', ' [4] | menu d', ' [5] | menu e', ' [6] | menu f', ' [7] | menu g', ' [8] | menu h', ' [9] | menu i', '------+-------------------------------------------------------------------------', ' [0] | Quit', '================================================================================', 'Press menu number (0-9): ' ])) self.assertEqual( t.get_page(['title'], [ Command('menu a', [CommandLine('command a', Meta())]), Command('menu b', [CommandLine('command b', Meta())]), Command('menu c', [CommandLine('command c', Meta())]), Command('menu d', [CommandLine('command d', Meta())]), Command('menu e', [CommandLine('command e', Meta())]), Command('menu f', [CommandLine('command f', Meta())]), Command('menu g', [CommandLine('command g', Meta())]), Command('menu h', [CommandLine('command h', Meta())]), Command('menu i', [CommandLine('command i', Meta())]), ], 8, 100), '\n'.join([ 'Host: host User: user', '================================================================================', ' title', '--------------------------------------------------------------------------------', '<= [P] Page 9 / 100 [N] =>', '--------------------------------------------------------------------------------', ' [1] | menu a', ' [2] | menu b', ' [3] | menu c', ' [4] | menu d', ' [5] | menu e', ' [6] | menu f', ' [7] | menu g', ' [8] | menu h', ' [9] | menu i', '------+-------------------------------------------------------------------------', ' [0] | Quit', '================================================================================', 'Press menu number (0-9): ' ])) self.assertEqual( t.get_page(['title'], [ Command('menu a', [CommandLine('command a', Meta())]), ], 99, 100), '\n'.join([ 'Host: host User: user', '================================================================================', ' title', '--------------------------------------------------------------------------------', '<= [P] Page 100 / 100 ', '--------------------------------------------------------------------------------', ' [1] | menu a', '------+-------------------------------------------------------------------------', ' [0] | Quit', '================================================================================', 'Press menu number (0-1): ' ])) # sub menu self.assertEqual( t.get_page(['Main Menu', 'title'], [ Menu('menu a', [Command('menu b', [CommandLine('command b', Meta())])], Meta()), Menu('menu c', [ Command('menu c', [CommandLine('command c', Meta())]), Command('menu d', [CommandLine('command d', Meta())]), ], Meta()), ], 0, 1), '\n'.join([ 'Host: host User: user', '================================================================================', ' Main Menu > title', '--------------------------------------------------------------------------------', ' [1] | Go to menu a', ' [2] | Go to menu c', '------+-------------------------------------------------------------------------', ' [0] | Return to Main Menu', '================================================================================', 'Press menu number (0-2): ' ])) # multiple command lines self.assertEqual( t.get_page(['Main Menu', 'title'], [ Command('menu a', [CommandLine('command a', Meta())]), Command('menu b', [ CommandLine('command b', Meta()), CommandLine('command b', Meta()), ]), Menu('menu c', [ Command('menu d', [ CommandLine('command d', Meta()), CommandLine('command d', Meta()), ]) ], Meta()), ], 0, 1), '\n'.join([ 'Host: host User: user', '================================================================================', ' Main Menu > title', '--------------------------------------------------------------------------------', ' [1] | menu a', ' [2] | menu b', ' [3] | Go to menu c', '------+-------------------------------------------------------------------------', ' [0] | Return to Main Menu', '================================================================================', 'Press menu number (0-3): ' ]))
def test_updated_error(self): self.assertRaisesMessage(ValueError, "Unknown field: a", Meta().updated, {'a': 'b'}, 'utf-8')
def test_get_page_ja(self): self.maxDiff = None t = Terminal({'': []}, 'ホスト', 'ユーザ', self.get_exec(), handler=self.handler, encoding='utf-8', lang='ja_JP', width=80) self.assertEqual( t.get_page(['タイトル'], [], 0, 1), '\n'.join([ 'ホスト名: ホスト 実行ユーザ: ユーザ', '================================================================================', ' タイトル', '--------------------------------------------------------------------------------', '------+-------------------------------------------------------------------------', ' [0] | 終了', '================================================================================', '番号を入力してください (0-0): ' ])) self.assertEqual( t.get_page(['メインメニュー', 'タイトル'], [ Command('メニュー a', [CommandLine('コマンド a', Meta())]), Command('メニュー b', [CommandLine('コマンド b', Meta())]), Command('メニュー c', [CommandLine('コマンド c', Meta())]), ], 0, 1), '\n'.join([ 'ホスト名: ホスト 実行ユーザ: ユーザ', '================================================================================', ' メインメニュー > タイトル', '--------------------------------------------------------------------------------', ' [1] | メニュー a', ' [2] | メニュー b', ' [3] | メニュー c', '------+-------------------------------------------------------------------------', ' [0] | メインメニュー に戻る', '================================================================================', '番号を入力してください (0-3): ' ])) self.assertEqual( t.get_page([ 'メインメニュー', 'タイトル1', 'タイトル2', 'タイトル3', 'タイトル4', 'タイトル5', 'タイトル6', 'タイトル7', 'タイトル8', ], [ Command('メニュー a', [CommandLine('コマンド a', Meta())]), Command('メニュー b', [CommandLine('コマンド b', Meta())]), Command('メニュー c', [CommandLine('コマンド c', Meta())]), ], 0, 1), '\n'.join([ 'ホスト名: ホスト 実行ユーザ: ユーザ', '================================================================================', ' ~ル2 > タイトル3 > タイトル4 > タイトル5 > タイトル6 > タイトル7 > タイトル8', '--------------------------------------------------------------------------------', ' [1] | メニュー a', ' [2] | メニュー b', ' [3] | メニュー c', '------+-------------------------------------------------------------------------', ' [0] | タイトル7 に戻る', '================================================================================', '番号を入力してください (0-3): ' ])) self.assertEqual( t.get_page(['タイトル'], [ Command('メニュー a', [CommandLine('コマンド a', Meta())]), Command('メニュー b', [CommandLine('コマンド b', Meta())]), Command('メニュー c', [CommandLine('コマンド c', Meta())]), Command('メニュー d', [CommandLine('コマンド d', Meta())]), Command('メニュー e', [CommandLine('コマンド e', Meta())]), Command('メニュー f', [CommandLine('コマンド f', Meta())]), Command('メニュー g', [CommandLine('コマンド g', Meta())]), Command('メニュー h', [CommandLine('コマンド h', Meta())]), Command('メニュー i', [CommandLine('コマンド i', Meta())]), ], 0, 100), '\n'.join([ 'ホスト名: ホスト 実行ユーザ: ユーザ', '================================================================================', ' タイトル', '--------------------------------------------------------------------------------', ' Page 1 / 100 [N] =>', '--------------------------------------------------------------------------------', ' [1] | メニュー a', ' [2] | メニュー b', ' [3] | メニュー c', ' [4] | メニュー d', ' [5] | メニュー e', ' [6] | メニュー f', ' [7] | メニュー g', ' [8] | メニュー h', ' [9] | メニュー i', '------+-------------------------------------------------------------------------', ' [0] | 終了', '================================================================================', '番号を入力してください (0-9): ' ])) self.assertEqual( t.get_page(['タイトル'], [ Command('メニュー a', [CommandLine('コマンド a', Meta())]), Command('メニュー b', [CommandLine('コマンド b', Meta())]), Command('メニュー c', [CommandLine('コマンド c', Meta())]), Command('メニュー d', [CommandLine('コマンド d', Meta())]), Command('メニュー e', [CommandLine('コマンド e', Meta())]), Command('メニュー f', [CommandLine('コマンド f', Meta())]), Command('メニュー g', [CommandLine('コマンド g', Meta())]), Command('メニュー h', [CommandLine('コマンド h', Meta())]), Command('メニュー i', [CommandLine('コマンド i', Meta())]), ], 8, 100), '\n'.join([ 'ホスト名: ホスト 実行ユーザ: ユーザ', '================================================================================', ' タイトル', '--------------------------------------------------------------------------------', '<= [P] Page 9 / 100 [N] =>', '--------------------------------------------------------------------------------', ' [1] | メニュー a', ' [2] | メニュー b', ' [3] | メニュー c', ' [4] | メニュー d', ' [5] | メニュー e', ' [6] | メニュー f', ' [7] | メニュー g', ' [8] | メニュー h', ' [9] | メニュー i', '------+-------------------------------------------------------------------------', ' [0] | 終了', '================================================================================', '番号を入力してください (0-9): ' ])) self.assertEqual( t.get_page(['タイトル'], [ Command('メニュー a', [CommandLine('コマンド a', Meta())]), ], 99, 100), '\n'.join([ 'ホスト名: ホスト 実行ユーザ: ユーザ', '================================================================================', ' タイトル', '--------------------------------------------------------------------------------', '<= [P] Page 100 / 100 ', '--------------------------------------------------------------------------------', ' [1] | メニュー a', '------+-------------------------------------------------------------------------', ' [0] | 終了', '================================================================================', '番号を入力してください (0-1): ' ])) # sub menu self.assertEqual( t.get_page(['メインメニュー', 'タイトル'], [ Menu('メニュー a', [Command('メニュー b', [CommandLine('コマンド b', Meta())])], Meta()), Menu('メニュー c', [ Command('メニュー c', [CommandLine('コマンド c', Meta())]), Command('メニュー d', [CommandLine('コマンド d', Meta())]), ], Meta()), ], 0, 1), '\n'.join([ 'ホスト名: ホスト 実行ユーザ: ユーザ', '================================================================================', ' メインメニュー > タイトル', '--------------------------------------------------------------------------------', ' [1] | メニュー a へ', ' [2] | メニュー c へ', '------+-------------------------------------------------------------------------', ' [0] | メインメニュー に戻る', '================================================================================', '番号を入力してください (0-2): ' ])) # multiple command lines self.assertEqual( t.get_page(['メインメニュー', 'タイトル'], [ Command('メニュー a', [CommandLine('コマンド a', Meta())]), Command('メニュー b', [ CommandLine('コマンド b', Meta()), CommandLine('コマンド b', Meta()), ]), Menu('メニュー c', [ Command('メニュー d', [ CommandLine('コマンド d', Meta()), CommandLine('コマンド d', Meta()), ]) ], Meta()), ], 0, 1), '\n'.join([ 'ホスト名: ホスト 実行ユーザ: ユーザ', '================================================================================', ' メインメニュー > タイトル', '--------------------------------------------------------------------------------', ' [1] | メニュー a', ' [2] | メニュー b', ' [3] | メニュー c へ', '------+-------------------------------------------------------------------------', ' [0] | メインメニュー に戻る', '================================================================================', '番号を入力してください (0-3): ' ]))
def test_loop(self): self.maxDiff = None root_menu = Menu('Main menu', [ Command('Menu a', [CommandLine('echo executing a', Meta())]), Command('Menu b', [CommandLine('echo executing b && exit 130', Meta())]), Menu('Sub Menu 1', [ Command('Menu 1', [CommandLine('echo executing 1', Meta())]), Command('Menu 2', [CommandLine('echo executing 2', Meta())]), Command('Menu 3', [CommandLine('echo executing 3', Meta())]), Command('Menu 4', [CommandLine('echo executing 4', Meta())]), Command('Menu 5', [CommandLine('echo executing 5', Meta())]), Command('Menu 6', [CommandLine('echo executing 6', Meta())]), Command('Menu 7', [CommandLine('echo executing 7', Meta())]), Command('Menu 8', [CommandLine('echo executing 8', Meta())]), Command('Menu 9', [CommandLine('echo executing 9', Meta())]), Command('Menu 10', [CommandLine('echo executing 10', Meta())]), ], Meta()) ], Meta()) _in = FakeInput(''.join([ '1n', '1N', '1\n', '1yx', '2Yx', '3n', '1yx', 'p', '9yx', '0', '-0' ])) # We use a temporary file due to capture the output of subprocess#call. path = os.path.join('tests', 'resources', 'expect', 'terminal_test_loop.txt') with self.withAssertOutputFile(path) as out: t = Terminal(root_menu, 'host', 'user', self.get_exec(encoding='utf-8', stdout=out, stderr=out), handler=TerminalHandler(stdin=_in, stdout=out, stderr=out, keep_input_clean=False), _input=_in, _output=out, encoding='utf-8', lang='en_US', width=80, timing=False) t.loop() self.assertEqual(t.executor.logger.buffer, [ (6, '[INFO] Command started: echo executing a'), (6, '[INFO] Command ended with return code: 0'), (6, '[INFO] Command started: echo executing b && exit 130'), (6, '[INFO] Command ended with return code: 130'), (6, '[INFO] Command started: echo executing 10'), (6, '[INFO] Command ended with return code: 0'), (6, '[INFO] Command started: echo executing 9'), (6, '[INFO] Command ended with return code: 0'), ])
def test_parse_error(self): self.assertRaisesMessage( ValueError, "CommandLine must be string or dict, not list.", CommandLine.parse, [], Meta())
def test_to_hash_string(self): self.assertEqual( len(CommandLine('cmd 1', Meta(), 'utf-8').to_hash_string()), 32) self.assertEqual( CommandLine('cmd 1', Meta(), 'utf-8').to_hash_string(), CommandLine('cmd 1', Meta(), 'sjis').to_hash_string()) self.assertNotEqual( CommandLine('cmd 1', Meta(), 'utf-8').to_hash_string(), CommandLine('cmd 2', Meta(), 'utf-8').to_hash_string()) self.assertEqual( CommandLine('cmd 1', Meta('/path/to/work1'), 'utf-8').to_hash_string(), CommandLine('cmd 1', Meta('/path/to/work2'), 'sjis').to_hash_string()) self.assertEqual( CommandLine('cmd 1', Meta('/path/to/work1', lock=True), 'utf-8').to_hash_string(), CommandLine('cmd 1', Meta('/path/to/work2', lock=False), 'sjis').to_hash_string()) self.assertNotEqual( CommandLine('cmd 1', Meta(env={'ABC': '123'}), 'utf-8').to_hash_string(), CommandLine('cmd 1', Meta(), 'utf-8').to_hash_string()) self.assertNotEqual( CommandLine('cmd 1', Meta(env={'ABC': '123'}), 'utf-8').to_hash_string(), CommandLine('cmd 1', Meta(env={ 'ABC': '123', '': '' }), 'utf-8').to_hash_string()) self.assertNotEqual( CommandLine('cmd 1', Meta(env={'ABC': '123'}), 'utf-8').to_hash_string(), CommandLine('cmd 1', Meta(env={'ABC': '1234'}), 'utf-8').to_hash_string()) self.assertEqual( CommandLine('cmd 1', Meta(env={'ABC': '123'}), 'utf-8').to_hash_string(), CommandLine('cmd 1', Meta(env={'ABC': '123'}), 'utf-8').to_hash_string())
def test_parse_error(self): self.assertRaisesMessage( TypeError, "data must be dict, not %s." % ('unicode' if six.PY2 else 'str'), Item.parse, {'a': ['b', {}]}, Meta(), Loader('.', '.'))
def test_execute_command_duplicate(self): self.maxDiff = None sleep_cmd = 'python -c "import time;time.sleep(1)"' if os.name == 'nt' else 'sleep 1' _in1 = FakeInput('\n'.join(['y', '\r'])) _in2 = FakeInput('\n'.join(['y', '\r'])) root_menu = Menu( 'Main Menu', [Command('Menu 1', [CommandLine(sleep_cmd, Meta(lock=True))])]) expected_en = '\n'.join([ 'Host: host User: user', '================================================================================', ' Confirmation', '--------------------------------------------------------------------------------', ' Would execute: Menu 1', '================================================================================', 'Do you really want to execute? (y/n) [n]: ' 'Host: host User: user', '================================================================================', ' Duplicate check', '--------------------------------------------------------------------------------', ' Already running: Menu 1', '================================================================================', 'Do you really want to continue? (y/n) [n]: ', ]) with self.withAssertOutput(expected_en, '') as (out, err): t = Terminal(root_menu, 'host', 'user', MockExecutor(0, True), TerminalHandler(stdin=_in1, stdout=out, stderr=err, keep_input_clean=False, getch_enabled=False), _input=_in1, _output=out, encoding='utf-8', lang='en_US', width=80, timing=False) t.execute_command( Command('Menu 1', [CommandLine(sleep_cmd, Meta(lock=True))])) expected_ja = '\n'.join([ 'ホスト名: host 実行ユーザ: user', '================================================================================', ' 実行確認', '--------------------------------------------------------------------------------', ' Menu 1 を行います。', '================================================================================', 'よろしいですか? (y/n) [n]: ' 'ホスト名: host 実行ユーザ: user', '================================================================================', ' 多重実行チェック', '--------------------------------------------------------------------------------', ' Menu 1 は既に実行中です。', '================================================================================', '本当によろしいですか? (y/n) [n]: ', ]) with self.withAssertOutput(expected_ja, '') as (out, err): t = Terminal(root_menu, 'host', 'user', MockExecutor(0, True), TerminalHandler(stdin=_in2, stdout=out, stderr=err, keep_input_clean=False, getch_enabled=False), _input=_in2, _output=out, encoding='utf-8', lang='ja_JP', width=80, timing=False) t.execute_command( Command('Menu 1', [CommandLine(sleep_cmd, Meta(lock=True))]))