11import logging
22import os
3+ import signal
34import subprocess
45import sys
5- import typing
66from dataclasses import dataclass , field
77
88import click
99from click .core import Context
1010from progress .spinner import MoonSpinner
11- from trogon import tui
1211
1312from testgen import settings
1413from testgen .commands .run_execute_tests import run_execution_steps
4039 get_tg_db ,
4140 get_tg_host ,
4241 get_tg_schema ,
43- logs ,
4442 version_service ,
4543)
44+ from testgen .scheduler import register_scheduler_job , run_scheduler
4645from testgen .ui .queries import profiling_run_queries , test_run_queries
4746from testgen .utils import plugins
4847
4948LOG = logging .getLogger ("testgen" )
5049
50+ APP_MODULES = ["ui" , "scheduler" ]
51+
5152
5253@dataclass
5354class Configuration :
@@ -58,8 +59,16 @@ class Configuration:
5859pass_configuration = click .make_pass_decorator (Configuration )
5960
6061
61- @tui ()
62+ class CliGroup (click .Group ):
63+ def invoke (self , ctx : Context ):
64+ try :
65+ super ().invoke (ctx )
66+ except Exception :
67+ LOG .exception ("There was an unexpected error" )
68+
69+
6270@click .group (
71+ cls = CliGroup ,
6372 help = f"This version: { settings .VERSION } \n \n Latest version: { version_service .get_latest_version ()} \n \n Schema revision: { get_schema_revision ()} "
6473)
6574@click .option (
@@ -83,7 +92,7 @@ def cli(ctx: Context, verbose: bool):
8392 sys .exit (1 )
8493
8594 if (
86- ctx .invoked_subcommand not in ["ui " , "tui " , "setup-system-db" , "upgrade-system-version" , "quick-start" ]
95+ ctx .invoked_subcommand not in ["run-app " , "ui " , "setup-system-db" , "upgrade-system-version" , "quick-start" ]
8796 and not is_db_revision_up_to_date ()
8897 ):
8998 click .secho ("The system database schema is outdated. Automatically running the following command:" , fg = "red" )
@@ -93,6 +102,7 @@ def cli(ctx: Context, verbose: bool):
93102 LOG .debug ("Current Step: Main Program" )
94103
95104
105+ @register_scheduler_job
96106@cli .command ("run-profile" , help = "Generates a new profile of the table group." )
97107@pass_configuration
98108@click .option (
@@ -143,6 +153,7 @@ def run_test_generation(configuration: Configuration, table_group_id: str, test_
143153 click .echo ("\n " + message )
144154
145155
156+ @register_scheduler_job
146157@cli .command ("run-tests" , help = "Performs tests defined for a test suite." )
147158@click .option (
148159 "-pk" ,
@@ -590,19 +601,19 @@ def list_table_groups(configuration: Configuration, project_key: str, display: b
590601def ui (): ...
591602
592603
593- @ui .command ("run" , help = "Run the browser application with default settings" )
594- @click .option ("-d" , "--debug" , is_flag = True , default = False )
595- def run (debug : bool ):
604+ @ui .command ("plugins" , help = "List installed application plugins" )
605+ def list_ui_plugins ():
606+ installed_plugins = list (plugins .discover ())
607+
608+ click .echo (click .style (len (installed_plugins ), fg = "bright_magenta" ) + click .style (" plugins installed" , bold = True ))
609+ for plugin in installed_plugins :
610+ click .echo (click .style (" + " , fg = "bright_green" ) + f"{ plugin .package : <30} " + f"\t version: { plugin .version } " )
611+
612+
613+ def run_ui ():
596614 from testgen .ui .scripts import patch_streamlit
597- configure_logging (
598- level = logging .INFO ,
599- log_format = "%(message)s" ,
600- )
601615
602616 status_code : int = - 1
603- logger = logging .getLogger ("testgen" )
604- stderr : typing .TextIO = typing .cast (typing .TextIO , logs .LogPipe (logger , logging .INFO ))
605- stdout : typing .TextIO = typing .cast (typing .TextIO , logs .LogPipe (logger , logging .INFO ))
606617
607618 use_ssl = os .path .isfile (settings .SSL_CERT_FILE ) and os .path .isfile (settings .SSL_KEY_FILE )
608619
@@ -621,31 +632,49 @@ def run(debug: bool):
621632 "run" ,
622633 app_file ,
623634 "--browser.gatherUsageStats=false" ,
635+ "--client.showErrorDetails=none" ,
636+ "--client.toolbarMode=minimal" ,
624637 f"--server.sslCertFile={ settings .SSL_CERT_FILE } " if use_ssl else "" ,
625638 f"--server.sslKeyFile={ settings .SSL_KEY_FILE } " if use_ssl else "" ,
626639 "--" ,
627- f"{ '--debug' if debug else '' } " ,
640+ f"{ '--debug' if settings . IS_DEBUG else '' } " ,
628641 ],
629- stdout = stdout ,
630- stderr = stderr ,
642+ env = {** os .environ , "TG_JOB_SOURCE" : "UI" }
631643 )
632644 except Exception :
633645 LOG .exception (f"Testgen UI exited with status code { status_code } " )
634- raise
635- finally :
636- if stderr :
637- stderr .close ()
638- if stdout :
639- stdout .close ()
640646
641647
642- @ui .command ("plugins" , help = "List installed application plugins" )
643- def list_ui_plugins ():
644- installed_plugins = list (plugins .discover ())
648+ @cli .command ("run-app" , help = "Runs TestGen's application modules" )
649+ @click .argument (
650+ "module" ,
651+ type = click .Choice (["all" , * APP_MODULES ]),
652+ default = "all" ,
653+ )
654+ def run_app (module ):
645655
646- click .echo (click .style (len (installed_plugins ), fg = "bright_magenta" ) + click .style (" plugins installed" , bold = True ))
647- for plugin in installed_plugins :
648- click .echo (click .style (" + " , fg = "bright_green" ) + f"{ plugin .package : <30} " + f"\t version: { plugin .version } " )
656+ match module :
657+ case "ui" :
658+ run_ui ()
659+
660+ case "scheduler" :
661+ run_scheduler ()
662+
663+ case "all" :
664+ children = [
665+ subprocess .Popen ([sys .executable , sys .argv [0 ], "run-app" , m ], start_new_session = True )
666+ for m in APP_MODULES
667+ ]
668+
669+ def term_children (signum , _ ):
670+ for child in children :
671+ child .send_signal (signum )
672+
673+ signal .signal (signal .SIGINT , term_children )
674+ signal .signal (signal .SIGTERM , term_children )
675+
676+ for child in children :
677+ child .wait ()
649678
650679
651680if __name__ == "__main__" :
0 commit comments