mirror of
https://github.com/dkmstr/openuds.git
synced 2025-01-11 05:17:55 +03:00
Some minor renames and adding new tests
This commit is contained in:
parent
0c3a1d746e
commit
db082109bd
@ -36,16 +36,12 @@ import typing
|
|||||||
import collections.abc
|
import collections.abc
|
||||||
from .job import Job
|
from .job import Job
|
||||||
from .delayed_task import DelayedTask
|
from .delayed_task import DelayedTask
|
||||||
|
from .jobs_factory import JobsFactory
|
||||||
# Imports for type checking
|
|
||||||
if typing.TYPE_CHECKING:
|
|
||||||
from .jobs_factory import JobsFactory
|
|
||||||
|
|
||||||
|
|
||||||
def factory() -> 'JobsFactory':
|
def factory() -> 'JobsFactory':
|
||||||
"""
|
"""
|
||||||
Returns a singleton to a jobs factory
|
Returns a singleton to a jobs factory
|
||||||
"""
|
"""
|
||||||
from .jobs_factory import JobsFactory # pylint: disable=import-outside-toplevel
|
|
||||||
|
|
||||||
return JobsFactory()
|
return JobsFactory()
|
||||||
|
@ -94,14 +94,14 @@ class TaskManager(metaclass=singleton.Singleton):
|
|||||||
logger.info("Caught term signal, finishing task manager")
|
logger.info("Caught term signal, finishing task manager")
|
||||||
TaskManager.manager().keep_running = False
|
TaskManager.manager().keep_running = False
|
||||||
|
|
||||||
def register_job(self, jobType: type[jobs.Job]) -> None:
|
def register_job(self, job_type: type[jobs.Job]) -> None:
|
||||||
jobName = jobType.friendly_name
|
job_name = job_type.friendly_name
|
||||||
jobs.factory().put(jobName, jobType)
|
jobs.factory().register(job_name, job_type)
|
||||||
|
|
||||||
def register_scheduled_tasks(self) -> None:
|
def register_scheduled_tasks(self) -> None:
|
||||||
logger.info("Registering sheduled tasks")
|
logger.info("Registering sheduled tasks")
|
||||||
|
|
||||||
# Simply import this to make workers "auto import themself"
|
# Simply import this to make workers "register" themselves
|
||||||
from uds.core import workers # pylint: disable=unused-import, import-outside-toplevel
|
from uds.core import workers # pylint: disable=unused-import, import-outside-toplevel
|
||||||
|
|
||||||
def add_other_tasks(self) -> None:
|
def add_other_tasks(self) -> None:
|
||||||
|
@ -286,9 +286,9 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
|||||||
cache.save(update_fields=['cache_level'])
|
cache.save(update_fields=['cache_level'])
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'Service State: %a %s %s',
|
'Service State: %a %s %s',
|
||||||
State.from_str(state).literal,
|
State.from_str(state).localized,
|
||||||
State.from_str(cache.state).literal,
|
State.from_str(cache.state).localized,
|
||||||
State.from_str(cache.os_state).literal,
|
State.from_str(cache.os_state).localized,
|
||||||
)
|
)
|
||||||
if State.from_str(state).is_runing() and cache.is_usable():
|
if State.from_str(state).is_runing() and cache.is_usable():
|
||||||
cache.set_state(State.PREPARING)
|
cache.set_state(State.PREPARING)
|
||||||
@ -336,7 +336,7 @@ class UserServiceManager(metaclass=singleton.Singleton):
|
|||||||
if userservice.is_usable() is False and State.from_str(userservice.state).is_removable() is False:
|
if userservice.is_usable() is False and State.from_str(userservice.state).is_removable() is False:
|
||||||
raise OperationException(_('Can\'t remove a non active element'))
|
raise OperationException(_('Can\'t remove a non active element'))
|
||||||
userservice.set_state(State.REMOVING)
|
userservice.set_state(State.REMOVING)
|
||||||
logger.debug("***** The state now is %s *****", State.from_str(userservice.state).literal)
|
logger.debug("***** The state now is %s *****", State.from_str(userservice.state).localized)
|
||||||
userservice.set_in_use(False) # For accounting, ensure that it is not in use right now
|
userservice.set_in_use(False) # For accounting, ensure that it is not in use right now
|
||||||
userservice.save()
|
userservice.save()
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ class StateUpdater:
|
|||||||
logger.debug(
|
logger.debug(
|
||||||
'Running Executor for %s with state %s and executor %s',
|
'Running Executor for %s with state %s and executor %s',
|
||||||
self.user_service.friendly_name,
|
self.user_service.friendly_name,
|
||||||
State.from_str(state).literal,
|
State.from_str(state).localized,
|
||||||
executor,
|
executor,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -133,8 +133,8 @@ class UpdateFromPreparing(StateUpdater):
|
|||||||
|
|
||||||
logger.debug(
|
logger.debug(
|
||||||
'State %s, StateOS %s for %s',
|
'State %s, StateOS %s for %s',
|
||||||
State.from_str(state).literal,
|
State.from_str(state).localized,
|
||||||
State.from_str(stateOs).literal,
|
State.from_str(stateOs).localized,
|
||||||
self.user_service.friendly_name,
|
self.user_service.friendly_name,
|
||||||
)
|
)
|
||||||
if stateOs == State.RUNNING:
|
if stateOs == State.RUNNING:
|
||||||
@ -193,10 +193,10 @@ class UpdateFromCanceling(StateUpdater):
|
|||||||
|
|
||||||
class UpdateFromOther(StateUpdater):
|
class UpdateFromOther(StateUpdater):
|
||||||
def finish(self):
|
def finish(self):
|
||||||
self.set_error(f'Unknown running transition from {State.from_str(self.user_service.state).literal}')
|
self.set_error(f'Unknown running transition from {State.from_str(self.user_service.state).localized}')
|
||||||
|
|
||||||
def running(self):
|
def running(self):
|
||||||
self.set_error(f'Unknown running transition from {State.from_str(self.user_service.state).literal}')
|
self.set_error(f'Unknown running transition from {State.from_str(self.user_service.state).localized}')
|
||||||
|
|
||||||
|
|
||||||
class UserServiceOpChecker(DelayedTask):
|
class UserServiceOpChecker(DelayedTask):
|
||||||
@ -245,7 +245,7 @@ class UserServiceOpChecker(DelayedTask):
|
|||||||
logger.debug(
|
logger.debug(
|
||||||
'Updating %s from %s with updater %s and state %s',
|
'Updating %s from %s with updater %s and state %s',
|
||||||
userservice.friendly_name,
|
userservice.friendly_name,
|
||||||
State.from_str(userservice.state).literal,
|
State.from_str(userservice.state).localized,
|
||||||
updater,
|
updater,
|
||||||
state,
|
state,
|
||||||
)
|
)
|
||||||
|
@ -95,7 +95,7 @@ class State(enum.StrEnum):
|
|||||||
return [self.LAUNCHING, self.PREPARING]
|
return [self.LAUNCHING, self.PREPARING]
|
||||||
|
|
||||||
@classproperty
|
@classproperty
|
||||||
def literal(self) -> str:
|
def localized(self) -> str:
|
||||||
"""Returns the literal translation of the state"""
|
"""Returns the literal translation of the state"""
|
||||||
return _TRANSLATIONS.get(self, _TRANSLATIONS[State.UNKNOWN])
|
return _TRANSLATIONS.get(self, _TRANSLATIONS[State.UNKNOWN])
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class Factory(typing.Generic[V], metaclass=singleton.Singleton):
|
|||||||
'''
|
'''
|
||||||
return self._objects
|
return self._objects
|
||||||
|
|
||||||
def put(self, type_name: str, type_: type[V]) -> None:
|
def register(self, type_name: str, type_: type[V]) -> None:
|
||||||
'''
|
'''
|
||||||
Inserts an object into the factory.
|
Inserts an object into the factory.
|
||||||
'''
|
'''
|
||||||
@ -50,11 +50,32 @@ class Factory(typing.Generic[V], metaclass=singleton.Singleton):
|
|||||||
'''
|
'''
|
||||||
return type_name.lower() in self._objects
|
return type_name.lower() in self._objects
|
||||||
|
|
||||||
|
def items(self) -> collections.abc.ItemsView[str, type[V]]:
|
||||||
|
'''
|
||||||
|
Returns an object from the factory.
|
||||||
|
'''
|
||||||
|
return self._objects.items()
|
||||||
|
|
||||||
|
def keys(self) -> collections.abc.KeysView[str]:
|
||||||
|
'''
|
||||||
|
Returns an object from the factory.
|
||||||
|
'''
|
||||||
|
return self._objects.keys()
|
||||||
|
|
||||||
|
def values(self) -> collections.abc.ValuesView[type[V]]:
|
||||||
|
'''
|
||||||
|
Returns an object from the factory.
|
||||||
|
'''
|
||||||
|
return self._objects.values()
|
||||||
|
|
||||||
# aliases for get
|
# aliases for get
|
||||||
lookup = get
|
lookup = get
|
||||||
__getitem__ = get
|
__getitem__ = get
|
||||||
|
__setitem__ = register
|
||||||
__contains__ = has
|
__contains__ = has
|
||||||
|
|
||||||
|
# Note that there is no remove method, as we don't intend to remove once added to a factory
|
||||||
|
|
||||||
|
|
||||||
class ModuleFactory(Factory[T]):
|
class ModuleFactory(Factory[T]):
|
||||||
'''
|
'''
|
||||||
@ -72,4 +93,4 @@ class ModuleFactory(Factory[T]):
|
|||||||
Inserts an object into the factory.
|
Inserts an object into the factory.
|
||||||
'''
|
'''
|
||||||
# logger.debug('Adding %s as %s', type_.type(), type_.__module__)
|
# logger.debug('Adding %s as %s', type_.type(), type_.__module__)
|
||||||
super().put(type_.get_type().lower(), type_)
|
super().register(type_.get_type().lower(), type_)
|
||||||
|
@ -165,8 +165,8 @@ class Command(BaseCommand):
|
|||||||
'id': item.uuid,
|
'id': item.uuid,
|
||||||
'unique_id': item.unique_id,
|
'unique_id': item.unique_id,
|
||||||
'friendly_name': item.friendly_name,
|
'friendly_name': item.friendly_name,
|
||||||
'state': State.from_str(item.state).literal,
|
'state': State.from_str(item.state).localized,
|
||||||
'os_state': State.from_str(item.os_state).literal,
|
'os_state': State.from_str(item.os_state).localized,
|
||||||
'state_date': item.state_date,
|
'state_date': item.state_date,
|
||||||
'creation_date': item.creation_date,
|
'creation_date': item.creation_date,
|
||||||
'revision': item.publication and item.publication.revision or '',
|
'revision': item.publication and item.publication.revision or '',
|
||||||
|
@ -94,10 +94,10 @@ class Scheduler(models.Model):
|
|||||||
Returns an instance of the class that this record of the Scheduler represents. This clas is derived
|
Returns an instance of the class that this record of the Scheduler represents. This clas is derived
|
||||||
of uds.core.jobs.Job.Job
|
of uds.core.jobs.Job.Job
|
||||||
"""
|
"""
|
||||||
jobInstance = jobs.factory().lookup(self.name)
|
job_instance_type = jobs.factory().lookup(self.name)
|
||||||
|
|
||||||
if jobInstance:
|
if job_instance_type:
|
||||||
return jobInstance(self.get_environment())
|
return job_instance_type(self.get_environment())
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ class ServicePoolPublication(UUIDModel):
|
|||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return (
|
return (
|
||||||
f'Publication {self.deployed_service.name}, rev {self.revision}, state {State.from_str(self.state).literal}'
|
f'Publication {self.deployed_service.name}, rev {self.revision}, state {State.from_str(self.state).localized}'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -635,7 +635,7 @@ class UserService(UUIDModel, properties.PropertiesMixin):
|
|||||||
return (
|
return (
|
||||||
f'User service {self.name}, unique_id {self.unique_id},'
|
f'User service {self.name}, unique_id {self.unique_id},'
|
||||||
f' cache_level {self.cache_level}, user {self.user},'
|
f' cache_level {self.cache_level}, user {self.user},'
|
||||||
f' name {self.friendly_name}, state {State.from_str(self.state).literal}:{State.from_str(self.os_state).literal}'
|
f' name {self.friendly_name}, state {State.from_str(self.state).localized}:{State.from_str(self.os_state).localized}'
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -35,7 +35,7 @@ import logging
|
|||||||
import typing
|
import typing
|
||||||
import collections.abc
|
import collections.abc
|
||||||
|
|
||||||
from uds.core import services
|
from uds.core import services, consts
|
||||||
from uds.core.managers.user_service import UserServiceManager
|
from uds.core.managers.user_service import UserServiceManager
|
||||||
from uds.core.types.states import State
|
from uds.core.types.states import State
|
||||||
from uds.core.util import log
|
from uds.core.util import log
|
||||||
@ -63,7 +63,6 @@ logger = logging.getLogger(__name__)
|
|||||||
opChangeMac,
|
opChangeMac,
|
||||||
) = range(10)
|
) = range(10)
|
||||||
|
|
||||||
NO_MORE_NAMES = 'NO-NAME-ERROR'
|
|
||||||
UP_STATES = ('up', 'reboot_in_progress', 'powering_up', 'restoring_state')
|
UP_STATES = ('up', 'reboot_in_progress', 'powering_up', 'restoring_state')
|
||||||
|
|
||||||
|
|
||||||
@ -147,7 +146,7 @@ class OVirtLinkedDeployment(services.UserService):
|
|||||||
self.service().get_basename(), self.service().getLenName()
|
self.service().get_basename(), self.service().getLenName()
|
||||||
)
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return NO_MORE_NAMES
|
return consts.NO_MORE_NAMES
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
def set_ip(self, ip: str) -> None:
|
def set_ip(self, ip: str) -> None:
|
||||||
@ -403,7 +402,7 @@ if sys.platform == 'win32':
|
|||||||
"""
|
"""
|
||||||
templateId = self.publication().getTemplateId()
|
templateId = self.publication().getTemplateId()
|
||||||
name = self.get_name()
|
name = self.get_name()
|
||||||
if name == NO_MORE_NAMES:
|
if name == consts.NO_MORE_NAMES:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
'No more names available for this service. (Increase digits for this service to fix)'
|
'No more names available for this service. (Increase digits for this service to fix)'
|
||||||
)
|
)
|
||||||
|
@ -35,7 +35,7 @@ import logging
|
|||||||
import typing
|
import typing
|
||||||
import collections.abc
|
import collections.abc
|
||||||
|
|
||||||
from uds.core import services
|
from uds.core import services, consts
|
||||||
from uds.core.types.states import State
|
from uds.core.types.states import State
|
||||||
from uds.core.util import log
|
from uds.core.util import log
|
||||||
|
|
||||||
@ -52,8 +52,6 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
opCreate, opStart, opShutdown, opRemove, opWait, opError, opFinish, opRetry = range(8)
|
opCreate, opStart, opShutdown, opRemove, opWait, opError, opFinish, opRetry = range(8)
|
||||||
|
|
||||||
NO_MORE_NAMES = 'NO-NAME-ERROR'
|
|
||||||
|
|
||||||
|
|
||||||
class LiveDeployment(services.UserService): # pylint: disable=too-many-public-methods
|
class LiveDeployment(services.UserService): # pylint: disable=too-many-public-methods
|
||||||
# : Recheck every six seconds by default (for task methods)
|
# : Recheck every six seconds by default (for task methods)
|
||||||
@ -115,7 +113,7 @@ class LiveDeployment(services.UserService): # pylint: disable=too-many-public-m
|
|||||||
self.service().get_basename(), self.service().getLenName()
|
self.service().get_basename(), self.service().getLenName()
|
||||||
)
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return NO_MORE_NAMES
|
return consts.NO_MORE_NAMES
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
def set_ip(self, ip: str) -> None:
|
def set_ip(self, ip: str) -> None:
|
||||||
@ -312,7 +310,7 @@ class LiveDeployment(services.UserService): # pylint: disable=too-many-public-m
|
|||||||
"""
|
"""
|
||||||
templateId = self.publication().getTemplateId()
|
templateId = self.publication().getTemplateId()
|
||||||
name = self.get_name()
|
name = self.get_name()
|
||||||
if name == NO_MORE_NAMES:
|
if name == consts.NO_MORE_NAMES:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
'No more names available for this service. (Increase digits for this service to fix)'
|
'No more names available for this service. (Increase digits for this service to fix)'
|
||||||
)
|
)
|
||||||
|
@ -35,7 +35,7 @@ import logging
|
|||||||
import typing
|
import typing
|
||||||
import collections.abc
|
import collections.abc
|
||||||
|
|
||||||
from uds.core import services
|
from uds.core import services, consts
|
||||||
from uds.core.types.states import State
|
from uds.core.types.states import State
|
||||||
from uds.core.util import log
|
from uds.core.util import log
|
||||||
|
|
||||||
@ -52,8 +52,6 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
opCreate, opStart, opSuspend, opRemove, opWait, opError, opFinish, opRetry = range(8)
|
opCreate, opStart, opSuspend, opRemove, opWait, opError, opFinish, opRetry = range(8)
|
||||||
|
|
||||||
NO_MORE_NAMES = 'NO-NAME-ERROR'
|
|
||||||
|
|
||||||
|
|
||||||
class LiveDeployment(services.UserService): # pylint: disable=too-many-public-methods
|
class LiveDeployment(services.UserService): # pylint: disable=too-many-public-methods
|
||||||
"""
|
"""
|
||||||
@ -123,7 +121,7 @@ class LiveDeployment(services.UserService): # pylint: disable=too-many-public-m
|
|||||||
self.service().get_basename(), self.service().getLenName()
|
self.service().get_basename(), self.service().getLenName()
|
||||||
)
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return NO_MORE_NAMES
|
return consts.NO_MORE_NAMES
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
def set_ip(self, ip) -> None:
|
def set_ip(self, ip) -> None:
|
||||||
@ -312,7 +310,7 @@ class LiveDeployment(services.UserService): # pylint: disable=too-many-public-m
|
|||||||
"""
|
"""
|
||||||
templateId = self.publication().getTemplateId()
|
templateId = self.publication().getTemplateId()
|
||||||
name = self.get_name()
|
name = self.get_name()
|
||||||
if name == NO_MORE_NAMES:
|
if name == consts.NO_MORE_NAMES:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
'No more names available for this service. (Increase digits for this service to fix)'
|
'No more names available for this service. (Increase digits for this service to fix)'
|
||||||
)
|
)
|
||||||
|
@ -35,7 +35,7 @@ import logging
|
|||||||
import typing
|
import typing
|
||||||
import collections.abc
|
import collections.abc
|
||||||
|
|
||||||
from uds.core import services
|
from uds.core import services, consts
|
||||||
from uds.core.managers.user_service import UserServiceManager
|
from uds.core.managers.user_service import UserServiceManager
|
||||||
from uds.core.types.states import State
|
from uds.core.types.states import State
|
||||||
from uds.core.util import log
|
from uds.core.util import log
|
||||||
@ -67,7 +67,6 @@ logger = logging.getLogger(__name__)
|
|||||||
opGracelyStop,
|
opGracelyStop,
|
||||||
) = range(11)
|
) = range(11)
|
||||||
|
|
||||||
NO_MORE_NAMES = 'NO-NAME-ERROR'
|
|
||||||
UP_STATES = ('up', 'reboot_in_progress', 'powering_up', 'restoring_state')
|
UP_STATES = ('up', 'reboot_in_progress', 'powering_up', 'restoring_state')
|
||||||
GUEST_SHUTDOWN_WAIT = 90 # Seconds
|
GUEST_SHUTDOWN_WAIT = 90 # Seconds
|
||||||
|
|
||||||
@ -154,7 +153,7 @@ class ProxmoxDeployment(services.UserService):
|
|||||||
self.service().get_basename(), self.service().get_lenname()
|
self.service().get_basename(), self.service().get_lenname()
|
||||||
)
|
)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return NO_MORE_NAMES
|
return consts.NO_MORE_NAMES
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
def set_ip(self, ip: str) -> None:
|
def set_ip(self, ip: str) -> None:
|
||||||
@ -366,7 +365,7 @@ if sys.platform == 'win32':
|
|||||||
"""
|
"""
|
||||||
templateId = self.publication().machine()
|
templateId = self.publication().machine()
|
||||||
name = self.get_name()
|
name = self.get_name()
|
||||||
if name == NO_MORE_NAMES:
|
if name == consts.NO_MORE_NAMES:
|
||||||
raise Exception(
|
raise Exception(
|
||||||
'No more names available for this service. (Increase digits for this service to fix)'
|
'No more names available for this service. (Increase digits for this service to fix)'
|
||||||
)
|
)
|
||||||
|
53
server/tests/core/util/test_factory.py
Normal file
53
server/tests/core/util/test_factory.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright (c) 2024 Virtual Cable S.L.U.
|
||||||
|
# All rights reserved.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
# are permitted provided that the following conditions are met:
|
||||||
|
#
|
||||||
|
# * Redistributions of source code must retain the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer.
|
||||||
|
# * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
# this list of conditions and the following disclaimer in the documentation
|
||||||
|
# and/or other materials provided with the distribution.
|
||||||
|
# * Neither the name of Virtual Cable S.L.U. nor the names of its contributors
|
||||||
|
# may be used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
"""
|
||||||
|
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||||
|
"""
|
||||||
|
import typing
|
||||||
|
import collections.abc
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
from ...utils.test import UDSTestCase
|
||||||
|
|
||||||
|
from uds.core.util import factory
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class FactoryObject:
|
||||||
|
def __init__(self, name: str, value: int):
|
||||||
|
self.name = name
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
class FactoryTest(UDSTestCase):
|
||||||
|
def test_factory(self) -> None:
|
||||||
|
|
||||||
|
f = factory.Factory[FactoryObject]()
|
||||||
|
|
||||||
|
pass
|
Loading…
Reference in New Issue
Block a user