62cb108519485033a645bbe5c48510ee854483f3
[ccsdk/cds.git] /
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.controllerblueprints.core.service
18
19 import io.mockk.every
20 import io.mockk.mockk
21 import kotlinx.coroutines.CompletableDeferred
22 import kotlinx.coroutines.runBlocking
23 import org.junit.Test
24 import org.onap.ccsdk.cds.controllerblueprints.core.BluePrintException
25 import org.onap.ccsdk.cds.controllerblueprints.core.data.EdgeLabel
26 import org.onap.ccsdk.cds.controllerblueprints.core.data.Graph
27 import org.onap.ccsdk.cds.controllerblueprints.core.toGraph
28 import kotlin.test.assertNotNull
29
30 class BluePrintWorkflowServiceTest {
31     @Test
32     fun testSimpleFlow() {
33         runBlocking {
34             val graph = "[START>A/SUCCESS, A>B/SUCCESS, B>C/SUCCESS, C>D/SUCCESS, D>E/SUCCESS, E>END/SUCCESS]"
35                     .toGraph()
36             val simpleWorkflow = TestBluePrintWorkFlowService()
37             simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "B", "C", "D", "E"), null)
38             val deferredOutput = CompletableDeferred<String>()
39             val input = "123456"
40             simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input, deferredOutput)
41             val response = deferredOutput.await()
42             assertNotNull(response, "failed to get response")
43         }
44     }
45
46     @Test
47     fun testConditionalFlow() {
48         runBlocking {
49             val graph = "[START>A/SUCCESS, A>B/SUCCESS, A>C/FAILURE, B>D/SUCCESS, C>D/SUCCESS, D>END/SUCCESS]"
50                     .toGraph()
51             val simpleWorkflow = TestBluePrintWorkFlowService()
52             simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "B", "C", "D", "E"), null)
53             val deferredOutput = CompletableDeferred<String>()
54             val input = "123456"
55             simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input, deferredOutput)
56             val response = deferredOutput.await()
57             assertNotNull(response, "failed to get response")
58         }
59     }
60
61     @Test
62     fun testBothConditionalFlow() {
63         runBlocking {
64             // Failure Flow
65             val failurePatGraph = "[START>A/SUCCESS, A>B/SUCCESS, A>C/FAILURE, B>D/SUCCESS, C>D/SUCCESS, D>END/SUCCESS]"
66                     .toGraph()
67             val failurePathWorkflow = TestBluePrintWorkFlowService()
68             failurePathWorkflow.simulatedState = prepareSimulation(arrayListOf("B", "C", "D", "E"),
69                     arrayListOf("A"))
70             val failurePathWorkflowDeferredOutput = CompletableDeferred<String>()
71             val failurePathWorkflowInput = "123456"
72             failurePathWorkflow.executeWorkflow(failurePatGraph, mockBluePrintRuntimeService(), failurePathWorkflowInput, failurePathWorkflowDeferredOutput)
73             val failurePathResponse = failurePathWorkflowDeferredOutput.await()
74             assertNotNull(failurePathResponse, "failed to get response")
75         }
76     }
77
78     @Test
79     fun testMultipleSkipFlow() {
80         runBlocking {
81             val graph = "[START>A/SUCCESS, A>B/SUCCESS, A>C/FAILURE, C>D/SUCCESS, D>E/SUCCESS, B>E/SUCCESS, E>END/SUCCESS]"
82                     .toGraph()
83             val simpleWorkflow = TestBluePrintWorkFlowService()
84             simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "B", "C", "D", "E"), null)
85             val deferredOutput = CompletableDeferred<String>()
86             val input = "123456"
87             simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input, deferredOutput)
88             val response = deferredOutput.await()
89             assertNotNull(response, "failed to get response")
90         }
91     }
92
93     @Test
94     fun testParallelFlow() {
95         runBlocking {
96             val graph = "[START>A/SUCCESS, A>B/SUCCESS, A>C/SUCCESS, B>D/SUCCESS, C>D/SUCCESS, D>END/SUCCESS]"
97                     .toGraph()
98             val simpleWorkflow = TestBluePrintWorkFlowService()
99             simpleWorkflow.simulatedState = prepareSimulation(arrayListOf("A", "B", "C", "D"), null)
100             val deferredOutput = CompletableDeferred<String>()
101             val input = "123456"
102             simpleWorkflow.executeWorkflow(graph, mockBluePrintRuntimeService(), input, deferredOutput)
103             val response = deferredOutput.await()
104             assertNotNull(response, "failed to get response")
105         }
106     }
107
108     private fun mockBluePrintRuntimeService(): BluePrintRuntimeService<*> {
109         val bluePrintRuntimeService = mockk<BluePrintRuntimeService<*>>()
110         every { bluePrintRuntimeService.id() } returns "123456"
111         return bluePrintRuntimeService
112     }
113
114     private fun prepareSimulation(successes: List<String>?, failures: List<String>?): MutableMap<String, EdgeLabel> {
115         val simulatedState: MutableMap<String, EdgeLabel> = hashMapOf()
116         successes?.forEach {
117             simulatedState[it] = EdgeLabel.SUCCESS
118         }
119         failures?.forEach {
120             simulatedState[it] = EdgeLabel.FAILURE
121         }
122         return simulatedState
123     }
124 }
125
126 class TestBluePrintWorkFlowService
127     : AbstractBluePrintWorkFlowService<String, String>() {
128
129     lateinit var simulatedState: MutableMap<String, EdgeLabel>
130
131     override suspend fun initializeWorkflow(input: String): EdgeLabel {
132         return EdgeLabel.SUCCESS
133     }
134
135     override suspend fun prepareNodeExecutionMessage(node: Graph.Node)
136             : NodeExecuteMessage<String, String> {
137         val deferredNodeOutput = CompletableDeferred<String>()
138         val nodeExecuteMessage = NodeExecuteMessage(node, "$node Input", deferredNodeOutput)
139         return nodeExecuteMessage
140     }
141
142     override suspend fun executeNode(node: Graph.Node, nodeInput: String,
143                                      deferredNodeOutput: CompletableDeferred<String>,
144                                      deferredNodeStatus: CompletableDeferred<EdgeLabel>) {
145 //        val random = (1..10).random() * 1000
146 //        println("will reply in $random ms")
147 //        kotlinx.coroutines.delay(random.toLong())
148         val status = simulatedState[node.id] ?: throw BluePrintException("failed to get status for the node($node)")
149         deferredNodeStatus.complete(status)
150         deferredNodeOutput.complete("$node, Output: $nodeInput output")
151     }
152
153     override suspend fun prepareNodeSkipMessage(node: Graph.Node)
154             : NodeSkipMessage<String, String> {
155         val deferredNodeOutput = CompletableDeferred<String>()
156         val nodeSkipMessage = NodeSkipMessage(node, "$node Skip Input", deferredNodeOutput)
157         return nodeSkipMessage
158     }
159
160     override suspend fun skipNode(node: Graph.Node, nodeInput: String,
161                                   deferredNodeOutput: CompletableDeferred<String>,
162                                   deferredNodeStatus: CompletableDeferred<EdgeLabel>) {
163         val status = simulatedState[node.id] ?: throw BluePrintException("failed to get status for the node($node)")
164         deferredNodeStatus.complete(status)
165     }
166
167     override suspend fun cancelNode(node: Graph.Node, nodeInput: String,
168                                     deferredNodeOutput: CompletableDeferred<String>,
169                                     deferredNodeStatus: CompletableDeferred<EdgeLabel>) {
170         TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
171     }
172
173     override suspend fun restartNode(node: Graph.Node, nodeInput: String,
174                                      deferredNodeOutput: CompletableDeferred<String>,
175                                      deferredNodeStatus: CompletableDeferred<EdgeLabel>) {
176         TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
177     }
178
179     override suspend fun prepareWorkflowOutput(): String {
180         return "Final Response"
181     }
182 }