Add unit tests for _has_nvidia_gpu_hardware()
Also add .gitreview and .zuul.yaml files Change-Id: I7f839a0ea7c3a3f72a4d6be5dfd47f9ddd0c0bef
This commit is contained in:
parent
a2f6ce020b
commit
4f49eab3fd
4
.gitreview
Normal file
4
.gitreview
Normal file
@ -0,0 +1,4 @@
|
||||
[gerrit]
|
||||
host=review.opendev.org
|
||||
port=29418
|
||||
project=openstack/charm-nova-compute-nvidia-vgpu
|
4
.zuul.yaml
Normal file
4
.zuul.yaml
Normal file
@ -0,0 +1,4 @@
|
||||
- project:
|
||||
templates:
|
||||
- openstack-python3-charm-jobs
|
||||
- openstack-cover-jobs
|
@ -1,6 +1,6 @@
|
||||
# Overview
|
||||
|
||||
This subordinate charm provides the NVidia vGPU support to the
|
||||
This subordinate charm provides the Nvidia vGPU support to the
|
||||
[OpenStack Nova Compute service][charm-nova-compute].
|
||||
|
||||
# Bugs
|
||||
|
@ -1,3 +1,5 @@
|
||||
# NOTE(lourot): versions newer than 1.0.0 fail as described in
|
||||
# https://github.com/canonical/charmcraft/pull/487#issuecomment-894529408
|
||||
git+https://github.com/canonical/charmcraft.git@1.0.0#egg=charmcraft
|
||||
|
||||
cffi==1.14.6; python_version < '3.6' # cffi 1.15.0 drops support for py35.
|
||||
|
@ -1,10 +1,10 @@
|
||||
name: nova-compute-nvidia-vgpu
|
||||
summary: NVidia vGPU support for OpenStack Nova Compute
|
||||
summary: Nvidia vGPU support for OpenStack Nova Compute
|
||||
maintainer: OpenStack Charmers <openstack-charmers@lists.ubuntu.com>
|
||||
description: |
|
||||
OpenStack Compute, codenamed Nova, is a cloud computing fabric controller.
|
||||
.
|
||||
This charm provides NVidia vGPU support for Nova.
|
||||
This charm provides Nvidia vGPU support for Nova.
|
||||
tags:
|
||||
- openstack
|
||||
series:
|
||||
|
83
osci.yaml
83
osci.yaml
@ -1,16 +1,89 @@
|
||||
- project:
|
||||
templates:
|
||||
- charm-yoga-unit-jobs
|
||||
- charm-yoga-functional-jobs
|
||||
- charm-xena-functional-jobs
|
||||
- charm-wallaby-functional-jobs
|
||||
- charm-victoria-functional-jobs
|
||||
check:
|
||||
jobs:
|
||||
# NOTE(lourot): adding `focal-ussuri` manually to the list here instead
|
||||
# of using `charm-ussuri-functional-jobs` as we don't support Bionic.
|
||||
- focal-ussuri
|
||||
- jammy-yoga-nvidia-vgpu:
|
||||
voting: false
|
||||
- impish-xena-nvidia-vgpu
|
||||
- hirsute-wallaby-nvidia-vgpu
|
||||
- focal-yoga-nvidia-vgpu
|
||||
- focal-xena-nvidia-vgpu
|
||||
- focal-wallaby-nvidia-vgpu
|
||||
- focal-victoria-nvidia-vgpu
|
||||
- focal-ussuri-nvidia-vgpu
|
||||
vars:
|
||||
needs_charm_build: true
|
||||
charm_build_name: nova-compute-nvidia-vgpu
|
||||
build_type: charmcraft
|
||||
|
||||
- job:
|
||||
name: jammy-yoga-nvidia-vgpu
|
||||
description: Run a functional test against jammy-yoga
|
||||
parent: func-target
|
||||
dependencies: &smoke-jobs
|
||||
- focal-ussuri-nvidia-vgpu
|
||||
vars:
|
||||
tox_extra_args: jammy-yoga
|
||||
- job:
|
||||
name: impish-xena-nvidia-vgpu
|
||||
description: Run a functional test against impish-xena
|
||||
parent: func-target
|
||||
dependencies: *smoke-jobs
|
||||
vars:
|
||||
tox_extra_args: impish-xena
|
||||
- job:
|
||||
name: hirsute-wallaby-nvidia-vgpu
|
||||
description: Run a functional test against hirsute-wallaby
|
||||
parent: func-target
|
||||
dependencies: *smoke-jobs
|
||||
vars:
|
||||
tox_extra_args: hirsute-wallaby
|
||||
- job:
|
||||
name: focal-yoga-nvidia-vgpu
|
||||
description: Run a functional test against focal-yoga
|
||||
parent: func-target
|
||||
dependencies: *smoke-jobs
|
||||
vars:
|
||||
tox_extra_args: focal-yoga
|
||||
- job:
|
||||
name: focal-xena-nvidia-vgpu
|
||||
description: Run a functional test against focal-xena
|
||||
parent: func-target
|
||||
dependencies: *smoke-jobs
|
||||
vars:
|
||||
tox_extra_args: focal-xena
|
||||
- job:
|
||||
name: focal-wallaby-nvidia-vgpu
|
||||
description: Run a functional test against focal-wallaby
|
||||
parent: func-target
|
||||
dependencies: *smoke-jobs
|
||||
vars:
|
||||
tox_extra_args: focal-wallaby
|
||||
- job:
|
||||
name: focal-victoria-nvidia-vgpu
|
||||
description: Run a functional test against focal-victoria
|
||||
parent: func-target
|
||||
dependencies: *smoke-jobs
|
||||
vars:
|
||||
tox_extra_args: focal-victoria
|
||||
- job:
|
||||
name: focal-ussuri-nvidia-vgpu
|
||||
description: Run a functional test against focal-ussuri
|
||||
parent: func-target
|
||||
dependencies:
|
||||
# The soft dependencies mean that if they are not configured to run
|
||||
# they will be ignored. See
|
||||
# https://github.com/openstack-charmers/zosci-config
|
||||
- charm-build
|
||||
- osci-lint
|
||||
- name: tox-py36
|
||||
soft: true
|
||||
- name: tox-py38
|
||||
soft: true
|
||||
- name: tox-py39
|
||||
soft: true
|
||||
vars:
|
||||
tox_extra_args: focal-ussuri
|
||||
|
14
src/charm.py
14
src/charm.py
@ -173,20 +173,28 @@ class NovaComputeNvidiaVgpuCharm(ops_openstack.core.OSBaseCharm):
|
||||
return [package['version'] for package in
|
||||
apt_cache().dpkg_list(['nvidia-vgpu-ubuntu-*']).values()]
|
||||
|
||||
@staticmethod
|
||||
@classmethod
|
||||
@cached
|
||||
def _has_nvidia_gpu_hardware():
|
||||
def _has_nvidia_gpu_hardware(cls):
|
||||
"""Search for NVIDIA GPU hardware.
|
||||
|
||||
:returns: True if some NVIDIA GPU hardware is found on the current
|
||||
unit.
|
||||
:rtype: bool
|
||||
"""
|
||||
return cls._has_nvidia_gpu_hardware_notcached()
|
||||
|
||||
@staticmethod
|
||||
def _has_nvidia_gpu_hardware_notcached():
|
||||
nvidia_gpu_hardware_found = False
|
||||
for device in SimpleParser().run():
|
||||
device_class = device.cls.name
|
||||
device_vendor = device.vendor.name
|
||||
device_subsystem_vendor = device.subsystem_vendor.name
|
||||
try:
|
||||
device_subsystem_vendor = device.subsystem_vendor.name
|
||||
except AttributeError:
|
||||
device_subsystem_vendor = ''
|
||||
|
||||
if '3D' in device_class and ('NVIDIA' in device_vendor or
|
||||
'NVIDIA' in device_subsystem_vendor):
|
||||
logging.debug('NVIDIA GPU found: {}'.format(device))
|
||||
|
@ -4,7 +4,7 @@
|
||||
charm-tools>=2.4.4
|
||||
coverage>=3.6
|
||||
mock>=1.2
|
||||
flake8>=4.0.1
|
||||
flake8>=4.0.1; python_version >= '3.6'
|
||||
stestr>=2.2.0
|
||||
requests>=2.18.4
|
||||
psutil
|
||||
@ -14,3 +14,4 @@ git+https://github.com/openstack-charmers/zaza.git#egg=zaza
|
||||
git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack
|
||||
pytz # workaround for 14.04 pip/tox
|
||||
pyudev # for ceph-* charm unit tests (not mocked?)
|
||||
cffi==1.14.6; python_version < '3.6' # cffi 1.15.0 drops support for py35.
|
||||
|
@ -1,3 +1,5 @@
|
||||
local_overlay_enabled: False
|
||||
|
||||
variables:
|
||||
openstack-origin: &openstack-origin distro
|
||||
|
||||
@ -165,7 +167,7 @@ applications:
|
||||
- '10'
|
||||
|
||||
nova-compute-nvidia-vgpu:
|
||||
charm: ../../../nova-compute-nvidia-vgpu
|
||||
charm: ../../nova-compute-nvidia-vgpu.charm
|
||||
|
||||
relations:
|
||||
- - 'ceph-osd:mon'
|
||||
|
@ -1,3 +1,5 @@
|
||||
local_overlay_enabled: False
|
||||
|
||||
variables:
|
||||
openstack-origin: &openstack-origin cloud:focal-victoria
|
||||
|
||||
@ -165,7 +167,7 @@ applications:
|
||||
- '10'
|
||||
|
||||
nova-compute-nvidia-vgpu:
|
||||
charm: ../../../nova-compute-nvidia-vgpu
|
||||
charm: ../../nova-compute-nvidia-vgpu.charm
|
||||
|
||||
relations:
|
||||
- - 'ceph-osd:mon'
|
||||
|
@ -1,3 +1,5 @@
|
||||
local_overlay_enabled: False
|
||||
|
||||
variables:
|
||||
openstack-origin: &openstack-origin cloud:focal-wallaby
|
||||
|
||||
@ -165,7 +167,7 @@ applications:
|
||||
- '10'
|
||||
|
||||
nova-compute-nvidia-vgpu:
|
||||
charm: ../../../nova-compute-nvidia-vgpu
|
||||
charm: ../../nova-compute-nvidia-vgpu.charm
|
||||
|
||||
relations:
|
||||
- - 'ceph-osd:mon'
|
||||
|
@ -1,3 +1,5 @@
|
||||
local_overlay_enabled: False
|
||||
|
||||
variables:
|
||||
openstack-origin: &openstack-origin cloud:focal-xena
|
||||
|
||||
@ -165,7 +167,7 @@ applications:
|
||||
- '10'
|
||||
|
||||
nova-compute-nvidia-vgpu:
|
||||
charm: ../../../nova-compute-nvidia-vgpu
|
||||
charm: ../../nova-compute-nvidia-vgpu.charm
|
||||
|
||||
relations:
|
||||
- - 'ceph-osd:mon'
|
||||
|
@ -1,3 +1,5 @@
|
||||
local_overlay_enabled: False
|
||||
|
||||
variables:
|
||||
openstack-origin: &openstack-origin cloud:focal-yoga
|
||||
|
||||
@ -165,7 +167,7 @@ applications:
|
||||
- '10'
|
||||
|
||||
nova-compute-nvidia-vgpu:
|
||||
charm: ../../../nova-compute-nvidia-vgpu
|
||||
charm: ../../nova-compute-nvidia-vgpu.charm
|
||||
|
||||
relations:
|
||||
- - 'ceph-osd:mon'
|
||||
|
@ -1,3 +1,5 @@
|
||||
local_overlay_enabled: False
|
||||
|
||||
variables:
|
||||
openstack-origin: &openstack-origin distro
|
||||
|
||||
@ -165,7 +167,7 @@ applications:
|
||||
- '10'
|
||||
|
||||
nova-compute-nvidia-vgpu:
|
||||
charm: ../../../nova-compute-nvidia-vgpu
|
||||
charm: ../../nova-compute-nvidia-vgpu.charm
|
||||
|
||||
relations:
|
||||
- - 'ceph-osd:mon'
|
||||
|
@ -1,3 +1,5 @@
|
||||
local_overlay_enabled: False
|
||||
|
||||
variables:
|
||||
openstack-origin: &openstack-origin distro
|
||||
|
||||
@ -165,7 +167,7 @@ applications:
|
||||
- '10'
|
||||
|
||||
nova-compute-nvidia-vgpu:
|
||||
charm: ../../../nova-compute-nvidia-vgpu
|
||||
charm: ../../nova-compute-nvidia-vgpu.charm
|
||||
|
||||
relations:
|
||||
- - 'ceph-osd:mon'
|
||||
|
@ -1,3 +1,5 @@
|
||||
local_overlay_enabled: False
|
||||
|
||||
variables:
|
||||
openstack-origin: &openstack-origin distro
|
||||
|
||||
@ -165,7 +167,7 @@ applications:
|
||||
- '10'
|
||||
|
||||
nova-compute-nvidia-vgpu:
|
||||
charm: ../../../nova-compute-nvidia-vgpu
|
||||
charm: ../../nova-compute-nvidia-vgpu.charm
|
||||
|
||||
relations:
|
||||
- - 'ceph-osd:mon'
|
||||
|
@ -7,12 +7,12 @@ gate_bundles:
|
||||
- focal-ussuri
|
||||
- focal-victoria
|
||||
- focal-wallaby
|
||||
- focal-xena
|
||||
- focal-yoga
|
||||
- hirsute-wallaby
|
||||
- impish-xena
|
||||
|
||||
dev_bundles:
|
||||
- focal-xena
|
||||
- impish-xena
|
||||
- jammy-yoga
|
||||
|
||||
configure:
|
||||
|
5
tox.ini
5
tox.ini
@ -54,6 +54,11 @@ basepython = python3.8
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
|
||||
[testenv:py39]
|
||||
basepython = python3.9
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
|
||||
[testenv:py3]
|
||||
basepython = python3
|
||||
deps = -r{toxinidir}/requirements.txt
|
||||
|
@ -13,23 +13,95 @@
|
||||
# limitations under the License.
|
||||
|
||||
import unittest
|
||||
from src.charm import NovaComputeNvidiaVgpuCharm
|
||||
|
||||
from mock import MagicMock, patch
|
||||
|
||||
from ops.model import ActiveStatus
|
||||
from ops.testing import Harness
|
||||
|
||||
import src.charm
|
||||
|
||||
class TestNovaComputeNvidiaVgpuCharm(unittest.TestCase):
|
||||
|
||||
class CharmTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self, obj, patches):
|
||||
super().setUp()
|
||||
self.patches = patches
|
||||
self.obj = obj
|
||||
self.patch_all()
|
||||
|
||||
def patch(self, method):
|
||||
_m = patch.object(self.obj, method)
|
||||
mock = _m.start()
|
||||
self.addCleanup(_m.stop)
|
||||
return mock
|
||||
|
||||
def patch_all(self):
|
||||
for method in self.patches:
|
||||
setattr(self, method, self.patch(method))
|
||||
|
||||
|
||||
class MockLspciProperty:
|
||||
def __init__(self, name):
|
||||
self.name = name
|
||||
|
||||
|
||||
class MockLspciDevice:
|
||||
def __init__(self, cls_name, vendor_name):
|
||||
self.cls = MockLspciProperty(cls_name)
|
||||
self.vendor = MockLspciProperty(vendor_name)
|
||||
|
||||
|
||||
class TestNovaComputeNvidiaVgpuCharm(CharmTestCase):
|
||||
|
||||
_PATCHES = [
|
||||
'SimpleParser',
|
||||
]
|
||||
|
||||
_PCI_DEVICES_LIST_WITHOUT_GPU = [
|
||||
# This is an NVIDIA device, but not a GPU card:
|
||||
MockLspciDevice(cls_name='VGA compatible controller',
|
||||
vendor_name='NVIDIA Corporation'),
|
||||
]
|
||||
|
||||
_PCI_DEVICES_LIST_WITH_NVIDIA_GPU = [
|
||||
# This is an NVIDIA device, but not a GPU card:
|
||||
MockLspciDevice(cls_name='VGA compatible controller',
|
||||
vendor_name='NVIDIA Corporation'),
|
||||
# This is an NVIDIA GPU card:
|
||||
MockLspciDevice(cls_name='3D controller',
|
||||
vendor_name='NVIDIA Corporation'),
|
||||
]
|
||||
|
||||
def setUp(self):
|
||||
self.harness = Harness(NovaComputeNvidiaVgpuCharm)
|
||||
super().setUp(src.charm, self._PATCHES)
|
||||
self.harness = Harness(src.charm.NovaComputeNvidiaVgpuCharm)
|
||||
self.addCleanup(self.harness.cleanup)
|
||||
self.harness.begin()
|
||||
|
||||
def test_start(self):
|
||||
def test_has_nvidia_gpu_hardware_with_hw(self):
|
||||
self.SimpleParser.return_value = MagicMock()
|
||||
self.SimpleParser.return_value.run.return_value = (
|
||||
self._PCI_DEVICES_LIST_WITH_NVIDIA_GPU)
|
||||
self.assertTrue(
|
||||
self.harness.charm._has_nvidia_gpu_hardware_notcached())
|
||||
|
||||
def test_has_nvidia_gpu_hardware_without_hw(self):
|
||||
self.SimpleParser.return_value = MagicMock()
|
||||
self.SimpleParser.return_value.run.return_value = (
|
||||
self._PCI_DEVICES_LIST_WITHOUT_GPU)
|
||||
self.assertFalse(
|
||||
self.harness.charm._has_nvidia_gpu_hardware_notcached())
|
||||
|
||||
def test_init(self):
|
||||
self.assertEqual(
|
||||
self.harness.framework.model.app.name,
|
||||
'nova-compute-nvidia-vgpu')
|
||||
# Test that charm is active upon installation.
|
||||
self.assertFalse(self.harness.charm._stored.is_started)
|
||||
self.assertIsNone(
|
||||
self.harness.charm._stored.last_installed_resource_hash)
|
||||
|
||||
def test_start(self):
|
||||
self.harness.charm.on.start.emit()
|
||||
self.assertTrue(isinstance(
|
||||
self.harness.model.unit.status, ActiveStatus))
|
||||
|
Loading…
Reference in New Issue
Block a user