From ee01c09ce809a7d5171662e564a98c1ec1ea40fc Mon Sep 17 00:00:00 2001 From: Oleg Mitsura Date: Mon, 8 Apr 2019 16:47:45 -0400 Subject: netconf-executor tests: adding MessageStateTests Issue-ID: CCSDK-1126 Change-Id: I6351163cf6e157eda41a47b07e53dfaac00f5da5 Signed-off-by: Oleg Mitsura --- .../netconf/executor/api/NetconfSessionListener.kt | 3 +- .../executor/core/NetconfDeviceCommunicator.kt | 94 ++++++------- .../netconf/executor/core/NetconfSessionImpl.kt | 2 +- .../executor/core/NetconfMessageStateTest.kt | 146 +++++++++++++++++++++ 4 files changed, 191 insertions(+), 54 deletions(-) create mode 100644 ms/blueprintsprocessor/functions/netconf-executor/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfMessageStateTest.kt (limited to 'ms/blueprintsprocessor/functions/netconf-executor') 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/NetconfSessionImpl.kt b/ms/blueprintsprocessor/functions/netconf-executor/src/main/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/functions/netconf/executor/core/NetconfSessionImpl.kt index ae4d8444c..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,7 +263,7 @@ class NetconfSessionImpl(private val deviceInfo: DeviceInfo, private val rpcServ } inner class NetconfSessionListenerImpl : NetconfSessionListener { - override fun notify(event: NetconfReceivedEvent) { + override fun accept(event: NetconfReceivedEvent) { val messageId = event.messageId when (event.type) { 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.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 -- cgit 1.2.3-korg