diff options
Diffstat (limited to 'opendc-web/opendc-web-server/src/test')
5 files changed, 224 insertions, 214 deletions
diff --git a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/service/UserAccountingServiceTest.java b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/service/UserAccountingServiceTest.java new file mode 100644 index 00000000..d1d82097 --- /dev/null +++ b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/service/UserAccountingServiceTest.java @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2023 AtLarge Research + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +package org.opendc.web.server.service; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyString; + +import io.quarkus.panache.mock.PanacheMock; +import io.quarkus.test.junit.QuarkusTest; +import java.time.Duration; +import java.time.LocalDate; +import javax.persistence.EntityExistsException; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.opendc.web.server.model.UserAccounting; + +/** + * Test suite for the {@link UserAccountingService}. + */ +@QuarkusTest +public class UserAccountingServiceTest { + /** + * The {@link UserAccountingService} instance under test. + */ + private UserAccountingService service; + + /** + * The user id to test with + */ + private final String userId = "test"; + + @BeforeEach + public void setUp() { + PanacheMock.mock(UserAccounting.class); + service = new UserAccountingService(Duration.ofHours(1)); + } + + @Test + public void testGetUserDoesNotExist() { + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(null); + + var accounting = service.getAccounting(userId); + + assertTrue(accounting.getPeriodEnd().isAfter(LocalDate.now())); + assertEquals(0, accounting.getSimulationTime()); + } + + @Test + public void testGetUserDoesExist() { + var now = LocalDate.now(); + var periodEnd = now.plusMonths(1); + + var mockAccounting = new UserAccounting(userId, periodEnd, 3600); + mockAccounting.simulationTime = 32; + + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(mockAccounting); + + var accounting = service.getAccounting(userId); + + assertAll( + () -> assertEquals(periodEnd, accounting.getPeriodEnd()), + () -> assertEquals(32, accounting.getSimulationTime()), + () -> assertEquals(3600, accounting.getSimulationTimeBudget())); + } + + @Test + public void testHasBudgetUserDoesNotExist() { + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(null); + + assertTrue(service.hasSimulationBudget(userId)); + } + + @Test + public void testHasBudget() { + var periodEnd = LocalDate.now().plusMonths(2); + + var mockAccounting = new UserAccounting(userId, periodEnd, 3600); + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(mockAccounting); + + assertTrue(service.hasSimulationBudget(userId)); + } + + @Test + public void testHasBudgetExceededButPeriodExpired() { + var periodEnd = LocalDate.now().minusMonths(2); + + var mockAccounting = new UserAccounting(userId, periodEnd, 3600); + mockAccounting.simulationTime = 3900; + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(mockAccounting); + + assertTrue(service.hasSimulationBudget(userId)); + } + + @Test + public void testHasBudgetPeriodExpired() { + var periodEnd = LocalDate.now().minusMonths(2); + + var mockAccounting = new UserAccounting(userId, periodEnd, 3600); + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(mockAccounting); + + assertTrue(service.hasSimulationBudget(userId)); + } + + @Test + public void testHasBudgetExceeded() { + var periodEnd = LocalDate.now().plusMonths(1); + + var mockAccounting = new UserAccounting(userId, periodEnd, 3600); + mockAccounting.simulationTime = 3900; + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(mockAccounting); + + assertFalse(service.hasSimulationBudget(userId)); + } + + @Test + public void testConsumeBudgetNewUser() { + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(null); + Mockito.when(UserAccounting.create(anyString(), any(), anyInt(), anyInt())) + .thenAnswer((i) -> { + var accounting = new UserAccounting(i.getArgument(0), i.getArgument(1), i.getArgument(2)); + accounting.simulationTime = i.getArgument(3); + return accounting; + }); + + assertFalse(service.consumeSimulationBudget(userId, 10)); + } + + @Test + public void testConsumeBudgetNewUserExceeded() { + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(null); + Mockito.when(UserAccounting.create(anyString(), any(), anyInt(), anyInt())) + .thenAnswer((i) -> { + var accounting = new UserAccounting(i.getArgument(0), i.getArgument(1), i.getArgument(2)); + accounting.simulationTime = i.getArgument(3); + return accounting; + }); + + assertTrue(service.consumeSimulationBudget(userId, 4000)); + } + + @Test + public void testConsumeBudgetNewUserConflict() { + var periodEnd = LocalDate.now().plusMonths(1); + var accountingMock = Mockito.spy(new UserAccounting(userId, periodEnd, 3600)); + + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(null).thenReturn(accountingMock); + Mockito.when(UserAccounting.create(anyString(), any(), anyInt(), anyInt())) + .thenThrow(new EntityExistsException()); + Mockito.when(accountingMock.consumeBudget(anyInt())).thenAnswer((i) -> { + accountingMock.simulationTime += i.<Integer>getArgument(0); + return true; + }); + + assertFalse(service.consumeSimulationBudget(userId, 10)); + } + + @Test + public void testConsumeBudgetResetSuccess() { + var periodEnd = LocalDate.now().minusMonths(2); + var accountingMock = Mockito.spy(new UserAccounting(userId, periodEnd, 3600)); + accountingMock.simulationTime = 3900; + + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(accountingMock); + Mockito.when(accountingMock.resetBudget(any(), anyInt())).thenAnswer((i) -> { + accountingMock.periodEnd = i.getArgument(0); + accountingMock.simulationTime += i.<Integer>getArgument(1); + return true; + }); + + assertTrue(service.consumeSimulationBudget(userId, 4000)); + } + + @Test + public void testInfiniteConflict() { + var periodEnd = LocalDate.now().plusMonths(1); + var accountingMock = Mockito.spy(new UserAccounting(userId, periodEnd, 3600)); + + Mockito.when(UserAccounting.findByUser(userId)).thenReturn(accountingMock); + Mockito.when(accountingMock.consumeBudget(anyInt())).thenAnswer((i) -> { + accountingMock.simulationTime += i.<Integer>getArgument(0); + return false; + }); + + assertThrows(IllegalStateException.class, () -> service.consumeSimulationBudget(userId, 10)); + } +} diff --git a/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/runner/JobResourceTest.kt b/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/runner/JobResourceTest.kt index 4a86c928..753b9ac4 100644 --- a/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/runner/JobResourceTest.kt +++ b/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/runner/JobResourceTest.kt @@ -101,7 +101,7 @@ class JobResourceTest { @Test @TestSecurity(user = "testUser", roles = ["runner"]) fun testQuery() { - every { jobService.queryPending() } returns listOf(dummyJob) + every { jobService.listPending() } returns listOf(dummyJob) When { get() diff --git a/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/user/PortfolioResourceTest.kt b/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/user/PortfolioResourceTest.kt index 5798d2e7..3ef63a51 100644 --- a/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/user/PortfolioResourceTest.kt +++ b/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/user/PortfolioResourceTest.kt @@ -68,7 +68,7 @@ class PortfolioResourceTest { @Test @TestSecurity(user = "testUser", roles = ["openid"]) fun testGetForProject() { - every { portfolioService.findAll("testUser", 1) } returns emptyList() + every { portfolioService.findByUser("testUser", 1) } returns emptyList() Given { pathParam("project", "1") @@ -197,7 +197,7 @@ class PortfolioResourceTest { @Test @TestSecurity(user = "testUser", roles = ["openid"]) fun testGetNonExisting() { - every { portfolioService.findOne("testUser", 1, 1) } returns null + every { portfolioService.findByUser("testUser", 1, 1) } returns null Given { pathParam("project", "1") @@ -215,7 +215,7 @@ class PortfolioResourceTest { @Test @TestSecurity(user = "testUser", roles = ["openid"]) fun testGetExisting() { - every { portfolioService.findOne("testUser", 1, 1) } returns dummyPortfolio + every { portfolioService.findByUser("testUser", 1, 1) } returns dummyPortfolio Given { pathParam("project", "1") diff --git a/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/user/ProjectResourceTest.kt b/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/user/ProjectResourceTest.kt index fec8759c..0be56c56 100644 --- a/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/user/ProjectResourceTest.kt +++ b/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/rest/user/ProjectResourceTest.kt @@ -91,7 +91,7 @@ class ProjectResourceTest { @TestSecurity(user = "testUser", roles = ["openid"]) fun testGetAll() { val projects = listOf(dummyProject) - every { projectService.findWithUser("testUser") } returns projects + every { projectService.findByUser("testUser") } returns projects When { get() @@ -108,7 +108,7 @@ class ProjectResourceTest { @Test @TestSecurity(user = "testUser", roles = ["openid"]) fun testGetNonExisting() { - every { projectService.findWithUser("testUser", 1) } returns null + every { projectService.findByUser("testUser", 1) } returns null When { get("/1") @@ -124,7 +124,7 @@ class ProjectResourceTest { @Test @TestSecurity(user = "testUser", roles = ["openid"]) fun testGetExisting() { - every { projectService.findWithUser("testUser", 1) } returns dummyProject + every { projectService.findByUser("testUser", 1) } returns dummyProject When { get("/1") @@ -141,7 +141,7 @@ class ProjectResourceTest { @Test @TestSecurity(user = "testUser", roles = ["openid"]) fun testCreate() { - every { projectService.createForUser("testUser", "test") } returns dummyProject + every { projectService.create("testUser", "test") } returns dummyProject Given { body(Project.Create("test")) @@ -196,7 +196,7 @@ class ProjectResourceTest { @Test @TestSecurity(user = "testUser", roles = ["openid"]) fun testDeleteNonExistent() { - every { projectService.deleteWithUser("testUser", 1) } returns null + every { projectService.delete("testUser", 1) } returns null When { delete("/1") @@ -212,7 +212,7 @@ class ProjectResourceTest { @Test @TestSecurity(user = "testUser", roles = ["openid"]) fun testDelete() { - every { projectService.deleteWithUser("testUser", 1) } returns dummyProject + every { projectService.delete("testUser", 1) } returns dummyProject When { delete("/1") @@ -228,7 +228,7 @@ class ProjectResourceTest { @Test @TestSecurity(user = "testUser", roles = ["openid"]) fun testDeleteNonOwner() { - every { projectService.deleteWithUser("testUser", 1) } throws IllegalArgumentException("User does not own project") + every { projectService.delete("testUser", 1) } throws IllegalArgumentException("User does not own project") When { delete("/1") diff --git a/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/service/UserAccountingServiceTest.kt b/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/service/UserAccountingServiceTest.kt deleted file mode 100644 index fdf04787..00000000 --- a/opendc-web/opendc-web-server/src/test/kotlin/org/opendc/web/server/service/UserAccountingServiceTest.kt +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2022 AtLarge Research - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -package org.opendc.web.server.service - -import io.mockk.every -import io.mockk.mockk -import io.quarkus.test.junit.QuarkusTest -import org.junit.jupiter.api.Assertions.assertAll -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Assertions.assertFalse -import org.junit.jupiter.api.Assertions.assertTrue -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows -import org.opendc.web.server.model.UserAccounting -import org.opendc.web.server.repository.UserAccountingRepository -import java.time.Duration -import java.time.LocalDate -import javax.persistence.EntityExistsException - -/** - * Test suite for the [UserAccountingService]. - */ -@QuarkusTest -class UserAccountingServiceTest { - /** - * The [UserAccountingRepository] that is mocked. - */ - private val repository: UserAccountingRepository = mockk() - - /** - * The [UserAccountingService] instance under test. - */ - private val service: UserAccountingService = UserAccountingService(repository, Duration.ofHours(1)) - - @Test - fun testGetUserDoesNotExist() { - val userId = "test" - - every { repository.findForUser(userId) } returns null - - val accounting = service.getAccounting(userId) - - assertTrue(accounting.periodEnd.isAfter(LocalDate.now())) - assertEquals(0, accounting.simulationTime) - } - - @Test - fun testGetUserDoesExist() { - val userId = "test" - - val now = LocalDate.now() - val periodEnd = now.plusMonths(1) - - every { repository.findForUser(userId) } returns UserAccounting(userId, periodEnd, 3600).also { it.simulationTime = 32 } - - val accounting = service.getAccounting(userId) - - assertAll( - { assertEquals(periodEnd, accounting.periodEnd) }, - { assertEquals(32, accounting.simulationTime) }, - { assertEquals(3600, accounting.simulationTimeBudget) } - ) - } - - @Test - fun testHasBudgetUserDoesNotExist() { - val userId = "test" - - every { repository.findForUser(userId) } returns null - - assertTrue(service.hasSimulationBudget(userId)) - } - - @Test - fun testHasBudget() { - val userId = "test" - val periodEnd = LocalDate.now().plusMonths(2) - - every { repository.findForUser(userId) } returns UserAccounting(userId, periodEnd, 3600) - - assertTrue(service.hasSimulationBudget(userId)) - } - - @Test - fun testHasBudgetExceededButPeriodExpired() { - val userId = "test" - val periodEnd = LocalDate.now().minusMonths(2) - - every { repository.findForUser(userId) } returns UserAccounting(userId, periodEnd, 3600).also { it.simulationTime = 3900 } - - assertTrue(service.hasSimulationBudget(userId)) - } - - @Test - fun testHasBudgetPeriodExpired() { - val userId = "test" - val periodEnd = LocalDate.now().minusMonths(2) - - every { repository.findForUser(userId) } returns UserAccounting(userId, periodEnd, 3600) - - assertTrue(service.hasSimulationBudget(userId)) - } - - @Test - fun testHasBudgetExceeded() { - val userId = "test" - val periodEnd = LocalDate.now().plusMonths(1) - - every { repository.findForUser(userId) } returns UserAccounting(userId, periodEnd, 3600).also { it.simulationTime = 3900 } - - assertFalse(service.hasSimulationBudget(userId)) - } - - @Test - fun testConsumeBudgetNewUser() { - val userId = "test" - - every { repository.findForUser(userId) } returns null - every { repository.save(any()) } returns Unit - - assertFalse(service.consumeSimulationBudget(userId, 10)) - } - - @Test - fun testConsumeBudgetNewUserExceeded() { - val userId = "test" - - every { repository.findForUser(userId) } returns null - every { repository.save(any()) } returns Unit - - assertTrue(service.consumeSimulationBudget(userId, 4000)) - } - - @Test - fun testConsumeBudgetNewUserConflict() { - val userId = "test" - - val periodEnd = LocalDate.now().plusMonths(1) - - every { repository.findForUser(userId) } returns null andThen UserAccounting(userId, periodEnd, 3600) - every { repository.save(any()) } throws EntityExistsException() - every { repository.consumeBudget(any(), any()) } answers { - val accounting = it.invocation.args[0] as UserAccounting - accounting.simulationTime -= it.invocation.args[1] as Int - true - } - - assertFalse(service.consumeSimulationBudget(userId, 10)) - } - - @Test - fun testConsumeBudgetResetSuccess() { - val userId = "test" - - val periodEnd = LocalDate.now().minusMonths(2) - - every { repository.findForUser(userId) } returns UserAccounting(userId, periodEnd, 3600).also { it.simulationTime = 3900 } - every { repository.resetBudget(any(), any(), any()) } answers { - val accounting = it.invocation.args[0] as UserAccounting - accounting.periodEnd = it.invocation.args[1] as LocalDate - accounting.simulationTime = it.invocation.args[2] as Int - true - } - - assertTrue(service.consumeSimulationBudget(userId, 4000)) - } - - @Test - fun testInfiniteConflict() { - val userId = "test" - - val periodEnd = LocalDate.now().plusMonths(1) - - every { repository.findForUser(userId) } returns UserAccounting(userId, periodEnd, 3600) - every { repository.consumeBudget(any(), any()) } answers { - val accounting = it.invocation.args[0] as UserAccounting - accounting.simulationTime -= it.invocation.args[1] as Int - false - } - - assertThrows<IllegalStateException> { service.consumeSimulationBudget(userId, 10) } - } -} |
