add session tests
This commit is contained in:
parent
3c5285a7d2
commit
3b31f092bd
|
@ -18,9 +18,10 @@ parameters:
|
|||
ref: Server.ServerId
|
||||
description: |
|
||||
Identifiant du serveur.
|
||||
deploy:
|
||||
deployed:
|
||||
type: Boolean
|
||||
description: Configuration de type déployée.
|
||||
default: true
|
||||
|
||||
response:
|
||||
type: ConfigConfiguration
|
||||
|
|
|
@ -17,6 +17,6 @@ parameters:
|
|||
type: Number
|
||||
description: |
|
||||
Identifiant du serveur.
|
||||
deploy:
|
||||
deployed:
|
||||
type: Boolean
|
||||
description: Configuration de type déployée.
|
||||
|
|
|
@ -10,6 +10,5 @@ public: false
|
|||
domain: servermodel-domain
|
||||
|
||||
parameters:
|
||||
servermodels:
|
||||
type: '[]Servermodel'
|
||||
description: Informations sur les modèles de serveur créés.
|
||||
type: Servermodel
|
||||
description: Informations sur les modèles de serveur créés.
|
||||
|
|
|
@ -10,6 +10,5 @@ public: false
|
|||
domain: servermodel-domain
|
||||
|
||||
parameters:
|
||||
servermodels:
|
||||
type: '[]Servermodel'
|
||||
description: Informations sur les modèles de serveur modifiés.
|
||||
type: 'Servermodel'
|
||||
description: Informations sur les modèles de serveur modifiés.
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
uri: session.server.get
|
||||
|
||||
description: |
|
||||
Configure le server.
|
||||
Récupérer la configuration du server.
|
||||
|
||||
pattern: rpc
|
||||
|
||||
|
@ -16,6 +16,11 @@ parameters:
|
|||
ref: Config.SessionId
|
||||
shortarg: s
|
||||
description: Identifiant de la configuration.
|
||||
name:
|
||||
type: String
|
||||
shortarg: n
|
||||
description: Nom de la variable.
|
||||
default: null
|
||||
|
||||
response:
|
||||
type: Session
|
||||
|
|
|
@ -18,6 +18,6 @@ parameters:
|
|||
description: Identifiant de la session.
|
||||
|
||||
response:
|
||||
type: SessionConfigurationStatus
|
||||
type: Session
|
||||
description: Statut de la configuration.
|
||||
|
||||
|
|
|
@ -16,6 +16,11 @@ parameters:
|
|||
ref: Config.SessionId
|
||||
shortarg: s
|
||||
description: Identifiant de la configuration.
|
||||
name:
|
||||
type: String
|
||||
shortarg: n
|
||||
description: Nom de la variable.
|
||||
default: null
|
||||
|
||||
response:
|
||||
type: Session
|
||||
|
|
|
@ -18,6 +18,6 @@ parameters:
|
|||
description: Identifiant de la session.
|
||||
|
||||
response:
|
||||
type: SessionConfigurationStatus
|
||||
type: Session
|
||||
description: Statut de la configuration.
|
||||
|
||||
|
|
|
@ -3,8 +3,15 @@ title: ConfigConfiguration
|
|||
type: object
|
||||
description: Description de la configuration.
|
||||
properties:
|
||||
server_id:
|
||||
type: number
|
||||
description: Identifiant du serveur.
|
||||
ref: Server.ServerId
|
||||
deployed:
|
||||
type: boolean
|
||||
description: La configuration est déployée.
|
||||
configuration:
|
||||
type: File
|
||||
type: object
|
||||
description: Détail de la configuration au format JSON.
|
||||
required:
|
||||
- configuration
|
||||
|
|
|
@ -37,16 +37,16 @@ properties:
|
|||
type: object
|
||||
description: Liste des services applicatifs déclarés pour ce modèle de serveur.
|
||||
schema:
|
||||
type: File
|
||||
type: string
|
||||
description: Contenu du schema.
|
||||
probes:
|
||||
type: File
|
||||
type: string
|
||||
description: Informations sur les sondes.
|
||||
creolefuncs:
|
||||
type: File
|
||||
type: string
|
||||
description: Fonctions Creole.
|
||||
conffiles:
|
||||
type: File
|
||||
type: string
|
||||
description: Fichiers creole au format tar encodé base64
|
||||
required:
|
||||
- servermodelid
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
---
|
||||
title: SessionConfigurationStatus
|
||||
type: object
|
||||
description: Statut de la configuration.
|
||||
properties:
|
||||
session_id:
|
||||
type: string
|
||||
description: ID de la session.
|
||||
ref: Config.SessionId
|
||||
status:
|
||||
type: string
|
||||
description: Statut de la configuration (peut être ok, error, incomplete)
|
||||
message:
|
||||
type: string
|
||||
description: Message d'erreur si la configuration a le statut error.
|
||||
mandatories:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
description: Liste des variables obligatoires non renseignées si la configuration a le statut incomplete.
|
||||
required:
|
||||
- session_id
|
||||
- status
|
||||
|
|
@ -12,9 +12,6 @@ properties:
|
|||
index:
|
||||
type: number
|
||||
description: Index de la variable a modifier.
|
||||
status:
|
||||
type: string
|
||||
description: Status de la modification.
|
||||
message:
|
||||
type: string
|
||||
description: Message d'erreur.
|
||||
|
|
|
@ -27,7 +27,7 @@ properties:
|
|||
type: boolean
|
||||
description: La configuration est en mode debug.
|
||||
content:
|
||||
type: file
|
||||
type: object
|
||||
description: Contenu de la configuration.
|
||||
required:
|
||||
- session_id
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
from .http import get_app
|
||||
# just to register every route
|
||||
from . import services as _services
|
||||
|
||||
__ALL__ = ('get_app',)
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
HTTP_PORT = 8080
|
||||
MESSAGE_ROOT_PATH = 'messages'
|
||||
ROOT_CACHE_DIR = 'cache'
|
||||
DEBUG = True
|
||||
DEBUG = False
|
||||
DATABASE_DIR = 'database'
|
||||
INTERNAL_USER = 'internal'
|
||||
CONFIGURATION_DIR = 'configurations'
|
||||
|
|
|
@ -149,7 +149,7 @@ class PublishDispatcher:
|
|||
return
|
||||
|
||||
# config is ok, so publish the message
|
||||
for function_obj in self.messages[version][message]['functions']:
|
||||
for function_obj in self.messages[version][message].get('functions', []):
|
||||
function = function_obj['function']
|
||||
module_name = function.__module__.split('.')[-2]
|
||||
function_name = function.__name__
|
||||
|
@ -163,21 +163,21 @@ class PublishDispatcher:
|
|||
if function_obj['risotto_context']:
|
||||
kw['risotto_context'] = risotto_context
|
||||
# send event
|
||||
await function(self.injected_self[function_obj['module']], **kw)
|
||||
returns = await function(self.injected_self[function_obj['module']], **kw)
|
||||
except Exception as err:
|
||||
if DEBUG:
|
||||
print_exc()
|
||||
log.error_msg(risotto_context, kwargs, err, info_msg)
|
||||
continue
|
||||
else:
|
||||
log.info_msg(risotto_context, kwargs, info_msg)
|
||||
|
||||
# notification
|
||||
if obj.get('notification'):
|
||||
notif_version, notif_message = obj['notification'].split('.', 1)
|
||||
await self.publish(notif_version,
|
||||
notif_message,
|
||||
risotto_context,
|
||||
**returns)
|
||||
# notification
|
||||
if function_obj.get('notification'):
|
||||
notif_version, notif_message = function_obj['notification'].split('.', 1)
|
||||
await self.publish(notif_version,
|
||||
notif_message,
|
||||
risotto_context,
|
||||
**returns)
|
||||
|
||||
|
||||
class Dispatcher(register.RegisterDispatcher, CallDispatcher, PublishDispatcher):
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
from aiohttp.web import Application, Response, get, post, HTTPBadRequest, HTTPInternalServerError, HTTPNotFound
|
||||
from tiramisu import Config
|
||||
from json import dumps
|
||||
from traceback import print_exc
|
||||
from tiramisu import Config
|
||||
|
||||
|
||||
from .dispatcher import dispatcher
|
||||
from .utils import _
|
||||
from .context import Context
|
||||
|
@ -8,7 +11,7 @@ from .error import CallError, NotAllowedError, RegistrationError
|
|||
from .message import get_messages
|
||||
from .logger import log
|
||||
from .config import DEBUG, HTTP_PORT
|
||||
from traceback import print_exc
|
||||
from .services import load_services
|
||||
|
||||
|
||||
def create_context(request):
|
||||
|
@ -96,6 +99,7 @@ async def get_app(loop):
|
|||
""" build all routes
|
||||
"""
|
||||
global extra_routes
|
||||
load_services()
|
||||
app = Application(loop=loop)
|
||||
routes = []
|
||||
for version, messages in dispatcher.messages.items():
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from typing import Dict
|
||||
from .context import Context
|
||||
from .utils import _
|
||||
from .config import DEBUG
|
||||
|
||||
|
||||
class Logger:
|
||||
|
@ -30,6 +31,7 @@ class Logger:
|
|||
""" send message when an error append
|
||||
"""
|
||||
paths_msg = self._get_message_paths(risotto_context)
|
||||
# if DEBUG:
|
||||
print(_(f'{risotto_context.username}: ERROR: {error} ({paths_msg} with arguments "{arguments}": {msg})'))
|
||||
|
||||
def info_msg(self,
|
||||
|
@ -48,7 +50,8 @@ class Logger:
|
|||
if msg:
|
||||
tmsg += f' {msg}'
|
||||
|
||||
print(tmsg)
|
||||
if DEBUG:
|
||||
print(tmsg)
|
||||
|
||||
|
||||
log = Logger()
|
||||
|
|
|
@ -209,10 +209,10 @@ class RegisterDispatcher:
|
|||
self.messages[version][message]['functions'] = []
|
||||
|
||||
dico = {'module': module_name,
|
||||
'functions': function,
|
||||
'function': function,
|
||||
'arguments': function_args,
|
||||
'risotto_context': inject_risotto_context}
|
||||
if notification:
|
||||
if notification and notification is not undefined:
|
||||
dico['notification'] = notification
|
||||
self.messages[version][message]['functions'].append(dico)
|
||||
|
||||
|
|
|
@ -4,15 +4,16 @@ from importlib import import_module
|
|||
from ..dispatcher import dispatcher
|
||||
|
||||
|
||||
def list_import():
|
||||
def load_services(modules=None,
|
||||
validate: bool=True):
|
||||
abs_here = dirname(abspath(__file__))
|
||||
here = basename(abs_here)
|
||||
module = basename(dirname(abs_here))
|
||||
for filename in listdir(abs_here):
|
||||
if not modules:
|
||||
modules = listdir(abs_here)
|
||||
for filename in modules:
|
||||
absfilename = join(abs_here, filename)
|
||||
if isdir(absfilename) and isfile(join(absfilename, '__init__.py')):
|
||||
dispatcher.set_module(filename, import_module(f'.{here}.{filename}', module))
|
||||
dispatcher.validate()
|
||||
|
||||
|
||||
list_import()
|
||||
if validate:
|
||||
dispatcher.validate()
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from lxml.etree import parse
|
||||
from io import BytesIO
|
||||
from os import unlink
|
||||
from os.path import isdir, isfile, join
|
||||
from traceback import print_exc
|
||||
from json import dumps
|
||||
from typing import Dict
|
||||
from typing import Dict, List
|
||||
|
||||
from tiramisu import Storage, delete_session, MetaConfig, MixConfig
|
||||
from rougail import load as rougail_load
|
||||
|
@ -22,7 +22,7 @@ class Risotto(Controller):
|
|||
server = {}
|
||||
|
||||
def __init__(self) -> None:
|
||||
for dirname in [ROOT_CACHE_DIR, DATABASE_DIR, ROUGAIL_DTD_PATH]:
|
||||
for dirname in [ROOT_CACHE_DIR, DATABASE_DIR]:
|
||||
if not isdir(dirname):
|
||||
raise RegistrationError(_(f'unable to find the cache dir "{dirname}"'))
|
||||
self.save_storage = Storage(engine='sqlite3', dir_database=DATABASE_DIR)
|
||||
|
@ -58,7 +58,8 @@ class Risotto(Controller):
|
|||
for servermodel in servermodels:
|
||||
if 'servermodelparentsid' in servermodel:
|
||||
for servermodelparentid in servermodel['servermodelparentsid']:
|
||||
self.servermodel_legacy(servermodel['servermodelname'],
|
||||
self.servermodel_legacy(risotto_context,
|
||||
servermodel['servermodelname'],
|
||||
servermodel['servermodelid'],
|
||||
servermodelparentid)
|
||||
|
||||
|
@ -156,6 +157,7 @@ class Risotto(Controller):
|
|||
return metaconfig
|
||||
|
||||
def servermodel_legacy(self,
|
||||
risotto_context: Context,
|
||||
servermodel_name: str,
|
||||
servermodel_id: int,
|
||||
servermodel_parent_id: int) -> None:
|
||||
|
@ -284,99 +286,106 @@ class Risotto(Controller):
|
|||
async def server_deleted(self,
|
||||
server_id: int) -> None:
|
||||
# delete config to it's parents
|
||||
for config in self.server[server_id].values():
|
||||
for server_type in ['server', 'server_to_deploy']:
|
||||
config = self.server[server_id]['server']
|
||||
for parent in config.config.parents():
|
||||
parent.config.pop(config.config.name())
|
||||
delete_session(config.config.name())
|
||||
delete_session(storage=self.save_storage,
|
||||
session_id=config.config.name())
|
||||
# delete metaconfig
|
||||
del self.server[server_id]
|
||||
|
||||
@register('v1.servermodel.created')
|
||||
async def servermodel_created(self,
|
||||
servermodels) -> None:
|
||||
risotto_context: Context,
|
||||
servermodelid: int,
|
||||
servermodelname: str,
|
||||
servermodelparentsid: List[int]) -> None:
|
||||
""" when servermodels are created, load it and do link
|
||||
"""
|
||||
for servermodel in servermodels:
|
||||
await self.load_servermodel(servermodel['servermodelid'], servermodel['servermodelname'])
|
||||
for servermodel in servermodels:
|
||||
if 'servermodelparentsid' in servermodel:
|
||||
for servermodelparentid in servermodel['servermodelparentsid']:
|
||||
self.servermodel_legacy(servermodel['servermodelname'], servermodel['servermodelid'], servermodelparentid)
|
||||
await self.load_and_link_servermodel(risotto_context,
|
||||
servermodelid,
|
||||
servermodelname,
|
||||
servermodelparentsid)
|
||||
|
||||
|
||||
async def load_and_link_servermodel(self,
|
||||
risotto_context: Context,
|
||||
servermodelid: int,
|
||||
servermodelname: str,
|
||||
servermodelparentsid: List[int]) -> None:
|
||||
await self.load_servermodel(risotto_context,
|
||||
servermodelid,
|
||||
servermodelname)
|
||||
if servermodelparentsid is not None:
|
||||
for servermodelparentid in servermodelparentsid:
|
||||
self.servermodel_legacy(risotto_context,
|
||||
servermodelname,
|
||||
servermodelid,
|
||||
servermodelparentid)
|
||||
|
||||
def servermodel_delete(self,
|
||||
servermodelid: int) -> List[MetaConfig]:
|
||||
metaconfig = self.servermodel.pop(servermodelid)
|
||||
mixconfig = next(metaconfig.config.list())
|
||||
children = []
|
||||
for child in mixconfig.config.list():
|
||||
children.append(child)
|
||||
mixconfig.config.pop(child.config.name())
|
||||
metaconfig.config.pop(mixconfig.config.name())
|
||||
delete_session(storage=self.save_storage,
|
||||
session_id=mixconfig.config.name())
|
||||
del mixconfig
|
||||
for parent in metaconfig.config.parents():
|
||||
parent.config.pop(metaconfig.config.name())
|
||||
delete_session(storage=self.save_storage,
|
||||
session_id=metaconfig.config.name())
|
||||
return children
|
||||
|
||||
@register('v1.servermodel.updated')
|
||||
async def servermodel_updated(self,
|
||||
risotto_context: Context,
|
||||
servermodels) -> None:
|
||||
for servermodel in servermodels:
|
||||
servermodelid = servermodel['servermodelid']
|
||||
servermodelname = servermodel['servermodelname']
|
||||
servermodelparentsid = servermodel.get('servermodelparentsid')
|
||||
log.info_msg(risotto_context,
|
||||
None,
|
||||
f'Reload servermodel {servermodelname} ({servermodelid})')
|
||||
# unlink cache to force download new aggregated file
|
||||
cache_file = join(ROOT_CACHE_DIR, str(servermodelid)+".xml")
|
||||
if isfile(cache_file):
|
||||
unlink(cache_file)
|
||||
servermodelid: int,
|
||||
servermodelname: str,
|
||||
servermodelparentsid: List[int]) -> None:
|
||||
log.info_msg(risotto_context,
|
||||
None,
|
||||
f'Reload servermodel {servermodelname} ({servermodelid})')
|
||||
# unlink cache to force download new aggregated file
|
||||
cache_file = join(ROOT_CACHE_DIR, str(servermodelid)+".xml")
|
||||
if isfile(cache_file):
|
||||
unlink(cache_file)
|
||||
|
||||
# get current servermodel
|
||||
old_servermodel = self.servermodel[servermodelid]
|
||||
# store all informations
|
||||
if servermodelid in self.servermodel:
|
||||
old_values = self.servermodel[servermodelid].value.exportation()
|
||||
old_permissives = self.servermodel[servermodelid].permissive.exportation()
|
||||
old_properties = self.servermodel[servermodelid].property.exportation()
|
||||
children = self.servermodel_delete(servermodelid)
|
||||
else:
|
||||
old_values = None
|
||||
|
||||
# create new one
|
||||
await self.load_servermodel(servermodelid, servermodelname)
|
||||
# create new one
|
||||
await self.load_and_link_servermodel(risotto_context,
|
||||
servermodelid,
|
||||
servermodelname,
|
||||
servermodelparentsid)
|
||||
|
||||
# migrate all informations
|
||||
self.servermodel[servermodelid].value.importation(old_servermodel.value.exportation())
|
||||
self.servermodel[servermodelid].permissive.importation(old_servermodel.permissive.exportation())
|
||||
self.servermodel[servermodelid].property.importation(old_servermodel.property.exportation())
|
||||
|
||||
# remove link to legacy
|
||||
if servermodelparentsid:
|
||||
for servermodelparentid in servermodelparentsid:
|
||||
mix = self.servermodel[servermodelparentid].config.get('m_v_' + str(servermodelparentid))
|
||||
try:
|
||||
mix.config.pop(old_servermodel.config.name())
|
||||
except:
|
||||
# if mix config is reloaded too
|
||||
pass
|
||||
# add new link
|
||||
self.servermodel_legacy(servermodelname, servermodelid, servermodelparentid)
|
||||
|
||||
# reload servers or servermodels in servermodel
|
||||
for subconfig in old_servermodel.config.list():
|
||||
if not isinstance(subconfig, MixConfig):
|
||||
# a server
|
||||
name = subconfig.config.name()
|
||||
if name.startswith('str_'):
|
||||
continue
|
||||
server_id = subconfig.information.get('server_id')
|
||||
server_name = subconfig.information.get('server_name')
|
||||
try:
|
||||
old_servermodel.config.pop(name)
|
||||
old_servermodel.config.pop(f'std_{server_id}')
|
||||
except:
|
||||
pass
|
||||
del self.server[server_id]
|
||||
self.load_server(risotto_context,
|
||||
server_id,
|
||||
server_name,
|
||||
servermodelid)
|
||||
else:
|
||||
# a servermodel
|
||||
for subsubconfig in subconfig.config.list():
|
||||
name = subsubconfig.config.name()
|
||||
try:
|
||||
subconfig.config.pop(name)
|
||||
except:
|
||||
pass
|
||||
self.servermodel_legacy(subsubconfig.information.get('servermodel_name'),
|
||||
subsubconfig.information.get('servermodel_id'),
|
||||
servermodelid)
|
||||
# migrates informations
|
||||
if old_values is not None:
|
||||
self.servermodel[servermodelid].value.importation(old_values)
|
||||
self.servermodel[servermodelid].permissive.importation(old_permissives)
|
||||
self.servermodel[servermodelid].property.importation(old_properties)
|
||||
for child in children:
|
||||
self.servermodel_legacy(risotto_context,
|
||||
child.information.get('servermodel_name'),
|
||||
child.information.get('servermodel_id'),
|
||||
servermodelid)
|
||||
|
||||
@register('v1.config.configuration.server.get', None)
|
||||
async def get_configuration(self,
|
||||
server_id: int,
|
||||
deploy: bool) -> bytes:
|
||||
deployed: bool) -> bytes:
|
||||
if server_id not in self.server:
|
||||
msg = _(f'cannot find server with id {server_id}')
|
||||
log.error_msg(risotto_context,
|
||||
|
@ -384,16 +393,16 @@ class Risotto(Controller):
|
|||
msg)
|
||||
raise CallError(msg)
|
||||
|
||||
if deploy:
|
||||
if deployed:
|
||||
server = self.server[server_id]['server']
|
||||
else:
|
||||
server = self.server[server_id]['server_to_deploy']
|
||||
|
||||
server.property.read_only()
|
||||
try:
|
||||
dico = server.value.dict(fullpath=True)
|
||||
configuration = server.value.dict(fullpath=True)
|
||||
except:
|
||||
if deploy:
|
||||
if deployed:
|
||||
msg = _(f'No configuration available for server {server_id}')
|
||||
else:
|
||||
msg = _(f'No undeployed configuration available for server {server_id}')
|
||||
|
@ -401,8 +410,9 @@ class Risotto(Controller):
|
|||
None,
|
||||
msg)
|
||||
raise CallError(msg)
|
||||
return dumps(dico).encode()
|
||||
|
||||
return {'server_id': server_id,
|
||||
'deployed': deployed,
|
||||
'configuration': configuration}
|
||||
|
||||
@register('v1.config.configuration.server.deploy', 'v1.config.configuration.server.updated')
|
||||
async def deploy_configuration(self,
|
||||
|
@ -428,4 +438,4 @@ class Risotto(Controller):
|
|||
config.property.importation(config_std.property.exportation())
|
||||
|
||||
return {'server_id': server_id,
|
||||
'deploy': True}
|
||||
'deployed': True}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from os import urandom # , unlink
|
||||
from binascii import hexlify
|
||||
from traceback import print_exc
|
||||
from json import dumps
|
||||
from typing import Dict, List, Optional, Any
|
||||
from tiramisu import Storage
|
||||
|
||||
|
@ -28,6 +27,7 @@ class Risotto(Controller):
|
|||
return storage_servermodel
|
||||
|
||||
def get_session(self,
|
||||
risotto_context: Context,
|
||||
session_id: str,
|
||||
type: str) -> Dict:
|
||||
""" Get session information from storage
|
||||
|
@ -36,7 +36,8 @@ class Risotto(Controller):
|
|||
storage = storage_server
|
||||
else:
|
||||
storage = storage_servermodel
|
||||
return storage.get_session(session_id)
|
||||
return storage.get_session(session_id,
|
||||
risotto_context.username)
|
||||
|
||||
def get_session_informations(self,
|
||||
risotto_context: Context,
|
||||
|
@ -44,9 +45,9 @@ class Risotto(Controller):
|
|||
type: str) -> Dict:
|
||||
""" format session with a session ID name
|
||||
"""
|
||||
session = self.get_session(session_id,
|
||||
type,
|
||||
risotto_context.username)
|
||||
session = self.get_session(risotto_context,
|
||||
session_id,
|
||||
type)
|
||||
return self.format_session(session_id,
|
||||
session)
|
||||
|
||||
|
@ -104,16 +105,16 @@ class Risotto(Controller):
|
|||
self.modify_storage)
|
||||
|
||||
# return session's information
|
||||
return self.get_session_informations(session_id,
|
||||
return self.get_session_informations(risotto_context,
|
||||
session_id,
|
||||
type)
|
||||
|
||||
@register(['v1.session.server.list', 'v1.session.servermodel.list'], None)
|
||||
async def list_session_server(self,
|
||||
risotto_context: Context) -> Dict:
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
storage = self.get_storage(type,
|
||||
risotto_context.username)
|
||||
return [self.format_session(session_id, session) or session_id, session in storage.get_sessions().items()]
|
||||
storage = self.get_storage(type)
|
||||
return [self.format_session(session_id, session) for session_id, session in storage.get_sessions().items()]
|
||||
|
||||
|
||||
@register(['v1.session.server.filter', 'v1.session.servermodel.filter'], None)
|
||||
|
@ -127,7 +128,7 @@ class Risotto(Controller):
|
|||
storage = self.get_storage(type)
|
||||
# to validate the session right
|
||||
storage.get_session(session_id,
|
||||
username)
|
||||
risotto_context.username)
|
||||
if namespace is not None:
|
||||
storage.set_namespace(session_id,
|
||||
namespace)
|
||||
|
@ -139,7 +140,8 @@ class Risotto(Controller):
|
|||
if debug is not None:
|
||||
storage.set_config_debug(session_id,
|
||||
debug)
|
||||
return self.get_session_informations(session_id,
|
||||
return self.get_session_informations(risotto_context,
|
||||
session_id,
|
||||
type)
|
||||
|
||||
@register(['v1.session.server.configure', 'v1.session.servermodel.configure'], None)
|
||||
|
@ -152,25 +154,25 @@ class Risotto(Controller):
|
|||
value: Any,
|
||||
value_multi: Optional[List]) -> Dict:
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
session = self.get_session(session_id,
|
||||
type,
|
||||
risotto_context.username)
|
||||
session = self.get_session(risotto_context,
|
||||
session_id,
|
||||
type)
|
||||
# if multi and not follower the value is in fact in value_multi
|
||||
option = session['config'].option(name).option
|
||||
option = session['option'].option(name).option
|
||||
if option.ismulti() and not option.isfollower():
|
||||
value = value_multi
|
||||
try:
|
||||
update = {'name': name,
|
||||
'action': action,
|
||||
'value': value}
|
||||
if index is not None:
|
||||
update['index'] = index
|
||||
updates = {'updates': [update]}
|
||||
session['option'].updates(updates)
|
||||
except Exception as err:
|
||||
if DEBUG:
|
||||
print_exc()
|
||||
raise CallError(str(err))
|
||||
namespace = session['namespace']
|
||||
update = {'name': f'{namespace}.{name}',
|
||||
'action': action,
|
||||
'value': value}
|
||||
if index is not None:
|
||||
update['index'] = index
|
||||
updates = {'updates': [update]}
|
||||
ret = session['option'].updates(updates)
|
||||
if update['name'] in ret:
|
||||
for val in ret[update['name']][index]:
|
||||
if isinstance(val, ValueError):
|
||||
raise CallError(val)
|
||||
ret = {'session_id': session_id,
|
||||
'name': name}
|
||||
if index is not None:
|
||||
|
@ -182,9 +184,9 @@ class Risotto(Controller):
|
|||
risotto_context: Context,
|
||||
session_id: str) -> Dict:
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
session = self.get_session(session_id,
|
||||
type,
|
||||
risotto_context.username)
|
||||
session = self.get_session(risotto_context,
|
||||
session_id,
|
||||
type)
|
||||
try:
|
||||
session['config'].forcepermissive.option(session['namespace']).value.dict()
|
||||
except Exception as err:
|
||||
|
@ -205,13 +207,17 @@ class Risotto(Controller):
|
|||
@register(['v1.session.server.get', 'v1.session.servermodel.get'], None)
|
||||
async def get_session_server(self,
|
||||
risotto_context: Context,
|
||||
session_id: str) -> Dict:
|
||||
session_id: str,
|
||||
name: Optional[str]) -> Dict:
|
||||
type = risotto_context.message.rsplit('.', 2)[-2]
|
||||
session = self.get_session(session_id,
|
||||
type,
|
||||
risotto_context.username)
|
||||
session = self.get_session(risotto_context,
|
||||
session_id,
|
||||
type)
|
||||
info = self.format_session(session_id, session)
|
||||
info['content'] = dumps(session['option'].value.dict(fullpath=True))
|
||||
if name is not None:
|
||||
info['content'] = {name: session['option'].option(name).value.get()}
|
||||
else:
|
||||
info['content'] = session['option'].value.dict()
|
||||
return info
|
||||
|
||||
@register(['v1.session.server.stop', 'v1.session.servermodel.stop'], None)
|
||||
|
|
|
@ -66,7 +66,7 @@ class Storage(object):
|
|||
mode: str):
|
||||
""" Define which edition mode to select
|
||||
"""
|
||||
config = self.session[id]['config']
|
||||
config = self.sessions[id]['config']
|
||||
for mode_level in modes.values():
|
||||
if modes[mode] < mode_level:
|
||||
config.property.add(mode_level.name)
|
||||
|
@ -77,7 +77,7 @@ class Storage(object):
|
|||
def set_config_debug(self, id_, is_debug):
|
||||
""" Enable/Disable debug mode
|
||||
"""
|
||||
config = self.session[id_]['config']
|
||||
config = self.sessions[id_]['config']
|
||||
if is_debug:
|
||||
config.property.pop('hidden')
|
||||
else:
|
||||
|
@ -94,13 +94,14 @@ class Storage(object):
|
|||
return self.sessions;
|
||||
|
||||
def get_session(self,
|
||||
id: int,
|
||||
session_id: int,
|
||||
username: str) -> Dict:
|
||||
if id not in self.sessions:
|
||||
if session_id not in self.sessions:
|
||||
raise Exception(f'the session {id} not exists')
|
||||
if username != storage.get_session(session_id)['username']:
|
||||
session = self.sessions[session_id]
|
||||
if username != session['username']:
|
||||
raise NotAllowedError()
|
||||
return self.sessions[id]
|
||||
return session
|
||||
|
||||
def del_session(self,
|
||||
id: int):
|
||||
|
|
|
@ -13,7 +13,6 @@ def setup_module(module):
|
|||
validate=False)
|
||||
config_module = dispatcher.get_service('config')
|
||||
config_module.save_storage = Storage(engine='sqlite3', dir_database=DATABASE_DIR, name='test')
|
||||
config_module.save_persistent = False
|
||||
dispatcher.set_module('server', import_module(f'.server', 'fake_services'))
|
||||
dispatcher.set_module('servermodel', import_module(f'.servermodel', 'fake_services'))
|
||||
|
||||
|
|
|
@ -0,0 +1,501 @@
|
|||
from importlib import import_module
|
||||
import pytest
|
||||
from tiramisu import Storage
|
||||
from risotto.context import Context
|
||||
from risotto.services import load_services
|
||||
from risotto.dispatcher import dispatcher
|
||||
from risotto.config import DATABASE_DIR
|
||||
from risotto.services.session.storage import storage_server, storage_servermodel
|
||||
|
||||
|
||||
def get_fake_context(module_name):
|
||||
risotto_context = Context()
|
||||
risotto_context.username = 'test'
|
||||
risotto_context.paths.append(f'{module_name}.on_join')
|
||||
risotto_context.type = None
|
||||
return risotto_context
|
||||
|
||||
|
||||
def setup_module(module):
|
||||
load_services(['config', 'session'],
|
||||
validate=False)
|
||||
config_module = dispatcher.get_service('config')
|
||||
config_module.save_storage = Storage(engine='sqlite3', dir_database=DATABASE_DIR, name='test')
|
||||
dispatcher.set_module('server', import_module(f'.server', 'fake_services'))
|
||||
dispatcher.set_module('servermodel', import_module(f'.servermodel', 'fake_services'))
|
||||
|
||||
|
||||
def teardown_function(function):
|
||||
config_module = dispatcher.get_service('session')
|
||||
storage_server.sessions = {}
|
||||
storage_servermodel.sessions = {}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_start():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_list():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
assert not await dispatcher.call('v1',
|
||||
'session.server.list',
|
||||
fake_context)
|
||||
await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
assert await dispatcher.call('v1',
|
||||
'session.server.list',
|
||||
fake_context)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_filter_namespace():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
session_id = session['session_id']
|
||||
namespace = 'containers'
|
||||
await dispatcher.call('v1',
|
||||
'session.server.filter',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
namespace=namespace)
|
||||
list_result = await dispatcher.call('v1',
|
||||
'session.server.list',
|
||||
fake_context)
|
||||
assert list_result[0]['namespace'] == namespace
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_filter_mode():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
session_id = session['session_id']
|
||||
assert session['mode'] == 'normal'
|
||||
mode = 'expert'
|
||||
await dispatcher.call('v1',
|
||||
'session.server.filter',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
mode=mode)
|
||||
list_result = await dispatcher.call('v1',
|
||||
'session.server.list',
|
||||
fake_context)
|
||||
assert list_result[0]['mode'] == mode
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_filter_debug():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
session_id = session['session_id']
|
||||
assert session['debug'] == False
|
||||
debug = True
|
||||
await dispatcher.call('v1',
|
||||
'session.server.filter',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
debug=debug)
|
||||
list_result = await dispatcher.call('v1',
|
||||
'session.server.list',
|
||||
fake_context)
|
||||
assert list_result[0]['debug'] == debug
|
||||
#FIXME
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_filter_get():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
session_id = session['session_id']
|
||||
values = await dispatcher.call('v1',
|
||||
'session.server.get',
|
||||
fake_context,
|
||||
session_id=session_id)
|
||||
assert values == {'content': {"general.mode_conteneur_actif": "non",
|
||||
"general.master.master": [],
|
||||
"general.master.slave1": [],
|
||||
"general.master.slave2": []},
|
||||
'debug': False,
|
||||
'id': 3,
|
||||
'mode': 'normal',
|
||||
'namespace': 'creole',
|
||||
'session_id': session_id,
|
||||
'timestamp': values['timestamp'],
|
||||
'username': 'test'}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_filter_get_one_value():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
session_id = session['session_id']
|
||||
values = await dispatcher.call('v1',
|
||||
'session.server.get',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
name="general.mode_conteneur_actif")
|
||||
assert values == {'content': {"general.mode_conteneur_actif": "non"},
|
||||
'debug': False,
|
||||
'id': 3,
|
||||
'mode': 'normal',
|
||||
'namespace': 'creole',
|
||||
'session_id': session_id,
|
||||
'timestamp': values['timestamp'],
|
||||
'username': 'test'}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_filter_configure():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
session_id = session['session_id']
|
||||
await dispatcher.call('v1',
|
||||
'session.server.configure',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
action='modify',
|
||||
name='general.mode_conteneur_actif',
|
||||
value='oui')
|
||||
list_result = await dispatcher.call('v1',
|
||||
'session.server.list',
|
||||
fake_context)
|
||||
values = await dispatcher.call('v1',
|
||||
'session.server.get',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
name="general.mode_conteneur_actif")
|
||||
assert values == {'content': {"general.mode_conteneur_actif": "oui"},
|
||||
'debug': False,
|
||||
'id': 3,
|
||||
'mode': 'normal',
|
||||
'namespace': 'creole',
|
||||
'session_id': session_id,
|
||||
'timestamp': values['timestamp'],
|
||||
'username': 'test'}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_filter_validate():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
session_id = session['session_id']
|
||||
await dispatcher.call('v1',
|
||||
'session.server.validate',
|
||||
fake_context,
|
||||
session_id=session_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_stop():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.server:
|
||||
await config_module.on_join(fake_context)
|
||||
assert not await dispatcher.call('v1',
|
||||
'session.server.list',
|
||||
fake_context)
|
||||
start = await dispatcher.call('v1',
|
||||
'session.server.start',
|
||||
fake_context,
|
||||
id=3)
|
||||
session_id = start['session_id']
|
||||
assert await dispatcher.call('v1',
|
||||
'session.server.list',
|
||||
fake_context)
|
||||
await dispatcher.call('v1',
|
||||
'session.server.stop',
|
||||
fake_context,
|
||||
session_id=session_id)
|
||||
assert not await dispatcher.call('v1',
|
||||
'session.server.list',
|
||||
fake_context)
|
||||
|
||||
|
||||
# servermodel
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_start():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_list():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
assert not await dispatcher.call('v1',
|
||||
'session.servermodel.list',
|
||||
fake_context)
|
||||
await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
assert await dispatcher.call('v1',
|
||||
'session.servermodel.list',
|
||||
fake_context)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_filter_namespace():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
session_id = session['session_id']
|
||||
namespace = 'containers'
|
||||
await dispatcher.call('v1',
|
||||
'session.servermodel.filter',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
namespace=namespace)
|
||||
list_result = await dispatcher.call('v1',
|
||||
'session.servermodel.list',
|
||||
fake_context)
|
||||
assert list_result[0]['namespace'] == namespace
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_filter_mode():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
session_id = session['session_id']
|
||||
assert session['mode'] == 'normal'
|
||||
mode = 'expert'
|
||||
await dispatcher.call('v1',
|
||||
'session.servermodel.filter',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
mode=mode)
|
||||
list_result = await dispatcher.call('v1',
|
||||
'session.servermodel.list',
|
||||
fake_context)
|
||||
assert list_result[0]['mode'] == mode
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_filter_debug():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
session_id = session['session_id']
|
||||
assert session['debug'] == False
|
||||
debug = True
|
||||
await dispatcher.call('v1',
|
||||
'session.servermodel.filter',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
debug=debug)
|
||||
list_result = await dispatcher.call('v1',
|
||||
'session.servermodel.list',
|
||||
fake_context)
|
||||
assert list_result[0]['debug'] == debug
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_filter_get():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
session_id = session['session_id']
|
||||
values = await dispatcher.call('v1',
|
||||
'session.servermodel.get',
|
||||
fake_context,
|
||||
session_id=session_id)
|
||||
assert values == {'content': {"general.mode_conteneur_actif": "non",
|
||||
"general.master.master": [],
|
||||
"general.master.slave1": [],
|
||||
"general.master.slave2": []},
|
||||
'debug': False,
|
||||
'id': 1,
|
||||
'mode': 'normal',
|
||||
'namespace': 'creole',
|
||||
'session_id': session_id,
|
||||
'timestamp': values['timestamp'],
|
||||
'username': 'test'}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_filter_get_one_value():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
session_id = session['session_id']
|
||||
values = await dispatcher.call('v1',
|
||||
'session.servermodel.get',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
name="general.mode_conteneur_actif")
|
||||
assert values == {'content': {"general.mode_conteneur_actif": "non"},
|
||||
'debug': False,
|
||||
'id': 1,
|
||||
'mode': 'normal',
|
||||
'namespace': 'creole',
|
||||
'session_id': session_id,
|
||||
'timestamp': values['timestamp'],
|
||||
'username': 'test'}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_filter_configure():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
session_id = session['session_id']
|
||||
await dispatcher.call('v1',
|
||||
'session.servermodel.configure',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
action='modify',
|
||||
name='general.mode_conteneur_actif',
|
||||
value='oui')
|
||||
list_result = await dispatcher.call('v1',
|
||||
'session.servermodel.list',
|
||||
fake_context)
|
||||
values = await dispatcher.call('v1',
|
||||
'session.servermodel.get',
|
||||
fake_context,
|
||||
session_id=session_id,
|
||||
name="general.mode_conteneur_actif")
|
||||
assert values == {'content': {"general.mode_conteneur_actif": "oui"},
|
||||
'debug': False,
|
||||
'id': 1,
|
||||
'mode': 'normal',
|
||||
'namespace': 'creole',
|
||||
'session_id': session_id,
|
||||
'timestamp': values['timestamp'],
|
||||
'username': 'test'}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_filter_validate():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
session = await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
session_id = session['session_id']
|
||||
await dispatcher.call('v1',
|
||||
'session.servermodel.validate',
|
||||
fake_context,
|
||||
session_id=session_id)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_servermodel_stop():
|
||||
fake_context = get_fake_context('session')
|
||||
config_module = dispatcher.get_service('config')
|
||||
if not config_module.servermodel:
|
||||
await config_module.on_join(fake_context)
|
||||
assert not await dispatcher.call('v1',
|
||||
'session.servermodel.list',
|
||||
fake_context)
|
||||
start = await dispatcher.call('v1',
|
||||
'session.servermodel.start',
|
||||
fake_context,
|
||||
id=1)
|
||||
session_id = start['session_id']
|
||||
assert await dispatcher.call('v1',
|
||||
'session.servermodel.list',
|
||||
fake_context)
|
||||
await dispatcher.call('v1',
|
||||
'session.servermodel.stop',
|
||||
fake_context,
|
||||
session_id=session_id)
|
||||
assert not await dispatcher.call('v1',
|
||||
'session.servermodel.list',
|
||||
fake_context)
|
Loading…
Reference in New Issue