summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-02-13 12:25:55 +0000
committerGerrit Code Review <review@openstack.org>2017-02-13 12:25:55 +0000
commitc77aa8923a59675d2474ef448d92663a31d5619c (patch)
tree29225246b4db7fc582c9acd76dabd919bbcbd89c
parent6c29488b0c40de32501ad96c8014cc5a77141da0 (diff)
parentd2a5333e9968edc88bdd9e854d6d5404435c5d60 (diff)
Merge "Limit the minimal RAM amount for OVS+DPDK to 1024MB"
-rw-r--r--nailgun/nailgun/api/v1/validators/node.py17
-rw-r--r--nailgun/nailgun/consts.py2
-rw-r--r--nailgun/nailgun/test/integration/test_orchestrator_serializer_90.py8
-rw-r--r--nailgun/nailgun/test/unit/test_node_attributes_validator.py76
4 files changed, 94 insertions, 9 deletions
diff --git a/nailgun/nailgun/api/v1/validators/node.py b/nailgun/nailgun/api/v1/validators/node.py
index c247bd8..5be2a06 100644
--- a/nailgun/nailgun/api/v1/validators/node.py
+++ b/nailgun/nailgun/api/v1/validators/node.py
@@ -503,6 +503,23 @@ class NodeAttributesValidator(base.BasicAttributesValidator):
503 ) 503 )
504 ) 504 )
505 505
506 dpdk_hugepages = utils.get_in(attrs, 'hugepages', 'dpdk', 'value')
507 if objects.Node.dpdk_enabled(node):
508 min_dpdk_hugepages = consts.MIN_DPDK_HUGEPAGES_MEMORY
509 if dpdk_hugepages < min_dpdk_hugepages:
510 raise errors.InvalidData(
511 "Node {0} does not have enough hugepages for dpdk. "
512 "Need to allocate at least {1} MB.".format(
513 node.id,
514 min_dpdk_hugepages
515 )
516 )
517 elif dpdk_hugepages != 0:
518 raise errors.InvalidData(
519 "Hugepages for dpdk should be equal to 0 "
520 "if dpdk is disabled."
521 )
522
506 try: 523 try:
507 objects.NodeAttributes.distribute_hugepages(node, attrs) 524 objects.NodeAttributes.distribute_hugepages(node, attrs)
508 except ValueError as exc: 525 except ValueError as exc:
diff --git a/nailgun/nailgun/consts.py b/nailgun/nailgun/consts.py
index c60b1c2..93007ab 100644
--- a/nailgun/nailgun/consts.py
+++ b/nailgun/nailgun/consts.py
@@ -518,6 +518,8 @@ DEFAULT_DEPLOYMENT_GRAPH_TYPE = 'default'
518DEFAULT_HUGEPAGE_SIZE = '2048' 518DEFAULT_HUGEPAGE_SIZE = '2048'
519HUGE_PAGES_SIZE_MAP = [('2048', '2M'), ('1048576', '1G')] 519HUGE_PAGES_SIZE_MAP = [('2048', '2M'), ('1048576', '1G')]
520DPDK_OVS_CORE_CPUS = 1 520DPDK_OVS_CORE_CPUS = 1
521# minimal RAM amount for OVS+DPDK in MB
522MIN_DPDK_HUGEPAGES_MEMORY = 1024
521 523
522MEMORY_RESERVED_FOR_OPERATING_SYSTEM = 1024 ** 3 # one GiB in bytes 524MEMORY_RESERVED_FOR_OPERATING_SYSTEM = 1024 ** 3 # one GiB in bytes
523 525
diff --git a/nailgun/nailgun/test/integration/test_orchestrator_serializer_90.py b/nailgun/nailgun/test/integration/test_orchestrator_serializer_90.py
index ee22c87..a7ba96f 100644
--- a/nailgun/nailgun/test/integration/test_orchestrator_serializer_90.py
+++ b/nailgun/nailgun/test/integration/test_orchestrator_serializer_90.py
@@ -488,7 +488,7 @@ class TestDeploymentAttributesSerialization90(
488 numa_nodes.append({ 488 numa_nodes.append({
489 'id': i, 489 'id': i,
490 'cpus': [i], 490 'cpus': [i],
491 'memory': 1024 ** 3 491 'memory': 2 * 1024 ** 3
492 }) 492 })
493 493
494 meta = { 494 meta = {
@@ -501,17 +501,19 @@ class TestDeploymentAttributesSerialization90(
501 cluster_id=self.cluster_db.id, 501 cluster_id=self.cluster_db.id,
502 roles=['compute'], 502 roles=['compute'],
503 meta=meta) 503 meta=meta)
504 node.interfaces[0].attributes.get('dpdk', {}).get(
505 'enabled', {})['value'] = True
504 node.attributes.update({ 506 node.attributes.update({
505 'hugepages': { 507 'hugepages': {
506 'dpdk': { 508 'dpdk': {
507 'value': 128}, 509 'value': 1024},
508 'nova': { 510 'nova': {
509 'value': {'2048': 1}}}} 511 'value': {'2048': 1}}}}
510 ) 512 )
511 serialized_for_astute = self.serialize() 513 serialized_for_astute = self.serialize()
512 serialized_node = serialized_for_astute['nodes'][0] 514 serialized_node = serialized_for_astute['nodes'][0]
513 self.assertEquals( 515 self.assertEquals(
514 [128, 128, 128], 516 [1024, 1024, 1024],
515 serialized_node['dpdk']['ovs_socket_mem']) 517 serialized_node['dpdk']['ovs_socket_mem'])
516 self.assertTrue(serialized_node['nova']['enable_hugepages']) 518 self.assertTrue(serialized_node['nova']['enable_hugepages'])
517 519
diff --git a/nailgun/nailgun/test/unit/test_node_attributes_validator.py b/nailgun/nailgun/test/unit/test_node_attributes_validator.py
index eb800fb..4b565e3 100644
--- a/nailgun/nailgun/test/unit/test_node_attributes_validator.py
+++ b/nailgun/nailgun/test/unit/test_node_attributes_validator.py
@@ -28,7 +28,7 @@ validator = node_validator.NodeAttributesValidator.validate
28 28
29def mock_cluster_attributes(func): 29def mock_cluster_attributes(func):
30 def wrapper(*args, **kwargs): 30 def wrapper(*args, **kwargs):
31 attr_mock = mock.patch.object( 31 cluster_attr_mock = mock.patch.object(
32 objects.Cluster, 32 objects.Cluster,
33 'get_editable_attributes', 33 'get_editable_attributes',
34 return_value={ 34 return_value={
@@ -39,7 +39,12 @@ def mock_cluster_attributes(func):
39 } 39 }
40 } 40 }
41 ) 41 )
42 with attr_mock: 42 node_dpdk_mock = mock.patch.object(
43 objects.Node,
44 'dpdk_enabled',
45 return_value=True
46 )
47 with cluster_attr_mock, node_dpdk_mock:
43 func(*args, **kwargs) 48 func(*args, **kwargs)
44 49
45 return wrapper 50 return wrapper
@@ -54,8 +59,8 @@ class BaseNodeAttributeValidatorTest(base.BaseTestCase):
54 meta['numa_topology'] = { 59 meta['numa_topology'] = {
55 "supported_hugepages": [2048, 1048576], 60 "supported_hugepages": [2048, 1048576],
56 "numa_nodes": [ 61 "numa_nodes": [
57 {"id": 0, "cpus": [0, 1], 'memory': 2 * 1024 ** 3}, 62 {"id": 0, "cpus": [0, 1], 'memory': 3 * 1024 ** 3},
58 {"id": 1, "cpus": [2, 3], 'memory': 2 * 1024 ** 3}, 63 {"id": 1, "cpus": [2, 3], 'memory': 3 * 1024 ** 3},
59 ] 64 ]
60 } 65 }
61 meta['cpu']['total'] = 4 66 meta['cpu']['total'] = 4
@@ -68,7 +73,7 @@ class BaseNodeAttributeValidatorTest(base.BaseTestCase):
68 }, 73 },
69 'dpdk': { 74 'dpdk': {
70 'type': 'number', 75 'type': 'number',
71 'value': 0, 76 'value': 1024,
72 }, 77 },
73 }, 78 },
74 'cpu_pinning': { 79 'cpu_pinning': {
@@ -107,7 +112,7 @@ class TestNodeAttributesValidatorHugepages(BaseNodeAttributeValidatorTest):
107 }, 112 },
108 }, 113 },
109 'dpdk': { 114 'dpdk': {
110 'value': 2, 115 'value': 1024,
111 }, 116 },
112 } 117 }
113 } 118 }
@@ -133,6 +138,65 @@ class TestNodeAttributesValidatorHugepages(BaseNodeAttributeValidatorTest):
133 validator, json.dumps(data), self.node, self.cluster) 138 validator, json.dumps(data), self.node, self.cluster)
134 139
135 @mock_cluster_attributes 140 @mock_cluster_attributes
141 def test_not_enough_dpdk_hugepages(self, m_dpdk_nics):
142 data = {
143 'hugepages': {
144 'nova': {
145 'value': {
146 '2048': 1,
147 '1048576': 0,
148 },
149 },
150 'dpdk': {
151 'value': 1023,
152 'min': 1024
153 },
154 }
155 }
156 message = ("Node {0} does not have enough hugepages for dpdk. "
157 "Need to allocate at least {1} MB.").format(self.node.id,
158 1024)
159 self.assertRaisesWithMessageIn(
160 errors.InvalidData, message,
161 validator, json.dumps(data), self.node, self.cluster)
162
163 @mock_cluster_attributes
164 @mock.patch.object(objects.Node, 'dpdk_enabled', return_value=False)
165 def test_valid_hugepages_non_dpdk(self, m_dpdk_nics, m_dpdk_enabled):
166 data = {
167 'hugepages': {
168 'nova': {
169 'value': {
170 '2048': 1,
171 '1048576': 1,
172 },
173 },
174 'dpdk': {
175 'value': 0,
176 },
177 }
178 }
179 self.assertNotRaises(errors.InvalidData, validator,
180 json.dumps(data), self.node, self.cluster)
181
182 @mock_cluster_attributes
183 @mock.patch.object(objects.Node, 'dpdk_enabled', return_value=False)
184 def test_non_zero_value_hugepages_non_dpdk(self, m_dpdk_nics,
185 m_dpdk_enabled):
186 data = {
187 'hugepages': {
188 'dpdk': {
189 'value': 1,
190 },
191 }
192 }
193 message = ("Hugepages for dpdk should be equal to 0 "
194 "if dpdk is disabled.")
195 self.assertRaisesWithMessageIn(
196 errors.InvalidData, message,
197 validator, json.dumps(data), self.node, self.cluster)
198
199 @mock_cluster_attributes
136 def test_dpdk_requires_too_much(self, m_dpdk_nics): 200 def test_dpdk_requires_too_much(self, m_dpdk_nics):
137 data = { 201 data = {
138 'hugepages': { 202 'hugepages': {