[391121] Fix reported bootaction defect

- Created unit test scenario to match bug report and unable
  to reproduce error.

Change-Id: I06bdd6d2e89257c71d00e03c599a062f10f9e198
This commit is contained in:
Scott Hussey 2018-03-16 08:42:25 -05:00
parent 815aa333ec
commit 2d2bb08d86
11 changed files with 155 additions and 7 deletions

View File

@ -163,6 +163,8 @@ class BootactionAssetsResource(StatefulResource):
try:
task = self.state_manager.get_task(ba_ctx['task_id'])
self.logger.debug("Loading design for task %s from design ref %s" %
(ba_ctx['task_id'], task.design_ref))
design_status, site_design = self.orchestrator.get_effective_site(
task.design_ref)

View File

@ -88,6 +88,9 @@ class HostProfile(base.DrydockPersistentObject, base.DrydockObject):
def apply_inheritance(self, site_design):
# No parent to inherit from, just apply design values
# and return
if self.source == hd_fields.ModelSource.Compiled:
return
if self.parent_profile is None:
self.source = hd_fields.ModelSource.Compiled
return

View File

@ -554,7 +554,12 @@ class Orchestrator(object):
identity_key = None
self.logger.debug(
"Creating boot action context for node %s" % nodename)
for ba in site_design.bootactions:
self.logger.debug(
"Boot actions target nodes: %s" % ba.target_nodes)
if nodename in ba.target_nodes:
if identity_key is None:
identity_key = os.urandom(32)

View File

@ -59,7 +59,7 @@ class TestActionPrepareNodes(object):
# check that the PrepareNodes action was split
# with 2 nodes in the definition
assert len(task.subtask_id_list) == 2
assert len(task.subtask_id_list) == 3
for st_id in task.subtask_id_list:
st = drydock_state.get_task(st_id)

View File

@ -0,0 +1,73 @@
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
#
# Licensed 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.
"""Generic testing for the orchestrator."""
import pytest
import tarfile
import io
import falcon
from falcon import testing
import drydock_provisioner.objects.fields as hd_fields
from drydock_provisioner.control.api import start_api
class TestBootActionContext(object):
def test_bootaction_context(self, falcontest, seed_bootaction_multinode):
"""Test that the API will return a boot action context"""
for n, c in seed_bootaction_multinode.items():
url = "/api/v1.0/bootactions/nodes/%s/units" % n
auth_hdr = {'X-Bootaction-Key': "%s" % c['identity_key']}
result = falcontest.simulate_get(url, headers=auth_hdr)
assert result.status == falcon.HTTP_200
fileobj = io.BytesIO(result.content)
t = tarfile.open(mode='r:gz', fileobj=fileobj)
t.close()
@pytest.fixture()
def seed_bootaction_multinode(self, blank_state, deckhand_orchestrator,
input_files, mock_get_build_data):
"""Add a task and boot action to the database for testing."""
input_file = input_files.join("deckhand_fullsite.yaml")
design_ref = "file://%s" % input_file
test_task = deckhand_orchestrator.create_task(
action=hd_fields.OrchestratorAction.Noop, design_ref=design_ref)
ba_ctx = dict()
design_status, design_data = deckhand_orchestrator.get_effective_site(
design_ref)
for n in design_data.baremetal_nodes:
id_key = deckhand_orchestrator.create_bootaction_context(
n.name, test_task)
node_ctx = dict(
task_id=test_task.get_id(), identity_key=id_key.hex())
ba_ctx[n.name] = node_ctx
return ba_ctx
@pytest.fixture()
def falcontest(self, drydock_state, deckhand_ingester,
deckhand_orchestrator, mock_get_build_data):
"""Create a test harness for the the Falcon API framework."""
return testing.TestClient(
start_api(
state_manager=drydock_state,
ingester=deckhand_ingester,
orchestrator=deckhand_orchestrator))

View File

@ -29,7 +29,7 @@ class TestBootActionSignal(object):
deckhand_orchestrator.create_bootaction_context("compute01", task)
# In the fullsite YAML, node 'compute01' is assigned two
# In the fullsite YAML, node 'controller01' is assigned two
# bootactions - one with signaling enabled, one disabled.
# Validate these counts
@ -54,4 +54,4 @@ class TestBootActionSignal(object):
design_status, design_data = deckhand_orchestrator.get_effective_site(
design_ref=design_ref)
assert len(design_data.bootactions) == 2
assert len(design_data.bootactions) == 3

View File

@ -53,5 +53,5 @@ class TestClass(object):
for ba in design_data.bootactions:
if ba.get_id() == 'hw_filtered':
assert 'compute01' in ba.target_nodes
assert 'controller01' not in ba.target_nodes
assert 'compute01' in ba.target_nodes

View File

@ -29,7 +29,7 @@ class TestClass(object):
assert design_status.status == objects.fields.ValidationResult.Success
assert len(design_data.host_profiles) == 2
assert len(design_data.baremetal_nodes) == 2
assert len(design_data.baremetal_nodes) == 3
def test_ingest_deckhand_docref_exists(self, input_files, setup,
deckhand_ingester):

View File

@ -34,7 +34,7 @@ class TestKernelParameterReferences(object):
design_status, design_data = orchestrator.get_effective_site(
design_ref)
assert len(design_data.baremetal_nodes) == 2
assert len(design_data.baremetal_nodes) == 3
node = design_data.get_baremetal_node("compute01")

View File

@ -59,7 +59,7 @@ class TestStorageSizing(object):
'(Storage partition)|(Logical Volume) .+ size is < 0')
regex_1 = re.compile('greater than 99%')
assert len(message_list) == 6
assert len(message_list) == 8
for msg in message_list:
msg = msg.to_dict()
LOG.debug(msg)

View File

@ -360,6 +360,27 @@ data:
metadata:
rack: rack2
---
schema: 'drydock/BaremetalNode/v1'
metadata:
schema: 'metadata/Document/v1'
name: compute02
storagePolicy: 'cleartext'
labels:
application: 'drydock'
data:
host_profile: k8-node
addressing:
- network: pxe
address: dhcp
- network: mgmt
address: 172.16.1.23
- network: private
address: 172.16.2.23
- network: oob
address: 172.16.100.23
metadata:
rack: rack3
---
schema: 'drydock/HardwareProfile/v1'
metadata:
schema: 'metadata/Document/v1'
@ -473,4 +494,48 @@ data:
- base64_decode
- utf8_decode
- template
---
schema: 'drydock/BootAction/v1'
metadata:
schema: 'metadata/Document/v1'
name: hw_filtered2
storagePolicy: 'cleartext'
labels:
application: 'drydock'
data:
node_filter:
filter_set_type: 'union'
filter_set:
- filter_type: 'union'
node_names:
- 'compute02'
assets:
- path: /var/tmp/hello.sh
type: file
permissions: '555'
data: |-
IyEvYmluL2Jhc2gKCmVjaG8gJ0hlbGxvIFdvcmxkISAtZnJvbSB7eyBub2RlLmhvc3RuYW1lIH19
Jwo=
data_pipeline:
- base64_decode
- utf8_decode
- template
- path: /lib/systemd/system/hello.service
type: unit
permissions: '600'
data: |-
W1VuaXRdCkRlc2NyaXB0aW9uPUhlbGxvIFdvcmxkCgpbU2VydmljZV0KVHlwZT1vbmVzaG90CkV4
ZWNTdGFydD0vdmFyL3RtcC9oZWxsby5zaAoKW0luc3RhbGxdCldhbnRlZEJ5PW11bHRpLXVzZXIu
dGFyZ2V0Cg==
data_pipeline:
- base64_decode
- utf8_decode
- path: /var/tmp/designref.sh
type: file
permissions: '500'
data: e3sgYWN0aW9uLmRlc2lnbl9yZWYgfX0K
data_pipeline:
- base64_decode
- utf8_decode
- template
...