diff --git a/src/test/kotlin/org/eclipse/hara/ddiclient/integrationtest/ForcePingTest.kt b/src/test/kotlin/org/eclipse/hara/ddiclient/integrationtest/ForcePingTest.kt new file mode 100644 index 0000000..8244b59 --- /dev/null +++ b/src/test/kotlin/org/eclipse/hara/ddiclient/integrationtest/ForcePingTest.kt @@ -0,0 +1,191 @@ +/* + * + * * Copyright © 2017-2024 Kynetics LLC + * * + * * This program and the accompanying materials are made + * * available under the terms of the Eclipse Public License 2.0 + * * which is available at https://www.eclipse.org/legal/epl-2.0/ + * * + * * SPDX-License-Identifier: EPL-2.0 + * + */ + +package org.eclipse.hara.ddiclient.integrationtest + +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.eclipse.hara.ddiclient.api.DeploymentPermitProvider +import org.eclipse.hara.ddiclient.api.MessageListener +import org.eclipse.hara.ddiclient.integrationtest.api.management.AssignDistributionType +import org.eclipse.hara.ddiclient.integrationtest.api.management.HawkbitAssignDistributionBody +import org.eclipse.hara.ddiclient.integrationtest.utils.logCurrentFunctionName +import org.testng.Assert +import org.testng.annotations.BeforeTest +import org.testng.annotations.Test +import kotlin.time.Duration.Companion.seconds + +class ForcePingTest : AbstractHaraMessageTest() { + + override val targetId: String = "forcePingTest" + + + @BeforeTest + override fun beforeTest() { + super.beforeTest() + setPollingTime("00:00:30") + runBlocking { + reCreateTestTargetOnServer() + } + } + + override fun filterHaraMessages(message: MessageListener.Message): Boolean { + return when (message) { + is MessageListener.Message.Event.Polling, + is MessageListener.Message.State.Idle, + is MessageListener.Message.Event.NoNewState -> true + + else -> false + } + } + + @Test(enabled = true, priority = 1, timeOut = 10_000, invocationCount = 1) + fun forcePingShouldPollFromServerImmediatelyTest() { + logCurrentFunctionName() + runBlocking { + + client = clientFromTargetId().invoke(targetId) + + expectPolling() + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.State.Idle)) + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + + launch { + runTheTest(true) + } + + delay(3.seconds) + client?.forcePing() + } + } + + @Test(enabled = true, priority = 2, timeOut = 60_000, invocationCount = 1) + fun timeIntervalBetweenEachForcePingCallShouldBe30SecondsTest() { + logCurrentFunctionName() + runBlocking { + setPollingTime("00:00:30") + + client = clientFromTargetId().invoke(targetId) + + expectPolling() + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.State.Idle)) + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.NoNewState)) + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.NoNewState)) + + val testJob = launch { + runTheTest(true) + } + + delay(3.seconds) + client?.forcePing() + + delay(5.seconds) + client?.forcePing() + + delay(2.seconds) + Assert.assertTrue(testJob.isActive, "The test finished earlier than expected!") + } + } + + @Test(enabled = true, priority = 3, timeOut = 10_000, invocationCount = 1) + fun forcePingShouldReturnNoNewStateWhenTargetStateOnServerIsNotChanged() { + logCurrentFunctionName() + runBlocking { + + client = clientFromTargetId().invoke(targetId) + + expectPolling() + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.State.Idle)) + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.NoNewState)) + + launch { + runTheTest(true) + } + + delay(2.seconds) + client?.forcePing() + } + } + + @Test(enabled = true, priority = 4, timeOut = 150_000, invocationCount = 1) + fun haraClientShouldReturnPollingStateAfterTheForcePingPollsUpdateFromServer() { + logCurrentFunctionName() + runBlocking { + + setPollingTime("00:00:10") + val deploymentBehavior = object : DeploymentPermitProvider { + override fun downloadAllowed() = CompletableDeferred(false) + override fun updateAllowed() = CompletableDeferred(false) + } + + client = clientFromTargetId(deploymentPermitProvider = deploymentBehavior).invoke( + targetId) + + expectPolling() + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.State.Idle)) + + //Force Ping should poll update from server + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + + //Expected immediate Polling after the receiving the update from server + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + + //There should be no Idle/NoNewState after the last polling + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + + //Regular Pinging + expectedHaraMessages.add( + ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + + launch { + runTheTest(true) + } + + delay(3.seconds) + assignDistributionToTheTarget( + HawkbitAssignDistributionBody(3, AssignDistributionType.SOFT, 0)) + + delay(2.seconds) + client?.forcePing() + } + } + + private suspend fun runTheTest(lastTest: Boolean = false) { + client?.startAsync() + startWatchingExpectedMessages(lastTest) + } + + private fun expectPolling() { + expectMessages(ExpectedMessage.HaraMessage(MessageListener.Message.Event.Polling)) + } +} \ No newline at end of file