diff options
Diffstat (limited to 'opendc-web/opendc-web-server/src/test')
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()); + } +} |
