Fix incorrect error handling for resolveWorkflowOutputs
[ccsdk/cds.git] / ms / blueprintsprocessor / modules / services / workflow-service / src / test / kotlin / org / onap / ccsdk / cds / blueprintsprocessor / services / workflow / BluePrintWorkflowExecutionServiceImplTest.kt
1 /*
2  *  Copyright © 2019 IBM.
3  *
4  *  Licensed under the Apache License, Version 2.0 (the "License");
5  *  you may not use this file except in compliance with the License.
6  *  You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  */
16
17 package org.onap.ccsdk.cds.blueprintsprocessor.services.workflow
18
19 import com.fasterxml.jackson.databind.JsonNode
20 import com.fasterxml.jackson.databind.node.ObjectNode
21 import io.mockk.every
22 import io.mockk.mockk
23 import io.mockk.mockkObject
24 import io.mockk.unmockkAll
25 import kotlinx.coroutines.runBlocking
26 import org.junit.After
27 import org.junit.Before
28 import org.junit.Test
29 import org.junit.runner.RunWith
30 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ActionIdentifiers
31 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.CommonHeader
32 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceInput
33 import org.onap.ccsdk.cds.blueprintsprocessor.core.api.data.ExecutionServiceOutput
34 import org.onap.ccsdk.cds.blueprintsprocessor.core.service.BluePrintClusterService
35 import org.onap.ccsdk.cds.blueprintsprocessor.services.workflow.mock.MockComponentFunction
36 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintConstants
37 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintError
38 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintProcessorException
39 import org.onap.ccsdk.cds.controllerblueprints.core.asJsonType
40 import org.onap.ccsdk.cds.controllerblueprints.core.data.Step
41 import org.onap.ccsdk.cds.controllerblueprints.core.data.Workflow
42 import org.onap.ccsdk.cds.controllerblueprints.core.interfaces.BluePrintWorkflowExecutionService
43 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintContext
44 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintDependencyService
45 import org.onap.ccsdk.cds.controllerblueprints.core.service.BluePrintRuntimeService
46 import org.onap.ccsdk.cds.controllerblueprints.core.utils.BluePrintMetadataUtils
47 import org.onap.ccsdk.cds.controllerblueprints.core.utils.JacksonUtils
48 import org.springframework.beans.factory.annotation.Autowired
49 import org.springframework.boot.test.mock.mockito.MockBean
50 import org.springframework.test.context.ContextConfiguration
51 import org.springframework.test.context.junit4.SpringRunner
52 import java.lang.RuntimeException
53 import kotlin.test.assertEquals
54 import kotlin.test.assertFailsWith
55 import kotlin.test.assertNotNull
56
57 @RunWith(SpringRunner::class)
58 @ContextConfiguration(classes = [WorkflowServiceConfiguration::class])
59 class BluePrintWorkflowExecutionServiceImplTest {
60
61     @Autowired
62     lateinit var bluePrintWorkflowExecutionService: BluePrintWorkflowExecutionService<ExecutionServiceInput, ExecutionServiceOutput>
63
64     @MockBean
65     lateinit var bluePrintClusterService: BluePrintClusterService
66
67     @Before
68     fun init() {
69         mockkObject(BluePrintDependencyService)
70         every { BluePrintDependencyService.applicationContext.getBean(any()) } returns MockComponentFunction()
71     }
72
73     @After
74     fun afterTests() {
75         unmockkAll()
76     }
77
78     @Test
79     fun testBluePrintWorkflowExecutionService() {
80         runBlocking {
81             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(
82                 "1234",
83                 "./../../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration"
84             )
85
86             val executionServiceInput = JacksonUtils.readValueFromClassPathFile(
87                 "execution-input/resource-assignment-input.json",
88                 ExecutionServiceInput::class.java
89             )!!
90
91             val executionServiceOutput = bluePrintWorkflowExecutionService
92                 .executeBluePrintWorkflow(bluePrintRuntimeService, executionServiceInput, hashMapOf())
93
94             assertNotNull(executionServiceOutput, "failed to get response")
95             assertEquals(
96                 BluePrintConstants.STATUS_SUCCESS, executionServiceOutput.status.message,
97                 "failed to get successful response"
98             )
99         }
100     }
101
102     @Test
103     fun testImperativeBluePrintWorkflowExecutionService() {
104         runBlocking {
105             val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(
106                 "1234",
107                 "./../../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration"
108             )
109
110             val executionServiceInput = JacksonUtils.readValueFromClassPathFile(
111                 "execution-input/imperative-test-input.json",
112                 ExecutionServiceInput::class.java
113             )!!
114
115             val executionServiceOutput = bluePrintWorkflowExecutionService
116                 .executeBluePrintWorkflow(bluePrintRuntimeService, executionServiceInput, hashMapOf())
117
118             assertNotNull(executionServiceOutput, "failed to get response")
119             assertEquals(
120                 BluePrintConstants.STATUS_SUCCESS, executionServiceOutput.status.message,
121                 "failed to get successful response"
122             )
123         }
124     }
125
126     @Test
127     fun `Blueprint fails on missing workflowName-parameters with a useful message`() {
128         assertFailsWith(exceptionClass = BluePrintProcessorException::class) {
129             runBlocking {
130                 val bluePrintRuntimeService = BluePrintMetadataUtils.getBluePrintRuntime(
131                     "1234",
132                     "./../../../../../components/model-catalog/blueprint-model/test-blueprint/baseconfiguration"
133                 )
134                 // service input will have a mislabeled input params, we are expecting to get an error when that happens with a useful error message
135                 val executionServiceInput =
136                     JacksonUtils.readValueFromClassPathFile(
137                         "execution-input/resource-assignment-input-missing-resource_assignment_request.json",
138                         ExecutionServiceInput::class.java
139                     )!!
140
141                 val executionServiceOutput = bluePrintWorkflowExecutionService
142                     .executeBluePrintWorkflow(bluePrintRuntimeService, executionServiceInput, hashMapOf())
143             }
144         }
145     }
146
147     @Test
148     fun `Should handle errors from resolve workflow output`() {
149         val imperativeWorkflowExecutionService: ImperativeWorkflowExecutionService = mockk()
150         val bluePrintWorkflowExecutionServiceImpl = BluePrintWorkflowExecutionServiceImpl(
151                 mockk(), mockk(), imperativeWorkflowExecutionService)
152         val bluePrintRuntimeService: BluePrintRuntimeService<MutableMap<String, JsonNode>> = mockk()
153         val bluePrintContext: BluePrintContext = mockk()
154         val executionServiceInput = ExecutionServiceInput().apply {
155             this.actionIdentifiers = ActionIdentifiers().apply { this.actionName = "config-assign" }
156             this.commonHeader = CommonHeader()
157             this.payload = """{"config-assign-request": {}}""".asJsonType() as ObjectNode
158         }
159         val workflow = Workflow().apply {
160             this.steps = mutableMapOf("one" to Step(), "two" to Step())
161         }
162         val blueprintError = BluePrintError()
163
164         every { bluePrintRuntimeService.bluePrintContext() } returns bluePrintContext
165         every { bluePrintRuntimeService.assignWorkflowInputs(any(), any()) } returns Unit
166         every { bluePrintContext.workflowByName(any()) } returns workflow
167         every {
168             bluePrintRuntimeService.resolveWorkflowOutputs(any())
169         } throws RuntimeException("failed to resolve property...")
170         every {
171             runBlocking {
172                 imperativeWorkflowExecutionService.executeBluePrintWorkflow(any(), any(), any())
173             }
174         } returns ExecutionServiceOutput()
175         every { bluePrintRuntimeService.getBluePrintError() } returns blueprintError
176
177         runBlocking {
178             val output = bluePrintWorkflowExecutionServiceImpl.executeBluePrintWorkflow(
179                     bluePrintRuntimeService, executionServiceInput, mutableMapOf())
180             assertEquals("failed to resolve property...", blueprintError.errors[0])
181             assertEquals("""{"config-assign-response":{}}""".asJsonType(), output.payload)
182         }
183     }
184 }