blob: 8e0396a0a3bc6ca44cfb959534a917c84fd19169 [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
""" BVT tests for extension custom actions lifecycle functionalities
"""
# Import Local Modules
from marvin.cloudstackTestCase import cloudstackTestCase
from marvin.cloudstackAPI import listManagementServers
from marvin.cloudstackException import CloudstackAPIException
from marvin.lib.base import (Extension,
ExtensionCustomAction)
from marvin.lib.common import (get_zone)
from marvin.lib.utils import (random_gen)
from marvin.sshClient import SshClient
from nose.plugins.attrib import attr
# Import System modules
import logging
import random
import string
import time
_multiprocess_shared_ = True
class TestExtensions(cloudstackTestCase):
@classmethod
def setUpClass(cls):
testClient = super(TestExtensions, cls).getClsTestClient()
cls.apiclient = testClient.getApiClient()
cls.services = testClient.getParsedTestDataConfig()
# Get Zone
cls.zone = get_zone(cls.apiclient, testClient.getZoneForTests())
cls.mgtSvrDetails = cls.config.__dict__["mgtSvr"][0].__dict__
cls._cleanup = []
cls.logger = logging.getLogger('TestExtensions')
cls.logger.setLevel(logging.DEBUG)
cls.resource_name_suffix = random_gen()
cls.extension = Extension.create(
cls.apiclient,
name=f"ext-{cls.resource_name_suffix}",
type='Orchestrator'
)
cls._cleanup.append(cls.extension)
@classmethod
def tearDownClass(cls):
super(TestExtensions, cls).tearDownClass()
def setUp(self):
self.cleanup = []
def tearDown(self):
super(TestExtensions, self).tearDown()
def popItemFromCleanup(self, item_id):
for idx, x in enumerate(self.cleanup):
if x.id == item_id:
self.cleanup.pop(idx)
break
@attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
def test_01_extension_create_custom_action(self):
name = random_gen()
details = [{}]
details[0]['abc'] = 'xyz'
parameters = [{}]
parameter0 = {
'name': 'Name',
'type': 'STRING',
'validationformat': 'NONE',
'required': True
}
parameters[0] = parameter0
self.custom_action = ExtensionCustomAction.create(
self.apiclient,
extensionid=self.extension.id,
name=name,
details=details,
parameters=parameters
)
self.cleanup.append(self.custom_action)
self.assertEqual(
name,
self.custom_action.name,
"Check custom action name failed"
)
self.assertEqual(
self.extension.id,
self.custom_action.extensionid,
"Check custom action extension ID failed"
)
self.assertEqual(
'VirtualMachine',
self.custom_action.resourcetype,
"Check custom action resorucetype failed"
)
self.assertFalse(
self.custom_action.enabled,
"Check custom action enabled failed"
)
self.assertTrue(
self.custom_action.allowedroletypes is not None and len(self.custom_action.allowedroletypes) == 1 and self.custom_action.allowedroletypes[0] == 'Admin',
"Check custom action allowedroletypes failed"
)
self.assertEqual(
3,
self.custom_action.timeout,
"Check custom action timeout failed"
)
action_details = self.custom_action.details.__dict__
for k, v in details[0].items():
self.assertIn(k, action_details, f"Key '{k}' should be present in details")
self.assertEqual(v, action_details[k], f"Value for key '{k}' should be '{v}'")
self.assertTrue(
self.custom_action.parameters is not None and len(self.custom_action.parameters) == 1,
"Check custom action parameters count failed"
)
parameter_result = self.custom_action.parameters[0].__dict__
for k, v in parameter0.items():
self.assertIn(k, parameter_result, f"Key '{k}' should be present in the parameter")
self.assertEqual(v, parameter_result[k], f"Parameter property for key '{k}' should be '{v}'")
actions = self.extension.list_custom_actions(self.apiclient)
self.assertTrue(
actions is not None and len(actions) == 1 and actions[0].id == self.custom_action.id,
"Check extension custom actions failed"
)
@attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
def test_02_extension_create_custom_action_name_fail(self):
name = random_gen()
self.custom_action = ExtensionCustomAction.create(
self.apiclient,
extensionid=self.extension.id,
name=name
)
try:
self.custom_action1 = ExtensionCustomAction.create(
self.apiclient,
extensionid=self.extension.id,
name=name
)
self.cleanup.append(self.custom_action1)
self.fail(f"Same name: {name} custom action created twice")
except CloudstackAPIException: pass
@attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
def test_03_extension_create_custom_action_resourcetype_fail(self):
try:
self.custom_action = ExtensionCustomAction.create(
self.apiclient,
extensionid=self.extension.id,
name=random_gen(),
resourcetype='Host'
)
self.cleanup.append(self.custom_action)
self.fail(f"Unknown resourcetype: {type} custom action created")
except CloudstackAPIException: pass
@attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
def test_04_extension_update_custom_action(self):
details = [{}]
details[0]['abc'] = 'xyz'
parameters = [{}]
parameter0 = {
'name': 'Name',
'type': 'STRING',
'validationformat': 'NONE',
'required': True
}
parameters[0] = parameter0
self.custom_action = ExtensionCustomAction.create(
self.apiclient,
extensionid=self.extension.id,
name=random_gen(),
details=details,
parameters=parameters
)
self.cleanup.append(self.custom_action)
details[0]['bca'] = 'yzx'
description = 'Updated test description'
parameter1 = {
'name': 'COUNT',
'type': 'NUMBER',
'validationformat': 'NONE',
'required': False,
'valueoptions': '10,100,1000'
}
parameters.append(parameter1)
updated_action = self.custom_action.update(
self.apiclient,
description=description,
enabled=True,
details=details,
parameters=parameters)['extensioncustomaction']
self.assertTrue(
updated_action.enabled,
"Check custom action enabled failed"
)
self.assertEqual(
description,
updated_action.description,
"Check custom action description failed"
)
action_details = updated_action.details.__dict__
for k, v in details[0].items():
self.assertIn(k, action_details, f"Key '{k}' should be present in details")
self.assertEqual(v, action_details[k], f"Value for key '{k}' should be '{v}'")
self.assertTrue(
updated_action.parameters is not None and len(updated_action.parameters) == 2,
"Check custom action parameters count failed"
)
for idx, param in enumerate(parameters):
parameter_result = updated_action.parameters[idx].__dict__
for k, v in param.items():
self.assertIn(k, parameter_result, f"Key '{k}' should be present in the parameter")
actual = ','.join(str(x) for x in parameter_result[k]) if k == 'valueoptions' else parameter_result[k]
self.assertEqual(v, actual, f"Parameter property for key '{k}' should be '{v}'")
@attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
def test_05_extension_run_custom_action_invalid_resource_type_fail(self):
name = random_gen()
self.custom_action = ExtensionCustomAction.create(
self.apiclient,
extensionid=self.extension.id,
name=name,
enabled=True
)
self.cleanup.append(self.custom_action)
try:
self.custom_action.run(
self.apiclient,
resourcetype='Host',
resourceid='abcd'
)
self.fail(f"Invalid resource custom action: {name} ran successfully")
except Exception as e:
msg = str(e)
if msg.startswith("Job failed") == False or "Internal error running action" not in msg == False:
self.fail(f"Unknown exception occurred: {e}")
pass
@attr(tags=["devcloud", "advanced", "advancedns", "smoke", "basic", "sg"], required_hardware="false")
def test_06_extension_run_custom_action_fail(self):
name = random_gen()
self.custom_action = ExtensionCustomAction.create(
self.apiclient,
extensionid=self.extension.id,
name=name,
enabled=True
)
self.cleanup.append(self.custom_action)
try:
self.custom_action.run(
self.apiclient,
resourceid='abcd'
)
self.fail(f"Invalid resource custom action: {name} ran successfully")
except Exception as e:
msg = str(e)
if msg.startswith("Job failed") == False or "Invalid action" not in msg == False:
self.fail(f"Unknown exception occurred: {e}")
pass