mirror of
https://github.com/dkmstr/openuds.git
synced 2025-01-21 18:03:54 +03:00
Doney Physical Machines
This commit is contained in:
parent
eb86784c62
commit
7316953e75
@ -258,7 +258,7 @@ class ServersServers(DetailHandler):
|
||||
raise self.invalid_request_response('Invalid MAC address')
|
||||
# Create a new one, and add it to group
|
||||
server = models.Server.objects.create(
|
||||
register_username=self._user.name,
|
||||
register_username=self._user.pretty_name,
|
||||
register_ip=self._request.ip,
|
||||
ip=self._params['ip'],
|
||||
hostname=self._params['hostname'],
|
||||
@ -291,7 +291,7 @@ class ServersServers(DetailHandler):
|
||||
try:
|
||||
models.Server.objects.filter(uuid=process_uuid(item)).update(
|
||||
# Update register info also on update
|
||||
register_username=self._user.name,
|
||||
register_username=self._user.pretty_name,
|
||||
register_ip=self._request.ip,
|
||||
hostname=self._params['hostname'],
|
||||
ip=self._params['ip'],
|
||||
@ -379,7 +379,7 @@ class ServersServers(DetailHandler):
|
||||
try:
|
||||
if parent.servers.filter(Q(ip=ip) | Q(hostname=hostname)).count() == 0:
|
||||
server = models.Server.objects.create(
|
||||
register_username=self._user.name,
|
||||
register_username=self._user.pretty_name,
|
||||
register_ip=self._request.ip,
|
||||
ip=ip,
|
||||
hostname=hostname,
|
||||
|
@ -62,7 +62,6 @@ class IPMachineUserService(services.UserService, autoserializable.AutoSerializab
|
||||
|
||||
_ip = autoserializable.StringField(default='')
|
||||
_reason = autoserializable.StringField(default='')
|
||||
_state = autoserializable.StringField(default=types.states.TaskState.FINISHED)
|
||||
_name = autoserializable.StringField(default='')
|
||||
|
||||
# Utility overrides for type checking...
|
||||
@ -80,18 +79,17 @@ class IPMachineUserService(services.UserService, autoserializable.AutoSerializab
|
||||
def get_name(self) -> str:
|
||||
if not self._name:
|
||||
# Generate a name with the IP + simple counter
|
||||
self._name = f'{self.get_ip()}{self.service().get_counter_and_inc()}'
|
||||
self._name = f'{self.get_ip()}:{self.service().get_counter_and_inc()}'
|
||||
return self._name
|
||||
|
||||
def get_unique_id(self) -> str:
|
||||
return self._name
|
||||
return self.get_name()
|
||||
|
||||
def set_ready(self) -> types.states.TaskState:
|
||||
# If single machine, ip is IP~counter,
|
||||
# If multiple and has a ';' on IP, the values is IP;MAC
|
||||
self.service().wakeup()
|
||||
self._state = types.states.TaskState.FINISHED
|
||||
return self._state
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
def _deploy(self) -> types.states.TaskState:
|
||||
# If not to be managed by a token, autologin user
|
||||
@ -99,8 +97,7 @@ class IPMachineUserService(services.UserService, autoserializable.AutoSerializab
|
||||
if userService:
|
||||
userService.set_in_use(True)
|
||||
|
||||
self._state = types.states.TaskState.FINISHED
|
||||
return self._state
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
def deploy_for_user(self, user: 'models.User') -> types.states.TaskState:
|
||||
logger.debug("Starting deploy of %s for user %s", self._ip, user)
|
||||
@ -110,13 +107,14 @@ class IPMachineUserService(services.UserService, autoserializable.AutoSerializab
|
||||
return self._error('Cache deploy not supported')
|
||||
|
||||
def _error(self, reason: str) -> types.states.TaskState:
|
||||
self._state = types.states.TaskState.ERROR
|
||||
self._ip = ''
|
||||
self._reason = reason
|
||||
return self._state
|
||||
self._reason = reason or 'Unknown error'
|
||||
return types.states.TaskState.ERROR
|
||||
|
||||
def check_state(self) -> types.states.TaskState:
|
||||
return types.states.TaskState.from_str(self._state)
|
||||
if self._reason:
|
||||
return types.states.TaskState.ERROR
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
def error_reason(self) -> str:
|
||||
"""
|
||||
@ -126,8 +124,9 @@ class IPMachineUserService(services.UserService, autoserializable.AutoSerializab
|
||||
return self._reason
|
||||
|
||||
def destroy(self) -> types.states.TaskState:
|
||||
self._state = types.states.TaskState.FINISHED
|
||||
return self._state
|
||||
self._ip = ''
|
||||
self._reason = ''
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
def cancel(self) -> types.states.TaskState:
|
||||
return self.destroy()
|
||||
@ -141,8 +140,10 @@ class IPMachineUserService(services.UserService, autoserializable.AutoSerializab
|
||||
|
||||
# Fill own data from restored data
|
||||
self._ip = _auto_data._ip
|
||||
self._name = self.db_obj().name or '' # If has a name, use it, else, use the generated one
|
||||
self._reason = _auto_data._reason
|
||||
self._state = _auto_data._state
|
||||
if _auto_data._state == types.states.TaskState.ERROR:
|
||||
self._reason = self._reason or 'Unknown error'
|
||||
|
||||
# Flag for upgrade
|
||||
self.mark_for_upgrade(True)
|
||||
|
@ -30,6 +30,7 @@
|
||||
"""
|
||||
@author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
import hashlib
|
||||
import logging
|
||||
import typing
|
||||
|
||||
@ -69,6 +70,12 @@ class IPMachinesUserService(services.UserService, autoserializable.AutoSerializa
|
||||
def service(self) -> 'IPMachinesService':
|
||||
return typing.cast('IPMachinesService', super().service())
|
||||
|
||||
def _set_in_use(self) -> None:
|
||||
if not self.service().get_token():
|
||||
userservice = self.db_obj()
|
||||
if userservice:
|
||||
userservice.set_in_use(True)
|
||||
|
||||
def set_ip(self, ip: str) -> None:
|
||||
logger.debug('Setting IP to %s (ignored)', ip)
|
||||
|
||||
@ -76,14 +83,11 @@ class IPMachinesUserService(services.UserService, autoserializable.AutoSerializa
|
||||
return self._ip
|
||||
|
||||
def get_name(self) -> str:
|
||||
# If single machine, ip is IP~counter,
|
||||
# If multiple and has a ';' on IP, the values is IP;MAC
|
||||
return self.get_ip()
|
||||
|
||||
def get_unique_id(self) -> str:
|
||||
if not self._mac:
|
||||
return self._ip
|
||||
return self._mac
|
||||
# Generate a 16 chars string mixing up all _vmid chars
|
||||
return hashlib.shake_128(self._vmid.encode('utf8')).hexdigest(8)
|
||||
|
||||
def set_ready(self) -> types.states.TaskState:
|
||||
self.service().wakeup(self._ip, self._mac)
|
||||
@ -92,13 +96,10 @@ class IPMachinesUserService(services.UserService, autoserializable.AutoSerializa
|
||||
def deploy_for_user(self, user: 'models.User') -> types.states.TaskState:
|
||||
logger.debug("Starting deploy of %s for user %s", self._ip, user)
|
||||
self._vmid = self.service().get_unassigned()
|
||||
|
||||
self._ip, self._mac = self.service().get_host_mac(self._vmid)
|
||||
|
||||
# If not to be managed by a token, autologin user
|
||||
if not self.service().get_token():
|
||||
userservice = self.db_obj()
|
||||
if userservice:
|
||||
userservice.set_in_use(True)
|
||||
self._set_in_use()
|
||||
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
@ -111,11 +112,8 @@ class IPMachinesUserService(services.UserService, autoserializable.AutoSerializa
|
||||
# Update ip & mac
|
||||
self._ip, self._mac = self.service().get_host_mac(vmid)
|
||||
|
||||
if not self.service().get_token():
|
||||
dbService = self.db_obj()
|
||||
if dbService:
|
||||
dbService.set_in_use(True)
|
||||
dbService.save()
|
||||
self._set_in_use()
|
||||
|
||||
return types.states.TaskState.FINISHED
|
||||
|
||||
def _error(self, reason: str) -> types.states.TaskState:
|
||||
@ -150,4 +148,4 @@ class IPMachinesUserService(services.UserService, autoserializable.AutoSerializa
|
||||
def cancel(self) -> types.states.TaskState:
|
||||
return self.destroy()
|
||||
|
||||
# Data is migrated on migration 0046, so no unmarshall is needed
|
||||
# Data is migrated on migration 0046, so no unmarshall is needed
|
||||
|
@ -176,6 +176,7 @@ class IPMachinesService(services.Service):
|
||||
random.shuffle(list_of_servers) # Reorder the list randomly if required
|
||||
for server in list_of_servers:
|
||||
if server.locked_until is None or server.locked_until < sql_now():
|
||||
server.lock(self.get_max_lock_time())
|
||||
return server.uuid
|
||||
raise exceptions.services.InsufficientResourcesException()
|
||||
|
||||
|
@ -34,11 +34,19 @@ import datetime
|
||||
import typing
|
||||
import uuid
|
||||
|
||||
from unittest import mock
|
||||
|
||||
from uds import models
|
||||
from uds.core import environment, types
|
||||
from uds.core.ui.user_interface import gui
|
||||
|
||||
from uds.services.PhysicalMachines import provider, service_single, service_multi
|
||||
from uds.services.PhysicalMachines import (
|
||||
provider,
|
||||
service_single,
|
||||
service_multi,
|
||||
deployment as deployment_single,
|
||||
deployment_multi,
|
||||
)
|
||||
|
||||
SERVER_GROUP_IPS_MACS: typing.Final[list[tuple[str, str]]] = [
|
||||
(f'127.0.1.{x}', f'{x:02x}:22:{x*2:02x}:44:{x*4:02x}:66') for x in range(1, 32)
|
||||
@ -178,3 +186,43 @@ def create_service_multi(
|
||||
)
|
||||
|
||||
return service_instance
|
||||
|
||||
|
||||
def create_userservice_single(
|
||||
service: typing.Optional[service_single.IPSingleMachineService] = None, **kwargs: typing.Any
|
||||
) -> deployment_single.IPMachineUserService:
|
||||
"""
|
||||
Create a user service
|
||||
"""
|
||||
uuid_ = str(uuid.uuid4())
|
||||
|
||||
userservice_instance = deployment_single.IPMachineUserService(
|
||||
environment=environment.Environment.private_environment(uuid_),
|
||||
service=service or create_service_single(),
|
||||
publication=None,
|
||||
uuid=uuid_,
|
||||
)
|
||||
|
||||
userservice_instance.db_obj = mock.MagicMock()
|
||||
|
||||
return userservice_instance
|
||||
|
||||
|
||||
def create_userservice_multi(
|
||||
service: typing.Optional[service_single.IPSingleMachineService] = None, **kwargs: typing.Any
|
||||
) -> deployment_multi.IPMachinesUserService:
|
||||
"""
|
||||
Create a user service
|
||||
"""
|
||||
uuid_ = str(uuid.uuid4())
|
||||
|
||||
userservice_instance = deployment_multi.IPMachinesUserService(
|
||||
environment=environment.Environment.private_environment(uuid_),
|
||||
service=service or create_service_multi(),
|
||||
publication=None,
|
||||
uuid=uuid_,
|
||||
)
|
||||
|
||||
userservice_instance.db_obj = mock.MagicMock()
|
||||
|
||||
return userservice_instance
|
||||
|
@ -9,6 +9,7 @@
|
||||
Author: Adolfo Gómez, dkmaster at dkmon dot com
|
||||
"""
|
||||
# We use commit/rollback
|
||||
from unittest import mock
|
||||
|
||||
from tests.utils.test import UDSTestCase
|
||||
from uds.core.util import autoserializable
|
||||
@ -27,12 +28,12 @@ class IPMachineUserServiceSerializationTest(UDSTestCase):
|
||||
|
||||
def _check_fields(instance: deployment.IPMachineUserService) -> None:
|
||||
self.assertEqual(instance._ip, '1.1.1.1')
|
||||
self.assertEqual(instance._state, 'state')
|
||||
self.assertEqual(instance._reason, 'reason')
|
||||
|
||||
data = obj.marshal()
|
||||
|
||||
instance = deployment.IPMachineUserService(environment=Environment.testing_environment(), service=None) # type: ignore # service is not used
|
||||
instance.db_obj = mock.MagicMock()
|
||||
instance.unmarshal(data)
|
||||
|
||||
marshaled_data = instance.marshal()
|
||||
|
@ -178,8 +178,9 @@ class TestServiceMulti(UDSTransactionTestCase):
|
||||
unassigned_uuid = service.get_unassigned()
|
||||
# Must be the first server
|
||||
self.assertEqual(unassigned_uuid, server.uuid, f'Error on element {num}') # type: ignore # if first is None,raises error
|
||||
# Lock it, so it's not returned again
|
||||
service.lock_server(unassigned_uuid)
|
||||
# Ensure it's locked
|
||||
server.refresh_from_db()
|
||||
self.assertIsNotNone(server.locked_until)
|
||||
|
||||
# Now, randomized, we must no receive same servers
|
||||
service.randomize_host.value = True
|
||||
@ -191,18 +192,21 @@ class TestServiceMulti(UDSTransactionTestCase):
|
||||
count = 0
|
||||
for count in range(128):
|
||||
unassigned_uuid = service.get_unassigned()
|
||||
self.assertNotEqual(unassigned_uuid, server_list[0].uuid)
|
||||
# unlock the server, for next iteration or test
|
||||
service.unlock_server(unassigned_uuid)
|
||||
if unassigned_uuid != server_list[0].uuid:
|
||||
break
|
||||
|
||||
if count == 127:
|
||||
self.fail('Randomized server selection failed')
|
||||
|
||||
# Unres
|
||||
|
||||
# Now ensure we can lock all servers
|
||||
for num in range(len(server_list)):
|
||||
unassigned_uuid = service.get_unassigned()
|
||||
self.assertIsNotNone(unassigned_uuid)
|
||||
service.lock_server(unassigned_uuid)
|
||||
self.assertTrue(models.Server.objects.get(uuid=unassigned_uuid).locked_until is not None)
|
||||
|
||||
def test_enumerate_assignables(self) -> None:
|
||||
service = fixtures.create_service_multi()
|
||||
@ -236,4 +240,4 @@ class TestServiceMulti(UDSTransactionTestCase):
|
||||
userservice_mock.assign.assert_called_once_with(server.uuid)
|
||||
# Ensure is locked
|
||||
server.refresh_from_db()
|
||||
self.assertIsNotNone(server.locked_until)
|
||||
self.assertIsNotNone(server.locked_until)
|
||||
|
@ -0,0 +1,132 @@
|
||||
# -*- 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
|
||||
from unittest import mock
|
||||
|
||||
from uds import models
|
||||
from uds.core import types
|
||||
|
||||
from . import fixtures
|
||||
|
||||
from ...utils.test import UDSTransactionTestCase
|
||||
|
||||
# from ...utils.generators import limited_iterator
|
||||
|
||||
|
||||
# We use transactions on some related methods (storage access, etc...)
|
||||
class TestUserServiceMulti(UDSTransactionTestCase):
|
||||
def test_userservice(self) -> None:
|
||||
"""
|
||||
Test the user service
|
||||
"""
|
||||
userservice = fixtures.create_userservice_multi()
|
||||
|
||||
# Does not supports cache
|
||||
self.assertEqual(
|
||||
userservice.deploy_for_cache(level=types.services.CacheLevel.L1), types.states.TaskState.ERROR
|
||||
)
|
||||
# Ensure check also returns error state
|
||||
self.assertEqual(userservice.check_state(), types.states.TaskState.ERROR)
|
||||
|
||||
# Ensure has no token for this test
|
||||
self.assertEqual(userservice.deploy_for_user(mock.MagicMock()), types.states.TaskState.FINISHED)
|
||||
|
||||
server = models.Server.objects.get(uuid=userservice._vmid)
|
||||
# Ensure is locked
|
||||
self.assertIsNotNone(server.locked_until)
|
||||
|
||||
# Destroy it
|
||||
self.assertEqual(userservice.destroy(), types.states.TaskState.FINISHED)
|
||||
# Ensure is not locked
|
||||
server.refresh_from_db()
|
||||
self.assertIsNone(server.locked_until)
|
||||
|
||||
def test_userservice_set_ready(self) -> None:
|
||||
"""
|
||||
Test the user service
|
||||
"""
|
||||
userservice = fixtures.create_userservice_multi()
|
||||
|
||||
# Ensure has no token for this test
|
||||
self.assertEqual(userservice.deploy_for_user(mock.MagicMock()), types.states.TaskState.FINISHED)
|
||||
|
||||
# Ensure is locked
|
||||
server = models.Server.objects.get(uuid=userservice._vmid)
|
||||
self.assertIsNotNone(server.locked_until)
|
||||
|
||||
# Set ready
|
||||
# patch service wakeup
|
||||
with mock.patch.object(userservice.service(), 'wakeup') as wakeup:
|
||||
self.assertEqual(userservice.set_ready(), types.states.TaskState.FINISHED)
|
||||
wakeup.assert_called_once_with(userservice._ip, userservice._mac)
|
||||
|
||||
def test_userservice_assign(self) -> None:
|
||||
"""
|
||||
Test the user service
|
||||
"""
|
||||
userservice = fixtures.create_userservice_multi()
|
||||
server = models.Server.objects.first()
|
||||
if not server:
|
||||
self.fail('No server found')
|
||||
|
||||
# Assign
|
||||
userservice.assign(server.uuid)
|
||||
self.assertEqual(userservice._vmid, server.uuid)
|
||||
|
||||
# Ensure ip and mac are same as server
|
||||
self.assertEqual(userservice._ip, server.ip)
|
||||
self.assertEqual(userservice._mac, server.mac)
|
||||
|
||||
def test_userservice_without_token(self) -> None:
|
||||
"""
|
||||
Test the user service
|
||||
"""
|
||||
userservice = fixtures.create_userservice_multi()
|
||||
db_obj_mock = typing.cast(mock.MagicMock, userservice.db_obj)
|
||||
|
||||
# Ensure has no token for this test
|
||||
userservice.service().token.value = ''
|
||||
self.assertEqual(userservice.deploy_for_user(mock.MagicMock()), types.states.TaskState.FINISHED)
|
||||
self.assertTrue(mock.call().set_in_use(True) in db_obj_mock.mock_calls)
|
||||
|
||||
def test_userservice_with_token(self) -> None:
|
||||
"""
|
||||
Test the user service
|
||||
"""
|
||||
userservice = fixtures.create_userservice_multi()
|
||||
db_obj_mock = typing.cast(mock.MagicMock, userservice.db_obj)
|
||||
|
||||
# Ensure has no token for this test
|
||||
userservice.service().token.value = 'token_value'
|
||||
self.assertEqual(userservice.deploy_for_user(mock.MagicMock()), types.states.TaskState.FINISHED)
|
||||
self.assertFalse(mock.call().set_in_use(True) in db_obj_mock.mock_calls)
|
@ -0,0 +1,72 @@
|
||||
# -*- 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
|
||||
"""
|
||||
from unittest import mock
|
||||
|
||||
from uds.core import types
|
||||
|
||||
from . import fixtures
|
||||
|
||||
from ...utils.test import UDSTransactionTestCase
|
||||
|
||||
# from ...utils.generators import limited_iterator
|
||||
|
||||
|
||||
# We use transactions on some related methods (storage access, etc...)
|
||||
class TestUserServiceSingle(UDSTransactionTestCase):
|
||||
def test_userservice(self) -> None:
|
||||
"""
|
||||
Test the user service
|
||||
"""
|
||||
userservice = fixtures.create_userservice_single()
|
||||
service = userservice.service()
|
||||
|
||||
self.assertEqual(userservice.deploy_for_user(mock.MagicMock()), types.states.TaskState.FINISHED)
|
||||
self.assertEqual(userservice.check_state(), types.states.TaskState.FINISHED)
|
||||
|
||||
self.assertEqual(userservice.get_ip(), service.host.value)
|
||||
self.assertEqual(userservice.get_name(), f'{userservice.get_ip()}:0')
|
||||
self.assertEqual(userservice.get_unique_id(), f'{userservice.get_ip()}:0')
|
||||
|
||||
# patch service wakeup to ensure it's called
|
||||
with mock.patch.object(service, 'wakeup') as wakeup:
|
||||
userservice.set_ready()
|
||||
wakeup.assert_called_with()
|
||||
|
||||
self.assertEqual(userservice.destroy(), types.states.TaskState.FINISHED)
|
||||
self.assertEqual(userservice.cancel(), types.states.TaskState.FINISHED)
|
||||
|
||||
# deploy for cache should return error
|
||||
state = userservice.deploy_for_cache(level=types.services.CacheLevel.L1)
|
||||
self.assertEqual(state, types.states.TaskState.ERROR)
|
||||
self.assertEqual(userservice.check_state(), types.states.TaskState.ERROR)
|
||||
self.assertEqual(userservice.error_reason(), userservice._reason)
|
Loading…
x
Reference in New Issue
Block a user