diff options
| author | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2023-01-30 22:22:59 +0000 |
|---|---|---|
| committer | Fabian Mastenbroek <mail.fabianm@gmail.com> | 2023-02-02 21:56:07 +0000 |
| commit | 49b3015a16287bb4486aa64c5c26f05f7c22089c (patch) | |
| tree | 2c2e3ef49181ed740ac938b00a00ae5958d96d30 /opendc-web/opendc-web-server/src/test/java/org/opendc | |
| parent | 6927c51885bb3073b310150c4f40c64eea44a919 (diff) | |
refactor(web/server): Remove unnecessary service indirections
This change removes the unnecessary service classes where they are only
used to forward data from the resource to the entities. Furthermore,
DTOs are now moved from the service layer to the resources.
Diffstat (limited to 'opendc-web/opendc-web-server/src/test/java/org/opendc')
8 files changed, 586 insertions, 336 deletions
diff --git a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/TraceResourceTest.java b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/TraceResourceTest.java index ebef3945..5c5976db 100644 --- a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/TraceResourceTest.java +++ b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/TraceResourceTest.java @@ -25,16 +25,10 @@ package org.opendc.web.server.rest; import static io.restassured.RestAssured.when; import static org.hamcrest.Matchers.equalTo; -import io.quarkus.panache.mock.PanacheMock; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; import io.restassured.http.ContentType; -import java.util.stream.Stream; -import org.hamcrest.Matchers; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.opendc.web.server.model.Trace; /** * Test suite for {@link TraceResource}. @@ -43,21 +37,11 @@ import org.opendc.web.server.model.Trace; @TestHTTPEndpoint(TraceResource.class) public final class TraceResourceTest { /** - * Set up the test environment. - */ - @BeforeEach - public void setUp() { - PanacheMock.mock(Trace.class); - } - - /** - * Test that tries to obtain all traces (empty response). + * Test that tries to obtain all traces. */ @Test public void testGetAllEmpty() { - Mockito.when(Trace.streamAll()).thenReturn(Stream.of()); - - when().get().then().statusCode(200).contentType(ContentType.JSON).body("", Matchers.empty()); + when().get().then().statusCode(200).contentType(ContentType.JSON); } /** @@ -65,9 +49,7 @@ public final class TraceResourceTest { */ @Test public void testGetNonExisting() { - Mockito.when(Trace.findById("bitbrains")).thenReturn(null); - - when().get("/bitbrains").then().statusCode(404).contentType(ContentType.JSON); + when().get("/unknown").then().statusCode(404).contentType(ContentType.JSON); } /** @@ -75,12 +57,10 @@ public final class TraceResourceTest { */ @Test public void testGetExisting() { - Mockito.when(Trace.findById("bitbrains")).thenReturn(new Trace("bitbrains", "Bitbrains", "VM")); - - when().get("/bitbrains") + when().get("/bitbrains-small") .then() .statusCode(200) .contentType(ContentType.JSON) - .body("name", equalTo("Bitbrains")); + .body("name", equalTo("Bitbrains Small")); } } diff --git a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/runner/JobResourceTest.java b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/runner/JobResourceTest.java index a163cd29..94b2cef0 100644 --- a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/runner/JobResourceTest.java +++ b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/runner/JobResourceTest.java @@ -25,30 +25,13 @@ package org.opendc.web.server.rest.runner; import static io.restassured.RestAssured.given; import static io.restassured.RestAssured.when; import static org.hamcrest.Matchers.equalTo; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.junit.mockito.InjectMock; import io.quarkus.test.security.TestSecurity; import io.restassured.http.ContentType; -import java.time.Instant; -import java.util.List; -import java.util.Set; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.opendc.web.proto.JobState; -import org.opendc.web.proto.OperationalPhenomena; -import org.opendc.web.proto.Targets; -import org.opendc.web.proto.Trace; -import org.opendc.web.proto.Workload; -import org.opendc.web.proto.runner.Job; -import org.opendc.web.proto.runner.Portfolio; -import org.opendc.web.proto.runner.Scenario; -import org.opendc.web.proto.runner.Topology; -import org.opendc.web.server.service.JobService; /** * Test suite for {@link JobResource}. @@ -56,27 +39,6 @@ import org.opendc.web.server.service.JobService; @QuarkusTest @TestHTTPEndpoint(JobResource.class) public final class JobResourceTest { - @InjectMock - private JobService jobService; - - /** - * Dummy values - */ - private final Portfolio dummyPortfolio = new Portfolio(1, 1, "test", new Targets(Set.of(), 1)); - - private final Topology dummyTopology = new Topology(1, 1, "test", List.of(), Instant.now(), Instant.now()); - private final Trace dummyTrace = new Trace("bitbrains", "Bitbrains", "vm"); - private final Scenario dummyScenario = new Scenario( - 1, - 1, - dummyPortfolio, - "test", - new Workload(dummyTrace, 1.0), - dummyTopology, - new OperationalPhenomena(false, false), - "test"); - private final Job dummyJob = new Job(1, dummyScenario, JobState.PENDING, Instant.now(), Instant.now(), 0, null); - /** * Test that tries to query the pending jobs without token. */ @@ -90,7 +52,7 @@ public final class JobResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "test", roles = {"openid"}) public void testQueryInvalidScope() { when().get().then().statusCode(403); @@ -101,12 +63,10 @@ public final class JobResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "test", roles = {"runner"}) public void testQuery() { - Mockito.when(jobService.listPending()).thenReturn(List.of(dummyJob)); - - when().get().then().statusCode(200).contentType(ContentType.JSON).body("get(0).id", equalTo(1)); + when().get().then().statusCode(200).contentType(ContentType.JSON).body("get(0).state", equalTo("PENDING")); } /** @@ -114,12 +74,10 @@ public final class JobResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "test", roles = {"runner"}) public void testGetNonExisting() { - Mockito.when(jobService.findById(1)).thenReturn(null); - - when().get("/1").then().statusCode(404).contentType(ContentType.JSON); + when().get("/0").then().statusCode(404).contentType(ContentType.JSON); } /** @@ -127,11 +85,9 @@ public final class JobResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "test", roles = {"runner"}) public void testGetExisting() { - Mockito.when(jobService.findById(1)).thenReturn(dummyJob); - when().get("/1").then().statusCode(200).contentType(ContentType.JSON).body("id", equalTo(1)); } @@ -140,15 +96,13 @@ public final class JobResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "test", roles = {"runner"}) public void testUpdateNonExistent() { - Mockito.when(jobService.updateState(eq(1L), any(), anyInt(), any())).thenReturn(null); - - given().body(new Job.Update(JobState.PENDING, 0, null)) + given().body(new org.opendc.web.proto.runner.Job.Update(JobState.PENDING, 0, null)) .contentType(ContentType.JSON) .when() - .post("/1") + .post("/0") .then() .statusCode(404) .contentType(ContentType.JSON); @@ -159,16 +113,13 @@ public final class JobResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "test", roles = {"runner"}) public void testUpdateState() { - Mockito.when(jobService.updateState(eq(1L), any(), anyInt(), any())) - .thenReturn(new Job(1, dummyScenario, JobState.CLAIMED, Instant.now(), Instant.now(), 0, null)); - - given().body(new Job.Update(JobState.CLAIMED, 0, null)) + given().body(new org.opendc.web.proto.runner.Job.Update(JobState.CLAIMED, 0, null)) .contentType(ContentType.JSON) .when() - .post("/1") + .post("/2") .then() .statusCode(200) .contentType(ContentType.JSON) @@ -180,7 +131,7 @@ public final class JobResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "test", roles = {"runner"}) public void testUpdateInvalidInput() { given().body("{ \"test\": \"test\" }") diff --git a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/PortfolioResourceTest.java b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/PortfolioResourceTest.java index cc3ac978..a952d83f 100644 --- a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/PortfolioResourceTest.java +++ b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/PortfolioResourceTest.java @@ -24,24 +24,14 @@ package org.opendc.web.server.rest.user; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.equalTo; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.eq; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.junit.mockito.InjectMock; import io.quarkus.test.security.TestSecurity; import io.restassured.http.ContentType; -import java.time.Instant; -import java.util.List; import java.util.Set; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; import org.opendc.web.proto.Targets; -import org.opendc.web.proto.user.Portfolio; -import org.opendc.web.proto.user.Project; -import org.opendc.web.proto.user.ProjectRole; -import org.opendc.web.server.service.PortfolioService; /** * Test suite for {@link PortfolioResource}. @@ -49,27 +39,25 @@ import org.opendc.web.server.service.PortfolioService; @QuarkusTest @TestHTTPEndpoint(PortfolioResource.class) public final class PortfolioResourceTest { - @InjectMock - private PortfolioService portfolioService; - - /** - * Dummy project and portfolio - */ - private final Project dummyProject = new Project(1, "test", Instant.now(), Instant.now(), ProjectRole.OWNER); - - private final Portfolio dummyPortfolio = - new Portfolio(1, 1, dummyProject, "test", new Targets(Set.of(), 1), List.of()); - /** * Test that tries to obtain the list of portfolios belonging to a project. */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetForProject() { - Mockito.when(portfolioService.findByUser("testUser", 1)).thenReturn(List.of()); + given().pathParam("project", 1).when().get().then().statusCode(200).contentType(ContentType.JSON); + } + /** + * Test that tries to obtain the list of portfolios belonging to a project without authorization. + */ + @Test + @TestSecurity( + user = "unknown", + roles = {"openid"}) + public void testGetForProjectNoAuthorization() { given().pathParam("project", 1).when().get().then().statusCode(200).contentType(ContentType.JSON); } @@ -78,40 +66,53 @@ public final class PortfolioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreateNonExistent() { - Mockito.when(portfolioService.create(eq("testUser"), eq(1), any())).thenReturn(null); + given().pathParam("project", "0") + .body(new org.opendc.web.proto.user.Portfolio.Create("test", new Targets(Set.of(), 1))) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(404) + .contentType(ContentType.JSON); + } + /** + * Test that tries to create a topology for a project. + */ + @Test + @TestSecurity( + user = "viewer", + roles = {"openid"}) + public void testCreateNotPermitted() { given().pathParam("project", "1") - .body(new Portfolio.Create("test", new Targets(Set.of(), 1))) + .body(new org.opendc.web.proto.user.Portfolio.Create("test", new Targets(Set.of(), 1))) .contentType(ContentType.JSON) .when() .post() .then() - .statusCode(404) + .statusCode(403) .contentType(ContentType.JSON); } /** - * Test that tries to create a portfolio for a scenario. + * Test that tries to create a portfolio for a project. */ @Test @TestSecurity( - user = "testUser", + user = "editor", roles = {"openid"}) public void testCreate() { - Mockito.when(portfolioService.create(eq("testUser"), eq(1L), any())).thenReturn(dummyPortfolio); - given().pathParam("project", "1") - .body(new Portfolio.Create("test", new Targets(Set.of(), 1))) + .body(new org.opendc.web.proto.user.Portfolio.Create("test", new Targets(Set.of(), 1))) .contentType(ContentType.JSON) .when() .post() .then() .statusCode(200) .contentType(ContentType.JSON) - .body("id", equalTo(1)) .body("name", equalTo("test")); } @@ -120,7 +121,7 @@ public final class PortfolioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "editor", roles = {"openid"}) public void testCreateEmpty() { given().pathParam("project", "1") @@ -138,11 +139,11 @@ public final class PortfolioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "editor", roles = {"openid"}) public void testCreateBlankName() { given().pathParam("project", "1") - .body(new Portfolio.Create("", new Targets(Set.of(), 1))) + .body(new org.opendc.web.proto.user.Portfolio.Create("", new Targets(Set.of(), 1))) .contentType(ContentType.JSON) .when() .post() @@ -164,7 +165,7 @@ public final class PortfolioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"runner"}) public void testGetInvalidToken() { given().pathParam("project", "1").when().get("/1").then().statusCode(403); @@ -175,13 +176,27 @@ public final class PortfolioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetNonExisting() { - Mockito.when(portfolioService.findByUser("testUser", 1, 1)).thenReturn(null); - given().pathParam("project", "1") .when() + .get("/0") + .then() + .statusCode(404) + .contentType(ContentType.JSON); + } + + /** + * Test that tries to obtain a portfolio for a non-existent project. + */ + @Test + @TestSecurity( + user = "owner", + roles = {"openid"}) + public void testGetNonExistingProject() { + given().pathParam("project", "0") + .when() .get("/1") .then() .statusCode(404) @@ -193,11 +208,9 @@ public final class PortfolioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetExisting() { - Mockito.when(portfolioService.findByUser("testUser", 1, 1)).thenReturn(dummyPortfolio); - given().pathParam("project", "1") .when() .get("/1") @@ -212,12 +225,21 @@ public final class PortfolioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testDeleteNonExistent() { - Mockito.when(portfolioService.delete("testUser", 1, 1)).thenReturn(null); + given().pathParam("project", "1").when().delete("/0").then().statusCode(404); + } - given().pathParam("project", "1").when().delete("/1").then().statusCode(404); + /** + * Test to delete a portfolio on a non-existent project. + */ + @Test + @TestSecurity( + user = "owner", + roles = {"openid"}) + public void testDeleteNonExistentProject() { + given().pathParam("project", "0").when().delete("/1").then().statusCode(404); } /** @@ -225,16 +247,41 @@ public final class PortfolioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testDelete() { - Mockito.when(portfolioService.delete("testUser", 1, 1)).thenReturn(dummyPortfolio); + int number = given().pathParam("project", "1") + .body(new org.opendc.web.proto.user.Portfolio.Create("Delete Portfolio", new Targets(Set.of(), 1))) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(200) + .contentType(ContentType.JSON) + .extract() + .path("number"); given().pathParam("project", "1") .when() - .delete("/1") + .delete("/" + number) .then() .statusCode(200) .contentType(ContentType.JSON); } + + /** + * Test to delete a portfolio as a viewer. + */ + @Test + @TestSecurity( + user = "viewer", + roles = {"openid"}) + public void testDeleteAsViewer() { + given().pathParam("project", "1") + .when() + .delete("/1") + .then() + .statusCode(403) + .contentType(ContentType.JSON); + } } diff --git a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/PortfolioScenarioResourceTest.java b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/PortfolioScenarioResourceTest.java index 8cb95a98..4f8d412c 100644 --- a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/PortfolioScenarioResourceTest.java +++ b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/PortfolioScenarioResourceTest.java @@ -24,32 +24,15 @@ package org.opendc.web.server.rest.user; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.equalTo; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.eq; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.junit.mockito.InjectMock; import io.quarkus.test.security.TestSecurity; import io.restassured.http.ContentType; -import java.time.Instant; -import java.util.List; -import java.util.Set; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.opendc.web.proto.JobState; import org.opendc.web.proto.OperationalPhenomena; -import org.opendc.web.proto.Targets; -import org.opendc.web.proto.Trace; import org.opendc.web.proto.Workload; -import org.opendc.web.proto.user.Job; -import org.opendc.web.proto.user.Portfolio; -import org.opendc.web.proto.user.Project; -import org.opendc.web.proto.user.ProjectRole; import org.opendc.web.proto.user.Scenario; -import org.opendc.web.proto.user.Topology; -import org.opendc.web.server.service.ScenarioService; /** * Test suite for {@link PortfolioScenarioResource}. @@ -57,30 +40,6 @@ import org.opendc.web.server.service.ScenarioService; @QuarkusTest @TestHTTPEndpoint(PortfolioScenarioResource.class) public final class PortfolioScenarioResourceTest { - @InjectMock - private ScenarioService scenarioService; - - /** - * Dummy values - */ - private final Project dummyProject = new Project(0, "test", Instant.now(), Instant.now(), ProjectRole.OWNER); - - private final Portfolio.Summary dummyPortfolio = new Portfolio.Summary(1, 1, "test", new Targets(Set.of(), 1)); - private final Job dummyJob = new Job(1, JobState.PENDING, Instant.now(), Instant.now(), null); - private final Trace dummyTrace = new Trace("bitbrains", "Bitbrains", "vm"); - private final Topology.Summary dummyTopology = new Topology.Summary(1, 1, "test", Instant.now(), Instant.now()); - private final Scenario dummyScenario = new Scenario( - 1, - 1, - dummyProject, - dummyPortfolio, - "test", - new Workload(dummyTrace, 1.0), - dummyTopology, - new OperationalPhenomena(false, false), - "test", - dummyJob); - /** * Test that tries to obtain a portfolio without token. */ @@ -99,7 +58,7 @@ public final class PortfolioScenarioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"runner"}) public void testGetInvalidToken() { given().pathParam("project", "1") @@ -111,15 +70,30 @@ public final class PortfolioScenarioResourceTest { } /** - * Test that tries to obtain a non-existent portfolio. + * Test that tries to obtain a scenario without authorization. */ @Test @TestSecurity( - user = "testUser", + user = "unknown", roles = {"openid"}) - public void testGet() { - Mockito.when(scenarioService.findAll("testUser", 1, 1)).thenReturn(List.of()); + public void testGetUnauthorized() { + given().pathParam("project", "1") + .pathParam("portfolio", "1") + .when() + .get() + .then() + .statusCode(200) + .contentType(ContentType.JSON); + } + /** + * Test that tries to obtain a scenario. + */ + @Test + @TestSecurity( + user = "owner", + roles = {"openid"}) + public void testGet() { given().pathParam("project", "1") .pathParam("portfolio", "1") .when() @@ -134,14 +108,31 @@ public final class PortfolioScenarioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreateNonExistent() { - Mockito.when(scenarioService.create(eq("testUser"), eq(1L), anyInt(), any())) - .thenReturn(null); + given().pathParam("project", "1") + .pathParam("portfolio", "0") + .body(new Scenario.Create( + "test", new Workload.Spec("test", 1.0), 1, new OperationalPhenomena(false, false), "test")) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(404) + .contentType(ContentType.JSON); + } + /** + * Test that tries to create a scenario for a portfolio without authorization. + */ + @Test + @TestSecurity( + user = "unknown", + roles = {"openid"}) + public void testCreateUnauthorized() { given().pathParam("project", "1") - .pathParam("portfolio", "1") + .pathParam("portfolio", "0") .body(new Scenario.Create( "test", new Workload.Spec("test", 1.0), 1, new OperationalPhenomena(false, false), "test")) .contentType(ContentType.JSON) @@ -153,27 +144,47 @@ public final class PortfolioScenarioResourceTest { } /** + * Test that tries to create a scenario for a portfolio as a viewer. + */ + @Test + @TestSecurity( + user = "viewer", + roles = {"openid"}) + public void testCreateAsViewer() { + given().pathParam("project", "1") + .pathParam("portfolio", "0") + .body(new Scenario.Create( + "test", new Workload.Spec("test", 1.0), 1, new OperationalPhenomena(false, false), "test")) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(403) + .contentType(ContentType.JSON); + } + + /** * Test that tries to create a scenario for a portfolio. */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreate() { - Mockito.when(scenarioService.create(eq("testUser"), eq(1L), eq(1), any())) - .thenReturn(dummyScenario); - given().pathParam("project", "1") .pathParam("portfolio", "1") .body(new Scenario.Create( - "test", new Workload.Spec("test", 1.0), 1, new OperationalPhenomena(false, false), "test")) + "test", + new Workload.Spec("bitbrains-small", 1.0), + 1, + new OperationalPhenomena(false, false), + "test")) .contentType(ContentType.JSON) .when() .post() .then() .statusCode(200) .contentType(ContentType.JSON) - .body("id", equalTo(1)) .body("name", equalTo("test")); } @@ -182,7 +193,7 @@ public final class PortfolioScenarioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreateEmpty() { given().pathParam("project", "1") @@ -201,7 +212,7 @@ public final class PortfolioScenarioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreateBlankName() { given().pathParam("project", "1") @@ -215,4 +226,48 @@ public final class PortfolioScenarioResourceTest { .statusCode(400) .contentType(ContentType.JSON); } + + /** + * Test that tries to create a scenario for a portfolio. + */ + @Test + @TestSecurity( + user = "owner", + roles = {"openid"}) + public void testCreateUnknownTopology() { + given().pathParam("project", "1") + .pathParam("portfolio", "1") + .body(new Scenario.Create( + "test", + new Workload.Spec("bitbrains-small", 1.0), + -1, + new OperationalPhenomena(false, false), + "test")) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(400) + .contentType(ContentType.JSON); + } + + /** + * Test that tries to create a scenario for a portfolio. + */ + @Test + @TestSecurity( + user = "owner", + roles = {"openid"}) + public void testCreateUnknownTrace() { + given().pathParam("project", "1") + .pathParam("portfolio", "1") + .body(new Scenario.Create( + "test", new Workload.Spec("unknown", 1.0), 1, new OperationalPhenomena(false, false), "test")) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(400) + .contentType(ContentType.JSON); + } } diff --git a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/ProjectResourceTest.java b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/ProjectResourceTest.java index 7ca314a6..8bd60808 100644 --- a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/ProjectResourceTest.java +++ b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/ProjectResourceTest.java @@ -28,16 +28,9 @@ import static org.hamcrest.Matchers.equalTo; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.junit.mockito.InjectMock; import io.quarkus.test.security.TestSecurity; import io.restassured.http.ContentType; -import java.time.Instant; -import java.util.List; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.opendc.web.proto.user.Project; -import org.opendc.web.proto.user.ProjectRole; -import org.opendc.web.server.service.ProjectService; /** * Test suite for [ProjectResource]. @@ -45,14 +38,6 @@ import org.opendc.web.server.service.ProjectService; @QuarkusTest @TestHTTPEndpoint(ProjectResource.class) public final class ProjectResourceTest { - @InjectMock - private ProjectService projectService; - - /** - * Dummy values. - */ - private final Project dummyProject = new Project(0, "test", Instant.now(), Instant.now(), ProjectRole.OWNER); - /** * Test that tries to obtain all projects without token. */ @@ -66,7 +51,7 @@ public final class ProjectResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"runner"}) public void testGetAllWithInvalidScope() { when().get().then().statusCode(403); @@ -77,12 +62,10 @@ public final class ProjectResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetAll() { - Mockito.when(projectService.findByUser("testUser")).thenReturn(List.of(dummyProject)); - - when().get().then().statusCode(200).contentType(ContentType.JSON).body("get(0).name", equalTo("test")); + when().get().then().statusCode(200).contentType(ContentType.JSON).body("get(0).name", equalTo("Test Project")); } /** @@ -90,25 +73,21 @@ public final class ProjectResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetNonExisting() { - Mockito.when(projectService.findByUser("testUser", 1)).thenReturn(null); - - when().get("/1").then().statusCode(404).contentType(ContentType.JSON); + when().get("/0").then().statusCode(404).contentType(ContentType.JSON); } /** - * Test that tries to obtain a job. + * Test that tries to obtain a project. */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetExisting() { - Mockito.when(projectService.findByUser("testUser", 1)).thenReturn(dummyProject); - - when().get("/1").then().statusCode(200).contentType(ContentType.JSON).body("id", equalTo(0)); + when().get("/1").then().statusCode(200).contentType(ContentType.JSON).body("id", equalTo(1)); } /** @@ -116,19 +95,16 @@ public final class ProjectResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreate() { - Mockito.when(projectService.create("testUser", "test")).thenReturn(dummyProject); - - given().body(new Project.Create("test")) + given().body(new org.opendc.web.proto.user.Project.Create("test")) .contentType(ContentType.JSON) .when() .post() .then() .statusCode(200) .contentType(ContentType.JSON) - .body("id", equalTo(0)) .body("name", equalTo("test")); } @@ -137,7 +113,7 @@ public final class ProjectResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreateEmpty() { given().body("{}") @@ -154,10 +130,10 @@ public final class ProjectResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreateBlankName() { - given().body(new Project.Create("")) + given().body(new org.opendc.web.proto.user.Project.Create("")) .contentType(ContentType.JSON) .when() .post() @@ -171,12 +147,10 @@ public final class ProjectResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testDeleteNonExistent() { - Mockito.when(projectService.delete("testUser", 1)).thenReturn(null); - - when().delete("/1").then().statusCode(404).contentType(ContentType.JSON); + when().delete("/0").then().statusCode(404).contentType(ContentType.JSON); } /** @@ -184,12 +158,20 @@ public final class ProjectResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testDelete() { - Mockito.when(projectService.delete("testUser", 1)).thenReturn(dummyProject); + int id = given().body(new org.opendc.web.proto.user.Project.Create("Delete Project")) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(200) + .contentType(ContentType.JSON) + .extract() + .path("id"); - when().delete("/1").then().statusCode(200).contentType(ContentType.JSON); + when().delete("/" + id).then().statusCode(200).contentType(ContentType.JSON); } /** @@ -197,12 +179,9 @@ public final class ProjectResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "viewer", roles = {"openid"}) public void testDeleteNonOwner() { - Mockito.when(projectService.delete("testUser", 1)) - .thenThrow(new IllegalArgumentException("User does not own project")); - when().delete("/1").then().statusCode(403).contentType(ContentType.JSON); } } diff --git a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/ScenarioResourceTest.java b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/ScenarioResourceTest.java index 850236d6..a980e4e2 100644 --- a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/ScenarioResourceTest.java +++ b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/ScenarioResourceTest.java @@ -27,55 +27,42 @@ import static org.hamcrest.Matchers.equalTo; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.junit.mockito.InjectMock; import io.quarkus.test.security.TestSecurity; +import io.restassured.builder.RequestSpecBuilder; import io.restassured.http.ContentType; -import java.time.Instant; -import java.util.Set; +import io.restassured.specification.RequestSpecification; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.opendc.web.proto.JobState; import org.opendc.web.proto.OperationalPhenomena; -import org.opendc.web.proto.Targets; -import org.opendc.web.proto.Trace; import org.opendc.web.proto.Workload; -import org.opendc.web.proto.user.Job; -import org.opendc.web.proto.user.Portfolio; -import org.opendc.web.proto.user.Project; -import org.opendc.web.proto.user.ProjectRole; import org.opendc.web.proto.user.Scenario; -import org.opendc.web.proto.user.Topology; -import org.opendc.web.server.service.ScenarioService; /** - * Test suite for [ScenarioResource]. + * Test suite for {@link ScenarioResource}. */ @QuarkusTest @TestHTTPEndpoint(ScenarioResource.class) public final class ScenarioResourceTest { - @InjectMock - private ScenarioService scenarioService; + /** + * Test that tries to obtain all scenarios belonging to a project without authorization. + */ + @Test + @TestSecurity( + user = "unknown", + roles = {"openid"}) + public void testGetAllUnauthorized() { + given().pathParam("project", "1").when().get().then().statusCode(404).contentType(ContentType.JSON); + } /** - * Dummy values + * Test that tries to obtain all scenarios belonging to a project. */ - private final Project dummyProject = new Project(0, "test", Instant.now(), Instant.now(), ProjectRole.OWNER); - - private final Portfolio.Summary dummyPortfolio = new Portfolio.Summary(1, 1, "test", new Targets(Set.of(), 1)); - private final Job dummyJob = new Job(1, JobState.PENDING, Instant.now(), Instant.now(), null); - private final Trace dummyTrace = new Trace("bitbrains", "Bitbrains", "vm"); - private final Topology.Summary dummyTopology = new Topology.Summary(1, 1, "test", Instant.now(), Instant.now()); - private final Scenario dummyScenario = new Scenario( - 1, - 1, - dummyProject, - dummyPortfolio, - "test", - new Workload(dummyTrace, 1.0), - dummyTopology, - new OperationalPhenomena(false, false), - "test", - dummyJob); + @Test + @TestSecurity( + user = "owner", + roles = {"openid"}) + public void testGetAll() { + given().pathParam("project", "1").when().get().then().statusCode(200).contentType(ContentType.JSON); + } /** * Test that tries to obtain a scenario without token. @@ -90,7 +77,7 @@ public final class ScenarioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"runner"}) public void testGetInvalidToken() { given().pathParam("project", "1").when().get("/1").then().statusCode(403); @@ -101,11 +88,25 @@ public final class ScenarioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetNonExisting() { - Mockito.when(scenarioService.findOne("testUser", 1, 1)).thenReturn(null); + given().pathParam("project", "1") + .when() + .get("/0") + .then() + .statusCode(404) + .contentType(ContentType.JSON); + } + /** + * Test that tries to obtain a scenario. + */ + @Test + @TestSecurity( + user = "unknown", + roles = {"openid"}) + public void testGetExistingUnauthorized() { given().pathParam("project", "1") .when() .get("/1") @@ -119,11 +120,9 @@ public final class ScenarioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetExisting() { - Mockito.when(scenarioService.findOne("testUser", 1, 1)).thenReturn(dummyScenario); - given().pathParam("project", "1") .when() .get("/1") @@ -138,27 +137,65 @@ public final class ScenarioResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testDeleteNonExistent() { - Mockito.when(scenarioService.delete("testUser", 1, 1)).thenReturn(null); + given().pathParam("project", "1").when().delete("/0").then().statusCode(404); + } + /** + * Test to delete a scenario without authorization. + */ + @Test + @TestSecurity( + user = "unknown", + roles = {"openid"}) + public void testDeleteUnauthorized() { given().pathParam("project", "1").when().delete("/1").then().statusCode(404); } /** + * Test to delete a scenario as a viewer. + */ + @Test + @TestSecurity( + user = "viewer", + roles = {"openid"}) + public void testDeleteAsViewer() { + given().pathParam("project", "1").when().delete("/1").then().statusCode(403); + } + + /** * Test to delete a scenario. */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testDelete() { - Mockito.when(scenarioService.delete("testUser", 1, 1)).thenReturn(dummyScenario); + RequestSpecification spec = new RequestSpecBuilder() + .setBasePath("/projects/1/portfolios/1/scenarios") + .build(); + + int number = given(spec) + .body(new Scenario.Create( + "test", + new Workload.Spec("bitbrains-small", 1.0), + 1, + new OperationalPhenomena(false, false), + "test")) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(200) + .contentType(ContentType.JSON) + .extract() + .path("number"); given().pathParam("project", "1") .when() - .delete("/1") + .delete("/" + number) .then() .statusCode(200) .contentType(ContentType.JSON); diff --git a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/TopologyResourceTest.java b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/TopologyResourceTest.java index 2cc6ea4b..21e35b09 100644 --- a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/TopologyResourceTest.java +++ b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/rest/user/TopologyResourceTest.java @@ -24,24 +24,14 @@ package org.opendc.web.server.rest.user; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.equalTo; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.eq; import io.quarkus.test.common.http.TestHTTPEndpoint; import io.quarkus.test.junit.QuarkusTest; -import io.quarkus.test.junit.mockito.InjectMock; import io.quarkus.test.security.TestSecurity; import io.restassured.http.ContentType; -import java.time.Instant; import java.util.List; import org.junit.jupiter.api.Test; -import org.mockito.Mockito; -import org.opendc.web.proto.user.Project; -import org.opendc.web.proto.user.ProjectRole; import org.opendc.web.proto.user.Topology; -import org.opendc.web.server.service.TopologyService; /** * Test suite for {@link TopologyResource}. @@ -49,27 +39,31 @@ import org.opendc.web.server.service.TopologyService; @QuarkusTest @TestHTTPEndpoint(TopologyResource.class) public final class TopologyResourceTest { - @InjectMock - private TopologyService topologyService; - /** - * Dummy project and topology. + * Test that tries to obtain the list of topologies of a project without proper authorization. */ - private final Project dummyProject = new Project(1, "test", Instant.now(), Instant.now(), ProjectRole.OWNER); - - private final Topology dummyTopology = - new Topology(1, 1, dummyProject, "test", List.of(), Instant.now(), Instant.now()); + @Test + @TestSecurity( + user = "unknown", + roles = {"openid"}) + public void testGetAllWithoutAuth() { + given().pathParam("project", "1") + .when() + .get() + .then() + .statusCode(200) + .contentType(ContentType.JSON) + .body(equalTo("[]")); + } /** * Test that tries to obtain the list of topologies belonging to a project. */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) - public void testGetForProject() { - Mockito.when(topologyService.findAll("testUser", 1)).thenReturn(List.of()); - + public void testGetAll() { given().pathParam("project", "1").when().get().then().statusCode(200).contentType(ContentType.JSON); } @@ -78,18 +72,34 @@ public final class TopologyResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreateNonExistent() { - Mockito.when(topologyService.create(eq("testUser"), eq(1L), any())).thenReturn(null); + given().pathParam("project", "0") + .body(new Topology.Create("test", List.of())) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(404) + .contentType(ContentType.JSON); + } + /** + * Test that tries to create a topology for a project as viewer. + */ + @Test + @TestSecurity( + user = "viewer", + roles = {"openid"}) + public void testCreateUnauthorized() { given().pathParam("project", "1") .body(new Topology.Create("test", List.of())) .contentType(ContentType.JSON) .when() .post() .then() - .statusCode(404) + .statusCode(403) .contentType(ContentType.JSON); } @@ -98,11 +108,9 @@ public final class TopologyResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreate() { - Mockito.when(topologyService.create(eq("testUser"), eq(1L), any())).thenReturn(dummyTopology); - given().pathParam("project", "1") .body(new Topology.Create("test", List.of())) .contentType(ContentType.JSON) @@ -111,7 +119,6 @@ public final class TopologyResourceTest { .then() .statusCode(200) .contentType(ContentType.JSON) - .body("id", equalTo(1)) .body("name", equalTo("test")); } @@ -120,7 +127,7 @@ public final class TopologyResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreateEmpty() { given().pathParam("project", "1") @@ -138,7 +145,7 @@ public final class TopologyResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testCreateBlankName() { given().pathParam("project", "1") @@ -164,7 +171,7 @@ public final class TopologyResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"runner"}) public void testGetInvalidToken() { given().pathParam("project", "1").when().get("/1").then().statusCode(403); @@ -175,11 +182,25 @@ public final class TopologyResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetNonExisting() { - Mockito.when(topologyService.findOne("testUser", 1, 1)).thenReturn(null); + given().pathParam("project", "1") + .when() + .get("/0") + .then() + .statusCode(404) + .contentType(ContentType.JSON); + } + /** + * Test that tries to obtain a topology without authorization. + */ + @Test + @TestSecurity( + user = "unknown", + roles = {"openid"}) + public void testGetUnauthorized() { given().pathParam("project", "1") .when() .get("/1") @@ -193,11 +214,9 @@ public final class TopologyResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testGetExisting() { - Mockito.when(topologyService.findOne("testUser", 1, 1)).thenReturn(dummyTopology); - given().pathParam("project", "1") .when() .get("/1") @@ -212,12 +231,26 @@ public final class TopologyResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testUpdateNonExistent() { - Mockito.when(topologyService.update(eq("testUser"), anyLong(), anyInt(), any())) - .thenReturn(null); + given().pathParam("project", "1") + .body(new Topology.Update(List.of())) + .contentType(ContentType.JSON) + .when() + .put("/0") + .then() + .statusCode(404); + } + /** + * Test to delete a topology without authorization. + */ + @Test + @TestSecurity( + user = "unknown", + roles = {"openid"}) + public void testUpdateUnauthorized() { given().pathParam("project", "1") .body(new Topology.Update(List.of())) .contentType(ContentType.JSON) @@ -228,16 +261,31 @@ public final class TopologyResourceTest { } /** + * Test to update a topology as a viewer. + */ + @Test + @TestSecurity( + user = "viewer", + roles = {"openid"}) + public void testUpdateAsViewer() { + given().pathParam("project", "1") + .body(new Topology.Update(List.of())) + .contentType(ContentType.JSON) + .when() + .put("/1") + .then() + .statusCode(403) + .contentType(ContentType.JSON); + } + + /** * Test to update a topology. */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testUpdate() { - Mockito.when(topologyService.update(eq("testUser"), anyLong(), anyInt(), any())) - .thenReturn(dummyTopology); - given().pathParam("project", "1") .body(new Topology.Update(List.of())) .contentType(ContentType.JSON) @@ -253,27 +301,56 @@ public final class TopologyResourceTest { */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testDeleteNonExistent() { - Mockito.when(topologyService.delete("testUser", 1, 1)).thenReturn(null); + given().pathParam("project", "1").when().delete("/0").then().statusCode(404); + } + /** + * Test to delete a topology without authorization. + */ + @Test + @TestSecurity( + user = "unknown", + roles = {"openid"}) + public void testDeleteUnauthorized() { given().pathParam("project", "1").when().delete("/1").then().statusCode(404); } /** + * Test to delete a topology as a viewer. + */ + @Test + @TestSecurity( + user = "viewer", + roles = {"openid"}) + public void testDeleteAsViewer() { + given().pathParam("project", "1").when().delete("/1").then().statusCode(403); + } + + /** * Test to delete a topology. */ @Test @TestSecurity( - user = "testUser", + user = "owner", roles = {"openid"}) public void testDelete() { - Mockito.when(topologyService.delete("testUser", 1, 1)).thenReturn(dummyTopology); + int number = given().pathParam("project", "1") + .body(new Topology.Create("Delete Topology", List.of())) + .contentType(ContentType.JSON) + .when() + .post() + .then() + .statusCode(200) + .contentType(ContentType.JSON) + .extract() + .path("number"); given().pathParam("project", "1") .when() - .delete("/1") + .delete("/" + number) .then() .statusCode(200) .contentType(ContentType.JSON); diff --git a/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/service/JobServiceTest.java b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/service/JobServiceTest.java new file mode 100644 index 00000000..f6d871c0 --- /dev/null +++ b/opendc-web/opendc-web-server/src/test/java/org/opendc/web/server/service/JobServiceTest.java @@ -0,0 +1,124 @@ +/* + * 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.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.eq; + +import io.quarkus.test.junit.QuarkusTest; +import java.time.Instant; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; +import org.opendc.web.proto.JobState; +import org.opendc.web.server.model.Job; + +/** + * Test suite for the {@link JobService}. + */ +@QuarkusTest +public class JobServiceTest { + /** + * The {@link JobService} instance under test. + */ + private JobService service; + + /** + * The mock {@link UserAccountingService}. + */ + private UserAccountingService mockAccountingService; + + @BeforeEach + public void setUp() { + mockAccountingService = Mockito.mock(UserAccountingService.class); + service = new JobService(mockAccountingService); + } + + @Test + public void testUpdateInvalidTransition() { + Job job = new Job(null, "test", Instant.now(), 1); + job.state = JobState.RUNNING; + + assertThrows(IllegalArgumentException.class, () -> service.updateJob(job, JobState.CLAIMED, 0, null)); + + Mockito.verifyNoInteractions(mockAccountingService); + } + + @Test + public void testUpdateNoBudget() { + Job job = Mockito.spy(new Job(null, "test", Instant.now(), 1)); + job.state = JobState.RUNNING; + + Mockito.when(mockAccountingService.consumeSimulationBudget(any(), anyInt())) + .thenReturn(true); + Mockito.doReturn(true).when(job).updateAtomically(any(), any(), anyInt(), any()); + + service.updateJob(job, JobState.RUNNING, 0, null); + + Mockito.verify(job).updateAtomically(eq(JobState.FAILED), any(), anyInt(), any()); + } + + @Test + public void testUpdateNoBudgetWhenFinishing() { + Job job = Mockito.spy(new Job(null, "test", Instant.now(), 1)); + job.state = JobState.RUNNING; + + Mockito.when(mockAccountingService.consumeSimulationBudget(any(), anyInt())) + .thenReturn(true); + Mockito.doReturn(true).when(job).updateAtomically(any(), any(), anyInt(), any()); + + service.updateJob(job, JobState.FINISHED, 0, null); + + Mockito.verify(job).updateAtomically(eq(JobState.FINISHED), any(), anyInt(), any()); + } + + @Test + public void testUpdateSuccess() { + Job job = Mockito.spy(new Job(null, "test", Instant.now(), 1)); + job.state = JobState.RUNNING; + + Mockito.when(mockAccountingService.consumeSimulationBudget(any(), anyInt())) + .thenReturn(false); + Mockito.doReturn(true).when(job).updateAtomically(any(), any(), anyInt(), any()); + + service.updateJob(job, JobState.FINISHED, 0, null); + + Mockito.verify(job).updateAtomically(eq(JobState.FINISHED), any(), anyInt(), any()); + } + + @Test + public void testUpdateConflict() { + Job job = Mockito.spy(new Job(null, "test", Instant.now(), 1)); + job.state = JobState.RUNNING; + + Mockito.when(mockAccountingService.consumeSimulationBudget(any(), anyInt())) + .thenReturn(false); + Mockito.doReturn(false).when(job).updateAtomically(any(), any(), anyInt(), any()); + + assertThrows(IllegalStateException.class, () -> service.updateJob(job, JobState.FINISHED, 0, null)); + + Mockito.verify(job).updateAtomically(eq(JobState.FINISHED), any(), anyInt(), any()); + } +} |
