2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright (C) 2019 Huawei Technologies Co., Ltd. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * ============LICENSE_END=========================================================
21 package org.onap.ccsdk.cds.blueprintsprocessor.services.execution.scripts
23 import com.fasterxml.jackson.databind.JsonNode
24 import com.fasterxml.jackson.databind.ObjectMapper
25 import com.fasterxml.jackson.databind.node.ObjectNode
28 import io.mockk.verify
29 import kotlinx.coroutines.runBlocking
31 import org.junit.runner.RunWith
32 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ActionIdentifiers
33 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.CommonHeader
34 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
35 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.StepData
36 import org.onap.ccsdk.cds.blueprintsprocessor.core.service.BluePrintClusterService
37 import org.onap.ccsdk.cds.blueprintsprocessor.core.service.CDS_LOCK_GROUP
38 import org.onap.ccsdk.cds.blueprintsprocessor.core.service.ClusterLock
39 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.AbstractComponentFunction
40 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.ComponentFunctionScriptingService
41 import org.onap.ccsdk.cds.blueprintsprocessor.services.execution.nodeTypeComponentScriptExecutor
42 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
43 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintTypes
44 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonPrimitive
45 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
46 import org.onap.ccsdk.cds.controllerblueprints.core.data.Implementation
47 import org.onap.ccsdk.cds.controllerblueprints.core.data.LockAssignment
48 import org.onap.ccsdk.cds.controllerblueprints.core.normalizedPathName
49 import org.onap.ccsdk.cds.controllerblueprints.core.scripts.BluePrintScriptsServiceImpl
50 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
51 import org.onap.ccsdk.cds.controllerblueprints.core.service.DefaultBluePrintRuntimeService
52 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
53 import org.springframework.beans.factory.annotation.Autowired
54 import org.springframework.test.context.ContextConfiguration
55 import org.springframework.test.context.junit4.SpringRunner
56 import kotlin.test.BeforeTest
57 import kotlin.test.assertEquals
58 import kotlin.test.assertNotNull
61 * Unit test cases for abstract component function.
63 @RunWith(SpringRunner::class)
64 @ContextConfiguration(
65 classes = [ComponentFunctionScriptingService::class,
66 BluePrintScriptsServiceImpl::class, DeprecatedBlueprintJythonService::class]
68 class AbstractComponentFunctionTest {
70 lateinit var bluePrintRuntimeService: DefaultBluePrintRuntimeService
71 lateinit var blueprintContext: BluePrintContext
72 lateinit var blueprintClusterService: BluePrintClusterService
75 lateinit var compSvc: ComponentFunctionScriptingService
79 bluePrintRuntimeService = mockk()
80 blueprintContext = mockk()
81 blueprintClusterService = mockk()
82 every { bluePrintRuntimeService.bluePrintContext() } returns blueprintContext
84 every { blueprintContext.rootPath } returns normalizedPathName("target")
86 blueprintContext.nodeTemplateOperationImplementation(
89 } returns Implementation()
93 fun testAbstractComponent() {
95 val samp = SampleComponent()
96 val comp = samp as AbstractComponentFunction
98 comp.bluePrintRuntimeService = bluePrintRuntimeService
99 comp.stepName = "sample-step"
100 assertNotNull(comp, "failed to get kotlin instance")
102 val input = getMockedInput(bluePrintRuntimeService)
104 val output = comp.applyNB(input)
106 assertEquals(output.actionIdentifiers.actionName, "activate")
107 assertEquals(output.commonHeader.requestId, "1234")
108 assertEquals(output.stepData!!.name, "activate-restconf")
109 assertEquals(output.status.message, "success")
114 fun testComponentFunctionPayload() {
115 val sampleComponent = SampleComponent()
116 sampleComponent.workflowName = "sample-action"
117 sampleComponent.executionServiceInput = JacksonUtils.readValueFromClassPathFile(
118 "payload/requests/sample-execution-request.json", ExecutionServiceInput::class.java
120 val payload = sampleComponent.requestPayload()
121 assertNotNull(payload, "failed to get payload")
122 val data = sampleComponent.requestPayloadActionProperty("data")?.first()
123 assertNotNull(data, "failed to get payload request action data")
127 fun testAbstractScriptComponent() {
129 val samp = SampleRestconfComponent(compSvc)
130 val comp = samp as AbstractComponentFunction
132 comp.bluePrintRuntimeService = bluePrintRuntimeService
133 comp.stepName = "sample-step"
134 assertNotNull(comp, "failed to get kotlin instance")
136 val input = getMockedInput(bluePrintRuntimeService)
138 val output = comp.applyNB(input)
140 assertEquals(output.actionIdentifiers.actionName, "activate")
141 assertEquals(output.commonHeader.requestId, "1234")
142 assertEquals(output.stepData!!.name, "activate-restconf")
143 assertEquals(output.status.message, "success")
148 fun testComponentScriptExecutorNodeType() {
149 val componentScriptExecutor = BluePrintTypes.nodeTypeComponentScriptExecutor()
150 assertNotNull(componentScriptExecutor.interfaces, "failed to get interface operations")
154 fun `prepareRequestNB should resolve lock properties`() {
155 val implementation = Implementation().apply {
156 this.lock = LockAssignment().apply {
157 this.key = """ {"get_input": "lock-key"} """.asJsonPrimitive()
161 blueprintContext.nodeTemplateOperationImplementation(any(), any(), any())
162 } returns implementation
165 bluePrintRuntimeService.resolvePropertyAssignments(any(), any(), any())
166 } returns mutableMapOf(
167 "key" to "abc-123-def-456".asJsonType(),
168 "acquireTimeout" to implementation.lock!!.acquireTimeout
171 val component: AbstractComponentFunction = SampleComponent()
172 component.bluePrintRuntimeService = bluePrintRuntimeService
173 component.bluePrintClusterService = blueprintClusterService
176 component.prepareRequestNB(getMockedInput(bluePrintRuntimeService))
179 val resolvedLock = component.implementation.lock!!
181 assertEquals("abc-123-def-456", resolvedLock.key.textValue())
183 assertEquals(180, resolvedLock.acquireTimeout.intValue())
186 @Test(expected = Exception::class)
187 fun `prepareRequestNB should throw exception if it fails to resolve lock key`() {
189 blueprintContext.nodeTemplateOperationImplementation(any(), any(), any())
190 } returns Implementation().apply { this.lock = LockAssignment() }
193 bluePrintRuntimeService.resolvePropertyAssignments(any(), any(), any())
194 } returns mutableMapOf("key" to "".asJsonType(),
195 "acquireTimeout" to Integer(360).asJsonType())
197 val component: AbstractComponentFunction = SampleComponent()
198 component.bluePrintRuntimeService = bluePrintRuntimeService
199 component.bluePrintClusterService = blueprintClusterService
202 component.prepareRequestNB(getMockedInput(bluePrintRuntimeService))
207 fun `applyNB - when lock is present use ClusterLock`() {
209 val lockName = "testing-lock"
212 blueprintContext.nodeTemplateOperationImplementation(any(), any(), any())
213 } returns Implementation().apply {
214 this.lock = LockAssignment().apply { this.key = lockName.asJsonType() }
218 bluePrintRuntimeService.resolvePropertyAssignments(any(), any(), any())
219 } returns mutableMapOf("key" to lockName.asJsonType(),
220 "acquireTimeout" to Integer(180).asJsonType())
222 val clusterLock: ClusterLock = mockk()
224 every { clusterLock.name() } returns lockName
225 every { runBlocking { clusterLock.tryLock(any()) } } returns true
226 every { runBlocking { clusterLock.unLock() } } returns Unit
229 runBlocking { blueprintClusterService.clusterLock(any()) }
230 } returns clusterLock
232 val component: AbstractComponentFunction = SampleComponent()
233 component.bluePrintRuntimeService = bluePrintRuntimeService
234 component.bluePrintClusterService = blueprintClusterService
237 component.applyNB(getMockedInput(bluePrintRuntimeService))
241 runBlocking { blueprintClusterService.clusterLock("$lockName@$CDS_LOCK_GROUP") }
243 verify { runBlocking { clusterLock.unLock() } }
247 * Mocked input for abstract function test.
249 private fun getMockedInput(bluePrintRuntime: DefaultBluePrintRuntimeService):
250 ExecutionServiceInput {
252 val mapper = ObjectMapper()
253 val rootNode = mapper.createObjectNode()
254 rootNode.put("ip-address", "0.0.0.0")
255 rootNode.put("type", "rest")
257 val operationInputs = hashMapOf<String, JsonNode>()
258 operationInputs[BluePrintConstants.PROPERTY_CURRENT_NODE_TEMPLATE] =
259 "activate-restconf".asJsonPrimitive()
260 operationInputs[BluePrintConstants.PROPERTY_CURRENT_INTERFACE] =
261 "interfaceName".asJsonPrimitive()
262 operationInputs[BluePrintConstants.PROPERTY_CURRENT_OPERATION] =
263 "operationName".asJsonPrimitive()
264 operationInputs["dynamic-properties"] = rootNode
266 val stepInputData = StepData().apply {
267 name = "activate-restconf"
268 properties = operationInputs
270 val executionServiceInput = ExecutionServiceInput().apply {
271 commonHeader = CommonHeader().apply {
274 actionIdentifiers = ActionIdentifiers().apply {
275 actionName = "activate"
277 payload = JacksonUtils.jsonNode("{}") as ObjectNode
279 executionServiceInput.stepData = stepInputData
282 bluePrintRuntime.resolveNodeTemplateInterfaceOperationInputs(
283 "activate-restconf", "interfaceName", "operationName"
285 } returns operationInputs
287 val operationOutputs = hashMapOf<String, JsonNode>()
289 bluePrintRuntime.resolveNodeTemplateInterfaceOperationOutputs(
290 "activate-restconf", "interfaceName", "operationName"
292 } returns operationOutputs
293 every { bluePrintRuntime.bluePrintContext() } returns blueprintContext
295 return executionServiceInput