From 210cc0ab1bdff78fcefd80ad59e340635a21b063 Mon Sep 17 00:00:00 2001 From: Steve Siani Date: Tue, 19 Nov 2019 22:44:58 -0500 Subject: Cli executor doesn't keep/support execution context Issue-ID: CCSDK-1927 Signed-off-by: Steve Siani Change-Id: Ib417bfd62662676fe7520a5500df82ade716f66c --- .../ssh/service/BlueprintSshClientServiceTest.kt | 92 +++++++++++++++---- .../ssh/service/echoShell/EchoShellFactory.kt | 102 +++++++++++++++++++++ 2 files changed, 177 insertions(+), 17 deletions(-) create mode 100644 ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/echoShell/EchoShellFactory.kt (limited to 'ms/blueprintsprocessor/modules/commons/ssh-lib/src/test') diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientServiceTest.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientServiceTest.kt index 683816f7f..3785a21b2 100644 --- a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientServiceTest.kt +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/BlueprintSshClientServiceTest.kt @@ -1,6 +1,8 @@ /* * Copyright © 2019 IBM. * + * Modifications Copyright © 2018-2019 IBM, 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 @@ -25,18 +27,22 @@ import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider import org.apache.sshd.server.session.ServerSession import org.apache.sshd.server.shell.ProcessShellCommandFactory -import org.junit.runner.RunWith import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertiesService import org.onap.ccsdk.cds.blueprintsprocessor.core.BluePrintPropertyConfiguration import org.onap.ccsdk.cds.blueprintsprocessor.ssh.BluePrintSshLibConfiguration +import org.onap.ccsdk.cds.blueprintsprocessor.ssh.service.echoShell.EchoShellFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.test.context.ContextConfiguration import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit4.SpringRunner import java.nio.file.Paths +import org.junit.runner.RunWith +import kotlin.test.BeforeTest +import kotlin.test.AfterTest import kotlin.test.Test -import kotlin.test.assertEquals +import kotlin.test.assertTrue import kotlin.test.assertNotNull +import kotlin.test.assertEquals @RunWith(SpringRunner::class) @ContextConfiguration( @@ -57,29 +63,76 @@ class BlueprintSshClientServiceTest { @Autowired lateinit var bluePrintSshLibPropertyService: BluePrintSshLibPropertyService - @Test - fun testBasicAuthSshClientService() { + lateinit var bluePrintSshLibPropertyServiceMock: BluePrintSshLibPropertyService + + private lateinit var sshServer: SshServer + + @BeforeTest + fun startShellServer() { runBlocking { - val sshServer = setupTestServer("localhost", 52815, "root", "dummyps") + println("Start local Shell server") + sshServer = setupTestServer("localhost", 52815, "root", "dummyps") sshServer.start() println(sshServer) - val bluePrintSshLibPropertyService = bluePrintSshLibPropertyService.blueprintSshClientService("sample") - val sshSession = bluePrintSshLibPropertyService.startSession() - val response = bluePrintSshLibPropertyService.executeCommandsNB(arrayListOf("echo '1'", "echo '2'"), 2000) - assertNotNull(response, "failed to get command response") - bluePrintSshLibPropertyService.closeSession() - sshServer.stop(true) } } - private fun setupTestServer(host: String, port: Int, userName: String, password: String): SshServer { + @AfterTest + fun stopShellServer() { + println("End the Shell server") + sshServer.stop(true) + } + + @Test + fun testStartSessionNB() { + val clientSession = getSshClientService().startSession() + assertNotNull(clientSession, "Failed to start ssh session with server") + } + + @Test + fun testBasicAuthSshClientService() { + runBlocking { + val blueprintSshClientService = getSshClientService() + blueprintSshClientService.startSession() + // Preparing response + val commandResults = arrayListOf() + commandResults.add(CommandResult("echo 1", "echo 1\n#", true)) + commandResults.add(CommandResult("echo 2", "echo 1\n#echo 2\n#", true)) + val response = blueprintSshClientService.executeCommands(arrayListOf("echo 1", "echo 2"), 2000) + blueprintSshClientService.closeSession() + + assertEquals(response, commandResults, "failed to get command responses") + } + } + + @Test + fun `testBasicAuthSshClientService single execution command`() { + runBlocking { + val blueprintSshClientService = getSshClientService() + blueprintSshClientService.startSession() + val response = blueprintSshClientService.executeCommand("echo 1", 2000) + blueprintSshClientService.closeSession() + + assertEquals(response, CommandResult("echo 1", "echo 1\n#", true), "failed to get command response") + } + } + + @Test + fun testCloseSessionNB() { + val bluePrintSshLibPropertyService = bluePrintSshLibPropertyService.blueprintSshClientService("sample") + val clientSession = bluePrintSshLibPropertyService.startSession() + bluePrintSshLibPropertyService.closeSession() + assertTrue(clientSession.isClosed, "Failed to close ssh session with server") + } + + private fun setupTestServer(host: String, port: Int, username: String, password: String): SshServer { val sshd = SshServer.setUpDefaultServer() sshd.port = port sshd.host = host sshd.keyPairProvider = createTestHostKeyProvider() - sshd.passwordAuthenticator = BogusPasswordAuthenticator(userName, password) + sshd.passwordAuthenticator = BogusPasswordAuthenticator(username, password) sshd.publickeyAuthenticator = AcceptAllPublickeyAuthenticator.INSTANCE - // sshd.shellFactory = EchoShellFactory() + sshd.shellFactory = EchoShellFactory.INSTANCE sshd.commandFactory = ProcessShellCommandFactory.INSTANCE return sshd } @@ -90,12 +143,17 @@ class BlueprintSshClientServiceTest { keyProvider.algorithm = RSA_ALGORITHM return keyProvider } + + private fun getSshClientService(): BlueprintSshClientService { + return bluePrintSshLibPropertyService.blueprintSshClientService("sample") + } } -class BogusPasswordAuthenticator(userName: String, password: String) : PasswordAuthenticator { +class BogusPasswordAuthenticator(private val usr: String, private val pwd: String) : PasswordAuthenticator { + override fun authenticate(username: String, password: String, serverSession: ServerSession): Boolean { - assertEquals(username, "root", "failed to match username") - assertEquals(password, "dummyps", "failed to match password") + assertEquals(username, usr, "failed to match username") + assertEquals(password, pwd, "failed to match password") return true } } diff --git a/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/echoShell/EchoShellFactory.kt b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/echoShell/EchoShellFactory.kt new file mode 100644 index 000000000..9d308202f --- /dev/null +++ b/ms/blueprintsprocessor/modules/commons/ssh-lib/src/test/kotlin/org/onap/ccsdk/cds/blueprintsprocessor/ssh/service/echoShell/EchoShellFactory.kt @@ -0,0 +1,102 @@ +/* + * Copyright © 2019 IBM. 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.ssh.service.echoShell + +import org.apache.sshd.common.Factory +import org.apache.sshd.server.Environment +import org.apache.sshd.server.command.Command +import org.apache.sshd.server.ExitCallback +import java.io.InputStream +import java.io.OutputStream +import java.io.IOException +import java.io.BufferedReader +import java.io.InputStreamReader +import java.io.InterruptedIOException + +class EchoShellFactory : Factory { + + override fun create(): Command { + return EchoShell() + } + + companion object { + val INSTANCE = EchoShellFactory() + } +} + +class EchoShell : Command, Runnable { + + var `in`: InputStream? = null + private set + var out: OutputStream? = null + private set + var err: OutputStream? = null + private set + private var callback: ExitCallback? = null + var environment: Environment? = null + private set + private var thread: Thread? = null + + override fun setInputStream(`in`: InputStream) { + this.`in` = `in` + } + + override fun setOutputStream(out: OutputStream) { + this.out = out + } + + override fun setErrorStream(err: OutputStream) { + this.err = err + } + + override fun setExitCallback(callback: ExitCallback) { + this.callback = callback + } + + @Throws(IOException::class) + override fun start(env: Environment) { + environment = env + thread = Thread(this, "EchoShell") + thread!!.isDaemon = true + thread!!.start() + } + + override fun destroy() { + thread!!.interrupt() + } + + override fun run() { + val r = BufferedReader(InputStreamReader(`in`)) + try { + while (true) { + val s = r.readLine() ?: return + out!!.write((s + "\n").toByteArray()) + out!!.write("#".toByteArray()) + out!!.flush() + if ("exit" == s) { + return + } + } + } catch (e: InterruptedIOException) { + // Ignore + } catch (e: Exception) { + e.printStackTrace() + } finally { + callback!!.onExit(0) + } + } +} -- cgit 1.2.3-korg