diff options
Diffstat (limited to 'ms/blueprintsprocessor')
10 files changed, 620 insertions, 172 deletions
diff --git a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties index fc148bf49..0e2cdf9de 100755 --- a/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties +++ b/ms/blueprintsprocessor/application/src/main/resources/application-dev.properties @@ -18,10 +18,10 @@ #logging.level.web=DEBUG
# Web server config
-server.port=8080
+server.port=8081
blueprintsprocessor.grpcEnable=false
-blueprintsprocessor.httpPort=8080
+blueprintsprocessor.httpPort=8081
blueprintsprocessor.grpcPort=9111
# Blueprint Processor File Execution and Handling Properties
diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfMessage.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfMessage.kt index ef3605c66..1d5f515d0 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfMessage.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfMessage.kt @@ -1,5 +1,5 @@ /* - * Copyright © 2017-2019 AT&T, Bell Canada + * Copyright © 2019 Bell Canada * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,25 +18,13 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.utils.RpcStatus -class DeviceResponse { - var status: String? = null - var errorMessage: String? = null - var responseMessage: String? = null - var requestMessage: String? = null - private var subDeviceResponse: MutableMap<Any, Any>? = null - - fun addSubDeviceResponse(key: String, subDeviceResponse: DeviceResponse) { - if (this.subDeviceResponse == null) { - this.subDeviceResponse = hashMapOf() - } - this.subDeviceResponse!![key] = subDeviceResponse - } +data class DeviceResponse(var status: String? = null, + var errorMessage: String? = null, + var responseMessage: String? = null, + var requestMessage: String? = null) { fun isSuccess(): Boolean { - if (this.status != RpcStatus.SUCCESS && !this.errorMessage.isNullOrEmpty()) { - return false - } - return true + return this.status == RpcStatus.SUCCESS && this.errorMessage.isNullOrEmpty() } } @@ -45,13 +33,14 @@ class DeviceResponse { * Creates an event of a given type and for the specified subject and the current time. * * @param type event type - * @param payload message from the device + * @param messagePayload message from the device * @param messageId id of the message related to the event * @param deviceInfo device of event */ -class NetconfReceivedEvent - (private var type: Type, private var payload: String = "", private var messageId: String = "", - private var deviceInfo: DeviceInfo) { +class NetconfReceivedEvent(val type: Type, + val messagePayload: String = "", + val messageId: String = "", + val deviceInfo: DeviceInfo) { enum class Type { DEVICE_REPLY, @@ -59,16 +48,4 @@ class NetconfReceivedEvent DEVICE_ERROR, SESSION_CLOSED } - - fun getType(): Type { - return type - } - - fun getMessagePayload(): String { - return payload - } - - fun getMessageID(): String { - return messageId - } }
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfSessionListener.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfSessionListener.kt index cfdd0104c..23982dcb5 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfSessionListener.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfSessionListener.kt @@ -16,6 +16,5 @@ package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api interface NetconfSessionListener { - - fun notify(event: NetconfReceivedEvent) + fun accept(event: NetconfReceivedEvent) } diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt index 4199998a8..12e3b83da 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfDeviceCommunicator.kt @@ -57,11 +57,7 @@ class NetconfDeviceCommunicator(private var inputStream: InputStream, val cInt = bufferReader.read() if (cInt == -1) { log.error("$deviceInfo: Received cInt = -1") -// bufferReader.close() socketClosed = true -// sessionListener.notify(NetconfReceivedEvent( -// NetconfReceivedEvent.Type.SESSION_CLOSED, -// deviceInfo = deviceInfo)) } val c = cInt.toChar() state = state.evaluateChar(c) @@ -71,7 +67,7 @@ class NetconfDeviceCommunicator(private var inputStream: InputStream, if (deviceReply == RpcMessageUtils.END_PATTERN) { socketClosed = true bufferReader.close() - sessionListener.notify(NetconfReceivedEvent( + sessionListener.accept(NetconfReceivedEvent( NetconfReceivedEvent.Type.DEVICE_UNREGISTERED, deviceInfo = deviceInfo)) } else { @@ -84,7 +80,7 @@ class NetconfDeviceCommunicator(private var inputStream: InputStream, if (!NetconfMessageUtils.validateChunkedFraming(deviceReply)) { log.debug("$deviceInfo: Received badly framed message $deviceReply") socketClosed = true - sessionListener.notify(NetconfReceivedEvent( + sessionListener.accept(NetconfReceivedEvent( NetconfReceivedEvent.Type.DEVICE_ERROR, deviceInfo = deviceInfo)) } else { @@ -98,98 +94,89 @@ class NetconfDeviceCommunicator(private var inputStream: InputStream, } catch (e: IOException) { log.warn("$deviceInfo: Fail while reading from channel", e) - sessionListener.notify(NetconfReceivedEvent( + sessionListener.accept(NetconfReceivedEvent( NetconfReceivedEvent.Type.DEVICE_ERROR, deviceInfo = deviceInfo)) } } - private enum class NetconfMessageState { + /** + * State machine for the Netconf message parser + */ + internal enum class NetconfMessageState { NO_MATCHING_PATTERN { override fun evaluateChar(c: Char): NetconfMessageState { - return if (c == ']') { - FIRST_BRACKET - } else if (c == '\n') { - FIRST_LF - } else { - this + return when (c) { + ']' -> FIRST_BRACKET + '\n' -> FIRST_LF + else -> this } } }, FIRST_BRACKET { override fun evaluateChar(c: Char): NetconfMessageState { - return if (c == ']') { - SECOND_BRACKET - } else { - NO_MATCHING_PATTERN + return when (c) { + ']' -> SECOND_BRACKET + else -> NO_MATCHING_PATTERN } } }, SECOND_BRACKET { override fun evaluateChar(c: Char): NetconfMessageState { - return if (c == '>') { - FIRST_BIGGER - } else { - NO_MATCHING_PATTERN + return when (c) { + '>' -> FIRST_BIGGER + else -> NO_MATCHING_PATTERN } } }, FIRST_BIGGER { override fun evaluateChar(c: Char): NetconfMessageState { - return if (c == ']') { - THIRD_BRACKET - } else { - NO_MATCHING_PATTERN + return when (c) { + ']' -> THIRD_BRACKET + else -> NO_MATCHING_PATTERN } } }, THIRD_BRACKET { override fun evaluateChar(c: Char): NetconfMessageState { - return if (c == ']') { - ENDING_BIGGER - } else { - NO_MATCHING_PATTERN + return when (c) { + ']' -> ENDING_BIGGER + else -> NO_MATCHING_PATTERN } } }, ENDING_BIGGER { override fun evaluateChar(c: Char): NetconfMessageState { - return if (c == '>') { - END_PATTERN - } else { - NO_MATCHING_PATTERN + return when (c) { + '>' -> END_PATTERN + else -> NO_MATCHING_PATTERN } } }, FIRST_LF { override fun evaluateChar(c: Char): NetconfMessageState { - return if (c == '#') { - FIRST_HASH - } else if (c == ']') { - FIRST_BRACKET - } else if (c == '\n') { - this - } else { - NO_MATCHING_PATTERN + return when (c) { + '#' -> FIRST_HASH + ']' -> FIRST_BRACKET + '\n' -> this + else -> NO_MATCHING_PATTERN } } }, FIRST_HASH { override fun evaluateChar(c: Char): NetconfMessageState { - return if (c == '#') { - SECOND_HASH - } else { - NO_MATCHING_PATTERN + return when (c) { + '#' -> SECOND_HASH + else -> NO_MATCHING_PATTERN } } }, SECOND_HASH { override fun evaluateChar(c: Char): NetconfMessageState { - return if (c == '\n') { - END_CHUNKED_PATTERN - } else { - NO_MATCHING_PATTERN + return when (c) { + '\n' -> END_CHUNKED_PATTERN + else -> NO_MATCHING_PATTERN } } }, @@ -204,6 +191,11 @@ class NetconfDeviceCommunicator(private var inputStream: InputStream, } }; + /** + * Evaluate next transition state based on current state and the character read + * @param c character read in + * @return result of lookup of transition to the next {@link NetconfMessageState} + */ internal abstract fun evaluateChar(c: Char): NetconfMessageState } @@ -234,7 +226,7 @@ class NetconfDeviceCommunicator(private var inputStream: InputStream, } else { log.error("$deviceInfo: Invalid message received: \n $deviceReply") } - sessionListener.notify(NetconfReceivedEvent( + sessionListener.accept(NetconfReceivedEvent( NetconfReceivedEvent.Type.DEVICE_REPLY, deviceReply, NetconfMessageUtils.getMsgId(deviceReply), diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt index 4619460e3..e4e3ffe4a 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImpl.kt @@ -49,7 +49,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(rpc, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in invokeRpc command $e.message" + output.errorMessage = "$deviceInfo: failed in 'invokeRpc' command ${e.message}" } return output } @@ -63,7 +63,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(message, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in get-config command $e.message" + output.errorMessage = "$deviceInfo: failed in 'get-config' command ${e.message}" } return output } @@ -78,7 +78,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(deleteConfigMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in delete config command $e.message" + output.errorMessage = "$deviceInfo: failed in 'delete-config' command ${e.message}" } return output } @@ -93,7 +93,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(lockMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in lock command $e.message" + output.errorMessage = "$deviceInfo: failed in 'lock' command ${e.message}" } return output @@ -109,7 +109,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(unlockMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in lock command $e.message" + output.errorMessage = "$deviceInfo: failed in 'unLock' command ${e.message}" } return output } @@ -123,7 +123,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(messageContent, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in commit command $e.message" + output.errorMessage = "$deviceInfo: failed in 'commit' command ${e.message}" } return output } @@ -137,7 +137,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(messageContent, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in cancelCommit command $e.message" + output.errorMessage = "$deviceInfo: failed in 'cancelCommit' command ${e.message}" } return output } @@ -152,7 +152,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(discardChangesMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in discard changes command " + e.message + output.errorMessage = "$deviceInfo: failed in 'discard-config' command ${e.message}" } return output } @@ -169,7 +169,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ response = asyncRpc(editMessage, messageId) } catch (e: Exception) { response.status = RpcStatus.FAILURE - response.errorMessage = e.message + response.errorMessage = "$deviceInfo: failed in 'editConfig' command ${e.message}" } return response } @@ -183,7 +183,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(validateMessage, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in validate command " + e.message + output.errorMessage = "$deviceInfo: failed in 'validate' command ${e.message}" } return output } @@ -197,7 +197,7 @@ class NetconfRpcServiceImpl(private var deviceInfo: DeviceInfo) : NetconfRpcServ output = asyncRpc(messageContent, messageId) } catch (e: Exception) { output.status = RpcStatus.FAILURE - output.errorMessage = "$deviceInfo: failed in closeSession command " + e.message + output.errorMessage = "$deviceInfo: failed in 'closeSession' command ${e.message}" } return output } diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt index de4cda950..d0f4a1dfb 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt @@ -263,13 +263,13 @@ class NetconfSessionImpl(private val deviceInfo: DeviceInfo, private val rpcServ } inner class NetconfSessionListenerImpl : NetconfSessionListener { - override fun notify(event: NetconfReceivedEvent) { - val messageId = event.getMessageID() + override fun accept(event: NetconfReceivedEvent) { + val messageId = event.messageId - when (event.getType()) { + when (event.type) { NetconfReceivedEvent.Type.DEVICE_UNREGISTERED -> disconnect() - NetconfReceivedEvent.Type.DEVICE_ERROR -> errorReplies.add(event.getMessagePayload()) - NetconfReceivedEvent.Type.DEVICE_REPLY -> replies[messageId]?.complete(event.getMessagePayload()) + NetconfReceivedEvent.Type.DEVICE_ERROR -> errorReplies.add(event.messagePayload) + NetconfReceivedEvent.Type.DEVICE_REPLY -> replies[messageId]?.complete(event.messagePayload) NetconfReceivedEvent.Type.SESSION_CLOSED -> disconnect() } } diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/DeviceInfoTest.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/DeviceInfoTest.kt new file mode 100644 index 000000000..d46ee78dd --- /dev/null +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/DeviceInfoTest.kt @@ -0,0 +1,37 @@ +/* + * Copyright © 2019 Bell Canada + * + * 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. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api + + +import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo +import org.junit.Test +import kotlin.test.assertEquals + +class DeviceInfoTest { + @Test + fun testToString() { + + val di: DeviceInfo = DeviceInfo().apply { + username = "username" + password = "password" + ipAddress = "localhost" + port = 2224 + connectTimeout = 10 + } + assertEquals("localhost:2224", di.toString()) + } +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfMessageTest.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfMessageTest.kt new file mode 100644 index 000000000..70bf0158d --- /dev/null +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/api/NetconfMessageTest.kt @@ -0,0 +1,65 @@ +/* + * Copyright © 2019 Bell Canada + * + * 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. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api + +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test +import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.utils.RpcStatus + +class NetconfMessageTest { + @Test + fun testSuccessfulDeviceResponse() { + val dr: DeviceResponse = genSuccessfulEmptyDeviceResponse() + assertTrue(dr.isSuccess()) + + val dr2: DeviceResponse = genSuccessfulEmptyDeviceResponse() + dr2.errorMessage = "some error msg" + assertFalse(dr2.isSuccess()) + } + + @Test + fun testUnsuccessfulDeviceResponse() { + val dr: DeviceResponse = genUnsuccessfulEmptyDeviceResponse() + assertFalse(dr.isSuccess()) + + //case 2: Success, but with error message + val dr2: DeviceResponse = genUnsuccessfulEmptyDeviceResponse() + dr2.errorMessage = "Some error message." + assertFalse(dr2.isSuccess()) + } + + //helper function to generate a device response + private fun genSuccessfulEmptyDeviceResponse(): DeviceResponse { + return DeviceResponse().apply { + status = RpcStatus.SUCCESS + errorMessage = "" + responseMessage = "" + requestMessage = "" + } + } + + private fun genUnsuccessfulEmptyDeviceResponse(): DeviceResponse { + return DeviceResponse().apply { + status = RpcStatus.FAILURE + errorMessage = "" + responseMessage = "" + requestMessage = "" + } + } + +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfMessageStateTest.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfMessageStateTest.kt new file mode 100644 index 000000000..95148dd11 --- /dev/null +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfMessageStateTest.kt @@ -0,0 +1,146 @@ +/* + * Copyright © 2019 Bell Canada + * + * 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. + */ + +package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.core + +import org.junit.Test +import kotlin.test.assertEquals +import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.core.NetconfDeviceCommunicator.NetconfMessageState +class NetconfMessageStateTest { + + private val charList: List<Char> = Char.MIN_VALUE.toInt().rangeTo(Char.MAX_VALUE.toInt()) + .map { it -> it.toChar() } + + @Test + fun `NO_MATCHING_PATTERN transitions`() { + assertEquals(NetconfMessageState.FIRST_BRACKET, + NetconfMessageState.NO_MATCHING_PATTERN.evaluateChar(']')) + assertEquals(NetconfMessageState.FIRST_LF, + NetconfMessageState.NO_MATCHING_PATTERN.evaluateChar('\n')) + + charList.minus(listOf(']','\n')).forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.NO_MATCHING_PATTERN.evaluateChar(it)) + } + } + + @Test + fun `FIRST_BRACKET transitions`() { + assertEquals(NetconfMessageState.SECOND_BRACKET, + NetconfMessageState.FIRST_BRACKET.evaluateChar(']')) + + charList.minus( ']').forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.FIRST_BRACKET.evaluateChar(it)) + } + } + + @Test + fun `SECOND_BRACKET transitions`() { + assertEquals(NetconfMessageState.FIRST_BIGGER, + NetconfMessageState.SECOND_BRACKET.evaluateChar('>')) + + charList.minus('>').forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.SECOND_BRACKET.evaluateChar(it)) + } + } + + @Test + fun `FIRST_BIGGER transitions`() { + assertEquals(NetconfMessageState.THIRD_BRACKET, + NetconfMessageState.FIRST_BIGGER.evaluateChar(']')) + + charList.minus(']').forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.FIRST_BIGGER.evaluateChar(it)) + } + } + + @Test + fun `THIRD_BRACKET transitions`() { + assertEquals(NetconfMessageState.ENDING_BIGGER, + NetconfMessageState.THIRD_BRACKET.evaluateChar(']')) + + charList.minus(']').forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.THIRD_BRACKET.evaluateChar(it)) + } + } + + @Test + fun `ENDING_BIGGER transitions`() { + assertEquals(NetconfMessageState.END_PATTERN, + NetconfMessageState.ENDING_BIGGER.evaluateChar('>')) + + charList.minus('>').forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.ENDING_BIGGER.evaluateChar(it)) + } + } + + @Test + fun `FIRST_LF transitions`() { + assertEquals(NetconfMessageState.FIRST_HASH, + NetconfMessageState.FIRST_LF.evaluateChar('#')) + assertEquals(NetconfMessageState.FIRST_BRACKET, + NetconfMessageState.FIRST_LF.evaluateChar(']')) + assertEquals(NetconfMessageState.FIRST_LF, + NetconfMessageState.FIRST_LF.evaluateChar('\n')) + charList.minus(listOf('#', ']', '\n')).forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.FIRST_LF.evaluateChar(it)) + } + } + + @Test + fun `FIRST_HASH transitions`() { + assertEquals(NetconfMessageState.SECOND_HASH, + NetconfMessageState.FIRST_HASH.evaluateChar('#')) + charList.minus('#').forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.FIRST_HASH.evaluateChar(it)) + } + } + + @Test + fun `SECOND_HASH transitions`() { + assertEquals(NetconfMessageState.END_CHUNKED_PATTERN, + NetconfMessageState.SECOND_HASH.evaluateChar('\n')) + + charList.minus( '\n').forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.SECOND_HASH.evaluateChar(it)) + } + } + + @Test + fun `END_CHUNKED_PATTERN transitions`() { + charList.forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.END_CHUNKED_PATTERN.evaluateChar(it)) + } + } + + @Test + fun `END_PATTERN transitions`() { + charList.forEach { + assertEquals(NetconfMessageState.NO_MATCHING_PATTERN, + NetconfMessageState.END_PATTERN.evaluateChar(it)) + } + } + +}
\ No newline at end of file diff --git a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImplTest.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImplTest.kt index 68d3e246f..eb32c546b 100644 --- a/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImplTest.kt +++ b/ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfRpcServiceImplTest.kt @@ -1,124 +1,356 @@ +/* + * Copyright © 2019 Bell Canada + * + * 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. + */ + package org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.core -import org.junit.After -import org.junit.Assert +import io.mockk.every +import io.mockk.mockk +import io.mockk.spyk import org.junit.Before -import org.junit.Test -import org.junit.Assert.* +import org.junit.Test import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api.DeviceInfo -import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.mocks.NetconfDeviceSimulator +import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api.DeviceResponse +import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.api.NetconfException +import org.onap.ccsdk.cds.blueprintsprocessor.functions.netconf.executor.utils.RpcStatus +import java.io.IOException +import java.util.concurrent.CompletableFuture +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue class NetconfRpcServiceImplTest { + private lateinit var mockNetconfSession: NetconfSessionImpl - private var device: NetconfDeviceSimulator? = null - private var deviceInfo: DeviceInfo? = null - - @Before - fun before() { - deviceInfo = DeviceInfo().apply { + companion object { + private const val someString = "someString" + private const val replyStr = "this is a reply" + private val failedDeviceResponse = DeviceResponse(status = RpcStatus.FAILURE, + requestMessage = "request message", responseMessage = replyStr) //responseMessage will be null in this POJO + private val successfulDeviceResponse = DeviceResponse(status = RpcStatus.SUCCESS, + requestMessage = "request message", responseMessage = replyStr) //responseMessage will be null in this POJO + //but will be set later from mockSession + private const val msgId = "100" + private const val timeout = 5 + private val deviceInfo: DeviceInfo = DeviceInfo().apply { username = "username" password = "password" ipAddress = "localhost" port = 2224 - connectTimeout = 10 + connectTimeout = 5 } + } - device = NetconfDeviceSimulator(deviceInfo!!.port) - device!!.start() + @Before + fun setup() { + mockNetconfSession = mockk() } - @After - fun after() { - device!!.stop() + @Test + fun `invokeRpc completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val invokeRpcrResult = spy.invokeRpc(someString) + assertEquals(successfulDeviceResponse, invokeRpcrResult) } @Test - fun setNetconfSession() { + fun `invokeRpc on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val invokeRpcrResult = spy.invokeRpc(someString) + assertEquals(failedDeviceResponse.status, invokeRpcrResult.status) + assertTrue { invokeRpcrResult.errorMessage!!.contains("failed in 'invokeRpc' command") } + } + @Test + fun `getConfig completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val invokeRpcrResult = spy.getConfig(someString) + assertEquals(successfulDeviceResponse, invokeRpcrResult) } @Test - fun getConfig() { + fun `getConfig on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val getConfigRpcResult = spy.getConfig(someString) + assertEquals(failedDeviceResponse.status, getConfigRpcResult.status) + assertTrue { getConfigRpcResult.errorMessage!!.contains("failed in 'get-config' command") } + } - val netconfRpcServiceImpl = NetconfRpcServiceImpl(deviceInfo!!) - val netconfSession = NetconfSessionImpl(deviceInfo!!, netconfRpcServiceImpl) - netconfRpcServiceImpl.setNetconfSession(netconfSession) - netconfSession.connect() - Assert.assertTrue(netconfRpcServiceImpl.getConfig("filter","target").status.equals("failure")) + @Test + fun `deleteConfig completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.deleteConfig(someString) + assertEquals(successfulDeviceResponse, rpcResult) } + @Test + fun `deleteConfig on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val rpcResult = spy.deleteConfig(someString) + assertEquals(failedDeviceResponse.status, rpcResult.status) + assertTrue { rpcResult.errorMessage!!.contains("failed in 'delete-config' command") } + } @Test - fun deleteConfig() { + fun `lock completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.lock(someString) + assertEquals(successfulDeviceResponse, rpcResult) + } - val netconfRpcServiceImpl = NetconfRpcServiceImpl(deviceInfo!!) - val netconfSession = NetconfSessionImpl(deviceInfo!!, netconfRpcServiceImpl) - netconfRpcServiceImpl.setNetconfSession(netconfSession) - netconfSession.connect() - Assert.assertTrue(netconfRpcServiceImpl.deleteConfig("target").status.equals("failure")) + @Test + fun `lock on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val rpcResult = spy.lock(someString) + assertEquals(failedDeviceResponse.status, rpcResult.status) + assertTrue { rpcResult.errorMessage!!.contains("failed in 'lock' command") } } @Test - fun lock() { - val netconfRpcServiceImpl = NetconfRpcServiceImpl(deviceInfo!!) - val netconfSession = NetconfSessionImpl(deviceInfo!!, netconfRpcServiceImpl) - netconfRpcServiceImpl.setNetconfSession(netconfSession) - netconfSession.connect() - Assert.assertTrue(netconfRpcServiceImpl.lock("target").status.equals("failure")) + fun `unLock completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.unLock(someString) + assertEquals(successfulDeviceResponse, rpcResult) } @Test - fun unLock() { - val netconfRpcServiceImpl = NetconfRpcServiceImpl(deviceInfo!!) - val netconfSession = NetconfSessionImpl(deviceInfo!!, netconfRpcServiceImpl) - netconfRpcServiceImpl.setNetconfSession(netconfSession) - netconfSession.connect() - Assert.assertTrue(netconfRpcServiceImpl.unLock("target").status.equals("failure")) + fun `unLock on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val rpcResult = spy.unLock(someString) + assertEquals(failedDeviceResponse.status, rpcResult.status) + assertTrue { rpcResult.errorMessage!!.contains("failed in 'unLock' command") } } @Test - fun commit() { - val netconfRpcServiceImpl = NetconfRpcServiceImpl(deviceInfo!!) - val netconfSession = NetconfSessionImpl(deviceInfo!!, netconfRpcServiceImpl) - netconfRpcServiceImpl.setNetconfSession(netconfSession) - netconfSession.connect() - Assert.assertTrue(netconfRpcServiceImpl.commit(true,60,"persist","1").status.equals("failure")) + fun `commit completes normally on confirmed flag and only persist but not persistId specified`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.commit(true, timeout, persist = "blah", persistId = "") + assertEquals(successfulDeviceResponse, rpcResult) + } + @Test + fun `commit completes normally on no confirm flag and only persistId but not persist specified`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.commit(false, timeout, persistId = "blah") + assertEquals(successfulDeviceResponse, rpcResult) } @Test - fun cancelCommit() { - val netconfSession = NetconfSessionImpl(deviceInfo!!, NetconfRpcServiceImpl(DeviceInfo())) - val netconfRpcServiceImpl = NetconfRpcServiceImpl(DeviceInfo()) - netconfRpcServiceImpl.setNetconfSession(netconfSession) - netconfSession.connect() + fun `commit fails on confirm flag with persistId specified`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns failedDeviceResponse + val rpcResult = spy.commit(true, timeout, persistId = "blah") + assertTrue { rpcResult.errorMessage!!.contains("failed in 'commit' command") } + } - Assert.assertNotNull(netconfRpcServiceImpl.cancelCommit("1")) + @Test + fun `commit fails on confirm flag with persist and persistId specified`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns failedDeviceResponse + val rpcResult = spy.commit(true, timeout, persist = "blah", persistId = "blah") + assertTrue { rpcResult.errorMessage!!.contains("failed in 'commit' command") } } @Test - fun discardConfig() { - val netconfRpcServiceImpl = NetconfRpcServiceImpl(deviceInfo!!) - val netconfSession = NetconfSessionImpl(deviceInfo!!, netconfRpcServiceImpl) - netconfRpcServiceImpl.setNetconfSession(netconfSession) - netconfSession.connect() - Assert.assertTrue(netconfRpcServiceImpl.discardConfig().status.equals("failure")) + fun `commit fails on no confirm flag with persist and persistId specified`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns failedDeviceResponse + val rpcResult = spy.commit(false, timeout, persist = "blah", persistId = "blah") + assertTrue { rpcResult.errorMessage!!.contains("failed in 'commit' command") } + } + @Test + fun `cancelCommit completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.cancelCommit(someString) + assertEquals(successfulDeviceResponse, rpcResult) } @Test - fun editConfig() { + fun `cancelCommit on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val rpcResult = spy.cancelCommit(someString) + assertEquals(failedDeviceResponse.status, rpcResult.status) + assertTrue { rpcResult.errorMessage!!.contains("failed in 'cancelCommit' command") } } @Test - fun validate() { - val netconfRpcServiceImpl = NetconfRpcServiceImpl(deviceInfo!!) - val netconfSession = NetconfSessionImpl(deviceInfo!!, netconfRpcServiceImpl) - netconfRpcServiceImpl.setNetconfSession(netconfSession) - netconfSession.connect() - Assert.assertTrue(netconfRpcServiceImpl.validate("target").status.equals("failure")) + fun `discardConfig completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.discardConfig() + assertEquals(successfulDeviceResponse, rpcResult) + } + @Test + fun `discardConfig on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val rpcResult = spy.discardConfig() + assertEquals(failedDeviceResponse.status, rpcResult.status) + assertTrue { rpcResult.errorMessage!!.contains("failed in 'discard-config' command") } } + @Test + fun `editConfig completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.editConfig("blah1", "blah2", "blah3") + assertEquals(successfulDeviceResponse, rpcResult) + } + + @Test + fun `editConfig on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val rpcResult = spy.editConfig("blah1", "blah2", "blah3") + assertEquals(failedDeviceResponse.status, rpcResult.status) + assertTrue { rpcResult.errorMessage!!.contains("failed in 'editConfig' command") } + } + + @Test + fun `validate completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.validate("blah1") + assertEquals(successfulDeviceResponse, rpcResult) + } + + @Test + fun `validate on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val rpcResult = spy.validate("blah1") + assertEquals(failedDeviceResponse.status, rpcResult.status) + assertTrue { rpcResult.errorMessage!!.contains("failed in 'validate' command") } + } + + @Test + fun `closeSession completes normally without force`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.closeSession(false) + assertEquals(successfulDeviceResponse, rpcResult) + } + + @Test + fun `closeSession completes normally with force`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.closeSession(true) + assertEquals(successfulDeviceResponse, rpcResult) + } + + @Test + fun `closeSession on error sets DeviceResponse status to FAILURE`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } throws IOException("Some IO exception...") + val rpcResult = spy.closeSession(true) + assertEquals(failedDeviceResponse.status, rpcResult.status) + assertTrue { rpcResult.errorMessage!!.contains("failed in 'closeSession' command") } + } + + @Test + fun `asyncRpc completes normally`() { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + every { spy.asyncRpc(any(), any()) } returns successfulDeviceResponse + val rpcResult = spy.asyncRpc("blah1", "blah2") + assertEquals(successfulDeviceResponse, rpcResult) + } + + @Test + fun `asyncRpc on error throws NetconfException`() { + assertFailsWith(exceptionClass = NetconfException::class) { + val netconfRpcService = NetconfRpcServiceImpl(deviceInfo) + netconfRpcService.setNetconfSession(mockNetconfSession) + val spy = spyk(netconfRpcService) + val erroneousFuture = CompletableFuture<String>() + erroneousFuture.complete("something something rpc-error>") + every { mockNetconfSession.asyncRpc(any(), any()) } returns erroneousFuture + val rpcResult = spy.asyncRpc("blah1", "blah2") + assertEquals(failedDeviceResponse.status, rpcResult.status) + assertTrue { rpcResult.errorMessage!!.contains("failed in 'closeSession' command") } + } + } }
\ No newline at end of file |