From 8da31607be38c4fcc7ddd0560f3f16d2564c0d62 Mon Sep 17 00:00:00 2001 From: EvgenySafronov <32324614+EvgenySafronov@users.noreply.github.com> Date: Wed, 3 Apr 2024 17:58:08 +0300 Subject: [PATCH 1/2] fixed connections leak, added synchronization to avoid deadlocks --- src/main/java/main/model/db/dao/DAO.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/main/model/db/dao/DAO.java b/src/main/java/main/model/db/dao/DAO.java index b731ed1..b1dfbbe 100644 --- a/src/main/java/main/model/db/dao/DAO.java +++ b/src/main/java/main/model/db/dao/DAO.java @@ -213,8 +213,9 @@ public boolean updateMultiply(List entities) throws AqualityException { protected JSONArray CallStoredProcedure(String sql, List> parameters) throws AqualityException { JSONArray json = null; - CallableStatement callableStatement = executeCallableStatement(sql, parameters, null); + CallableStatement callableStatement = null; try { + callableStatement = executeCallableStatement(sql, parameters, null); ResultSet rs = callableStatement.getResultSet(); if (rs != null) { json = RS_Converter.convertToJSON(rs); @@ -284,18 +285,14 @@ private CallableStatement executeCallableStatement(String sql, List Date: Tue, 9 Apr 2024 17:54:18 +0300 Subject: [PATCH 2/2] Improved performance for endpoints: /public/test/create-or-update, /public/test/result/start, /public/test/result/finish; Fixed INSERT_TEST_RESULT final_result_id comparison --- CHANGELOG.md | 7 + pom.xml | 2 +- .../controllers/Project/ResultController.java | 102 +++++++++------ .../controllers/Project/TestController.java | 120 ++++++++++-------- src/main/java/main/model/db/dao/DAO.java | 2 +- .../main/model/db/dao/project/TestDao.java | 5 +- .../model/db/dao/project/TestResultDao.java | 45 ++++++- src/main/java/main/utils/DateUtils.java | 5 + .../PublicTestResultFinishServlet.java | 23 +--- .../PublicTestResultStartServlet.java | 10 +- .../view/publicApi/PublicTestServlet.java | 6 +- src/main/resources/db_changelog/changelog.xml | 1 + .../db_changelog/db.changelog-1.5.1.xml | 115 +++++++++++++++++ .../dao/project/TestResultDaoTest.java | 8 ++ 14 files changed, 324 insertions(+), 127 deletions(-) create mode 100644 src/main/resources/db_changelog/db.changelog-1.5.1.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index 2aef5ee..5e99f54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # CHANGELOG +## 1.5.1 (2024-04-12) +Bugfixes: +- Fixed 500 (Entity is locked) issue +- Fixed SQL connections leak +- Improved /public/test/create-or-update, /public/test/result/start, /public/test/result/finish performance +- Fixed INSERT_TEST_RESULT final_result_id comparison + ## 1.5.0 (2023-07-28) - Added `/issues/assign` endpoint, which allows to check previously created Test Runs and Test Results and assign Issues to them if there's a RegEx match diff --git a/pom.xml b/pom.xml index e232c60..3f52ae1 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ unifi_reporting_api api war - 1.5.0 + 1.5.1 UTF-8 diff --git a/src/main/java/main/controllers/Project/ResultController.java b/src/main/java/main/controllers/Project/ResultController.java index 09d52aa..87e014f 100644 --- a/src/main/java/main/controllers/Project/ResultController.java +++ b/src/main/java/main/controllers/Project/ResultController.java @@ -14,6 +14,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; public class ResultController extends BaseController { @@ -56,15 +57,29 @@ public TestResultDto create(TestResultDto template) throws AqualityException { } } - @Override - public List get(TestResultDto template) throws AqualityException { - if (baseUser.isFromGlobalManagement() || baseUser.getProjectUser(template.getProject_id()).isViewer()) { - return fillResults(testResultDao.searchAll(template)); + public TestResultDto updateWithFinalResultIdAndFailReason(TestResultDto testResult) throws AqualityException { + if (baseUser.isManager() || baseUser.getProjectUser(testResult.getProject_id()).isEditor()) { + return testResultDao.updateFinalResultIdAndFailReason( + testResult.getId(), + testResult.getFinal_result_id(), + testResult.getFail_reason(), + testResult.getFinish_date()); } else { - throw new AqualityPermissionsException("Account is not allowed to view Test Results", baseUser); + throw new AqualityPermissionsException("Account is not allowed to update Test Result", baseUser); } } + @Override + public List get(TestResultDto template) throws AqualityException { + checkReadPermissions(template.getProject_id()); + return fillResults(testResultDao.searchAll(template)); + } + + public List getRaw(TestResultDto template) throws AqualityException { + checkReadPermissions(template.getProject_id()); + return testResultDao.searchAll(template); + } + @Override public boolean delete(TestResultDto template) throws AqualityException { if (baseUser.isManager() || baseUser.getProjectUser(template.getProject_id()).isEditor()) { @@ -76,8 +91,11 @@ public boolean delete(TestResultDto template) throws AqualityException { public List getOnlyFailedResults(TestResultDto testResultTemplate) throws AqualityException { List testResults = this.get(testResultTemplate); - return testResults.stream().filter(x -> x.getFinal_result_id() != FAILED_STATUS_ID && x.getFail_reason() != null - && x.getIssue_id() == null).collect(Collectors.toList()); + return testResults.stream() + .filter(x -> !Objects.equals(x.getFinal_result_id(), FAILED_STATUS_ID) && + x.getFail_reason() != null && + x.getIssue_id() == null) + .collect(Collectors.toList()); } public boolean createMultiple(List listOfAttachments) throws AqualityException { @@ -98,7 +116,7 @@ public List getLatestResultsByMilestone(Integer projectId, Intege } public boolean updateMultipleTestResults(List entities) throws AqualityException { - if (entities.size() > 0 + if (!entities.isEmpty() && (baseUser.isManager() || baseUser.getProjectUser(entities.get(0).getProject_id()).isEditor())) { return testResultDao.updateMultiply(entities); } else { @@ -114,6 +132,38 @@ public List get(TestResultStatDto template) throws AqualityEx } } + public Map matchIssues(Integer testResultId) throws AqualityException { + TestResultDto testResultTemplate = new TestResultDto(); + testResultTemplate.setId(testResultId); + List testResults = this.getOnlyFailedResults(testResultTemplate); + if (testResults.isEmpty()) { + throw new AqualityParametersException("No test result found to update. Wrong ID might be provided."); + } + IssueDto issueTemplate = new IssueDto(); + issueTemplate.setProject_id(testResults.get(0).getProject_id()); + List issues = issueController.get(issueTemplate); + Integer count = assignIssuesToResults(issues, testResults); + Map results = new HashMap<>(); + results.put("Issues assigned", count); + return results; + } + + public Integer assignIssuesToResults(List issues, List testResults) + throws AqualityException { + Integer count = 0; + for (TestResultDto testResult : testResults) { + for (IssueDto issue : issues) { + if (issue.getExpression() != null + && RegexpUtil.match(testResult.getFail_reason(), issue.getExpression())) { + testResult.setIssue_id(issue.getId()); + this.create(testResult); + count++; + } + } + } + return count; + } + private void createPendingStepResults(TestResultDto template) throws AqualityException { Step2TestDto step2TestTemplate = new Step2TestDto(); step2TestTemplate.setProject_id(template.getProject_id()); @@ -133,7 +183,7 @@ private void createPendingStepResults(TestResultDto template) throws AqualityExc private List fillResults(List results) throws AqualityException { - if (results.size() > 0) { + if (!results.isEmpty()) { int projectId = results.get(0).getProject_id(); List finalResults = finalResultController.get(new FinalResultDto()); IssueDto issueDto = new IssueDto(); @@ -163,7 +213,7 @@ private List fillResults(List results) throws Aqua } private void fillResult(TestResultDto result, List finalResults, List tests, - List issues, List attachments, boolean isStepsEnabled) + List issues, List attachments, boolean isStepsEnabled) throws AqualityException { if (isStepsEnabled) { fillResultSteps(result); @@ -187,35 +237,9 @@ private void fillResultSteps(TestResultDto result) throws AqualityException { result.setSteps(stepResultController.get(stepResultTemplate)); } - public Map matchIssues(Integer testResultId) throws AqualityException { - TestResultDto testResultTemplate = new TestResultDto(); - testResultTemplate.setId(testResultId); - List testResults = this.getOnlyFailedResults(testResultTemplate); - if (testResults.isEmpty()) { - throw new AqualityParametersException("No test result found to update. Wrong ID might be provided."); - } - IssueDto issueTemplate = new IssueDto(); - issueTemplate.setProject_id(testResults.get(0).getProject_id()); - List issues = issueController.get(issueTemplate); - Integer count = assignIssuesToResults(issues, testResults); - Map results = new HashMap<>(); - results.put("Issues assigned", count); - return results; - } - - public Integer assignIssuesToResults(List issues, List testResults) - throws AqualityException { - Integer count = 0; - for (TestResultDto testResult : testResults) { - for (IssueDto issue : issues) { - if (issue.getExpression() != null - && RegexpUtil.match(testResult.getFail_reason(), issue.getExpression())) { - testResult.setIssue_id(issue.getId()); - this.create(testResult); - count++; - } - } + private void checkReadPermissions(Integer projectId) throws AqualityException { + if (!(baseUser.isFromGlobalManagement() || baseUser.getProjectUser(projectId).isViewer())) { + throw new AqualityPermissionsException("Account is not allowed to view Test Results", baseUser); } - return count; } } diff --git a/src/main/java/main/controllers/Project/TestController.java b/src/main/java/main/controllers/Project/TestController.java index ce7d292..fdc2ac9 100644 --- a/src/main/java/main/controllers/Project/TestController.java +++ b/src/main/java/main/controllers/Project/TestController.java @@ -30,45 +30,20 @@ public TestController(UserDto user) { } public TestDto create(TestDto template, boolean updateSuites) throws AqualityException { - if (baseUser.isManager() || baseUser.getProjectUser(template.getProject_id()).isEditor()) { - TestDto test = testDao.create(template); - if (updateSuites) { - test.setSuites(template.getSuites()); - updateSuites(test); - test = get(test).get(0); - } - return test; - } else { - throw new AqualityPermissionsException("Account is not allowed to create Test", baseUser); + checkCreatePermissions(template.getProject_id()); + TestDto test = testDao.create(template); + if (updateSuites) { + test.setSuites(template.getSuites()); + updateSuites(test); + test = get(test).get(0); } + return test; } public TestDto createOrUpdate(TestDto test) throws AqualityException { - TestDto searchTemplate = new TestDto(); - searchTemplate.setId(test.getId()); - searchTemplate.setProject_id(test.getProject_id()); - searchTemplate.setName(test.getName()); - - List existingTests = get(searchTemplate); - - if(!existingTests.isEmpty()) { - TestDto existingTest = existingTests.get(0); - if(existingTest.getSuites() != null) { - TestSuiteDto existingSuite = existingTest.getSuites().stream() - .filter(suite -> suite.getId().equals(test.getSuites().get(0).getId())) - .findFirst().orElse(null); - if(existingSuite == null) { - List listOfSuites = existingTest.getSuites(); - listOfSuites.add(test.getSuites().get(0)); - existingTest.setSuites(listOfSuites); - } - }else { - existingTest.setSuites(test.getSuites()); - } - return create(existingTest, true); - } else { - return create(test, true); - } + checkCreatePermissions(test.getProject_id()); + TestDto rawTest = getOrCreateRawTest(test); + return updateTestSuites(rawTest, test.getSuites().get(0).getId()); } @Override @@ -77,22 +52,15 @@ public TestDto create(TestDto template) throws AqualityException { } public List get(TestDto template) throws AqualityException { - if (baseUser.isFromGlobalManagement() || baseUser.getProjectUser(template.getProject_id()).isViewer()) { - return fillTests(testDao.searchAll(template)); - } else { - throw new AqualityPermissionsException("Account is not allowed to view Tests", baseUser); - } + checkReadPermissions(template.getProject_id()); + return fillTests(testDao.searchAll(template)); } public List get(Integer issueId, Integer projectId) throws AqualityException { - if (baseUser.isFromGlobalManagement() || baseUser.getProjectUser(projectId).isViewer()) { - return fillTests(testDao.getTestsAffectedByIssue(issueId)); - } else { - throw new AqualityPermissionsException("Account is not allowed to view Tests", baseUser); - } + checkReadPermissions(projectId); + return fillTests(testDao.getTestsAffectedByIssue(issueId)); } - @Override public boolean delete(TestDto template) throws AqualityException { if (baseUser.isManager() || baseUser.getProjectUser(template.getProject_id()).isEditor()) { @@ -103,7 +71,7 @@ public boolean delete(TestDto template) throws AqualityException { } public void updateMultipleTests(List entities) throws AqualityException { - if (entities.size() > 0 && (baseUser.isManager() || baseUser.getProjectUser(entities.get(0).getProject_id()).isEditor())) { + if (!entities.isEmpty() && (baseUser.isManager() || baseUser.getProjectUser(entities.get(0).getProject_id()).isEditor())) { for (TestDto test : entities) { updateSuites(test); } @@ -157,14 +125,12 @@ protected List getResultsToMove(TestDto from, TestDto to) { private List fillTests(List tests) throws AqualityException { List filledTests = new ArrayList<>(); - if (tests.size() > 0) { + if (!tests.isEmpty()) { Integer projectId = tests.get(0).getProject_id(); ProjectUserDto projectUserDto = new ProjectUserDto(); projectUserDto.setProject_id(tests.get(0).getProject_id()); List projectUsers = projectUserController.get(projectUserDto); - TestSuiteDto testSuiteDto = new TestSuiteDto(); - testSuiteDto.setProject_id(projectId); - List testSuites = suiteDao.searchAll(testSuiteDto); + List testSuites = getProjectTestSuites(projectId); ProjectDto projectDto = new ProjectDto(); projectDto.setId(tests.get(0).getProject_id()); @@ -189,7 +155,7 @@ private void updateSuites(TestDto test) throws AqualityException { Test2SuiteDto test2SuiteDto = new Test2SuiteDto(); test2SuiteDto.setTest_id(test.getId()); List oldSuites = test2SuiteController.get(test2SuiteDto); - if (test.getSuites() != null && test.getSuites().size() > 0) { + if (test.getSuites() != null && !test.getSuites().isEmpty()) { List suites = test.getSuites(); for (TestSuiteDto newSuite : suites) { Test2SuiteDto alreadyExists = oldSuites.stream().filter(x -> Objects.equals(x.getSuite_id(), newSuite.getId())).findAny().orElse(null); @@ -204,10 +170,58 @@ private void updateSuites(TestDto test) throws AqualityException { } } - if (oldSuites.size() > 0) { + if (!oldSuites.isEmpty()) { for (Test2SuiteDto oldSuite : oldSuites) { test2SuiteController.delete(oldSuite, test.getProject_id()); } } } + + private void checkReadPermissions(Integer projectId) throws AqualityException { + if (!(baseUser.isFromGlobalManagement() || baseUser.getProjectUser(projectId).isViewer())) { + throw new AqualityPermissionsException("Account is not allowed to view Tests", baseUser); + } + } + + private void checkCreatePermissions(Integer projectId) throws AqualityException { + if (!(baseUser.isFromGlobalManagement() || baseUser.getProjectUser(projectId).isEditor())) { + throw new AqualityPermissionsException("Account is not allowed to create Test", baseUser); + } + } + + private List getProjectTestSuites(Integer projectId) throws AqualityException { + TestSuiteDto testSuiteDto = new TestSuiteDto(); + testSuiteDto.setProject_id(projectId); + return suiteDao.searchAll(testSuiteDto); + } + + private TestDto getOrCreateRawTest(TestDto test) throws AqualityException { + TestDto searchTemplate = new TestDto(); + searchTemplate.setId(test.getId()); + searchTemplate.setProject_id(test.getProject_id()); + searchTemplate.setName(test.getName()); + + List existingTests = testDao.searchAll(searchTemplate); + + return existingTests.isEmpty() ? testDao.create(test) : existingTests.get(0); + } + + private TestDto updateTestSuites(TestDto testDto, Integer testSuiteId) throws AqualityException { + Integer projectId = testDto.getProject_id(); + Test2SuiteDto test2SuiteDto = new Test2SuiteDto(); + test2SuiteDto.setProject_id(projectId); + test2SuiteDto.setTest_id(testDto.getId()); + + List existingTest2Suites = test2SuiteController.get(test2SuiteDto); + if (existingTest2Suites.stream().noneMatch(test2Suite -> test2Suite.getSuite_id().equals(testSuiteId))) { + test2SuiteDto.setSuite_id(testSuiteId); + Test2SuiteDto createdTest2Suite = test2SuiteController.create(test2SuiteDto, projectId); + existingTest2Suites.add(createdTest2Suite); + } + + List projectTestSuites = getProjectTestSuites(projectId); + testDto.setSuites(test2SuiteController.convertToSuites(existingTest2Suites, projectTestSuites)); + + return testDto; + } } diff --git a/src/main/java/main/model/db/dao/DAO.java b/src/main/java/main/model/db/dao/DAO.java index b1dfbbe..607633b 100644 --- a/src/main/java/main/model/db/dao/DAO.java +++ b/src/main/java/main/model/db/dao/DAO.java @@ -229,7 +229,7 @@ protected JSONArray CallStoredProcedure(String sql, List> p return json; } - private T getSingleResult(List allResults, Integer id) throws AqualityException { + protected T getSingleResult(List allResults, Integer id) throws AqualityException { if (!allResults.isEmpty()) { return allResults.get(0); } else { diff --git a/src/main/java/main/model/db/dao/project/TestDao.java b/src/main/java/main/model/db/dao/project/TestDao.java index e71501c..9afe027 100644 --- a/src/main/java/main/model/db/dao/project/TestDao.java +++ b/src/main/java/main/model/db/dao/project/TestDao.java @@ -9,17 +9,18 @@ import java.util.List; public class TestDao extends DAO { + private static final String TESTS_AFFECTED_BY_ISSUE_QUERY = "{call SELECT_ISSUE_TESTS(?)}"; + public TestDao() { super(TestDto.class); select = "{call SELECT_TEST(?,?,?,?,?,?)}"; insert = "{call INSERT_TEST(?,?,?,?,?,?)}"; remove = "{call REMOVE_TEST(?)}"; } - private String testsAffectedByIssueQuery = "{call SELECT_ISSUE_TESTS(?)}"; public List getTestsAffectedByIssue(Integer issueId) throws AqualityException { List> parameters = new ArrayList<>(); parameters.add(new Pair<>("request_issue_id", issueId.toString())); - return dtoMapper.mapObjects(CallStoredProcedure(testsAffectedByIssueQuery, parameters).toString()); + return dtoMapper.mapObjects(CallStoredProcedure(TESTS_AFFECTED_BY_ISSUE_QUERY, parameters).toString()); } } diff --git a/src/main/java/main/model/db/dao/project/TestResultDao.java b/src/main/java/main/model/db/dao/project/TestResultDao.java index a9fc9d7..9df415d 100644 --- a/src/main/java/main/model/db/dao/project/TestResultDao.java +++ b/src/main/java/main/model/db/dao/project/TestResultDao.java @@ -4,12 +4,20 @@ import main.exceptions.AqualityException; import main.model.db.dao.DAO; import main.model.dto.project.TestResultDto; +import main.utils.DateUtils; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; +import java.util.Date; import java.util.List; public class TestResultDao extends DAO { + private static final String SYNC_SUITE_QUERY = "{call SELECT_LEGACY_RESULTS(?,?)}"; + private static final String SELECT_LATEST_RESULTS_BY_MILESTONE = "{call SELECT_LATEST_RESULTS_BY_MILESTONE(?)}"; + private static final String FINISH_TEST_RESULT_QUERY = + "{call UPDATE_TEST_RESULT_WITH_FINAL_RESULT_ID_AND_FAIL_REASON(?,?,?,?)}"; + public TestResultDao() { super(TestResultDto.class); select = "{call SELECT_TEST_RESULT(?,?,?,?,?,?,?,?,?,?)}"; @@ -17,26 +25,49 @@ public TestResultDao() { remove = "{call REMOVE_TEST_RESULT(?)}"; } - - private String syncSuiteQuery = "{call SELECT_LEGACY_RESULTS(?,?)}"; - private String latestResultsByMilestone = "{call SELECT_LATEST_RESULTS_BY_MILESTONE(?)}"; - /** * @param suiteId suite id for search * @param testId test id for search * @return all not executed results till first executed * @throws AqualityException */ - public List selectSuiteLegacyResults(@NotNull Integer suiteId, @NotNull Integer testId) throws AqualityException { + public List selectSuiteLegacyResults( + @NotNull Integer suiteId, + @NotNull Integer testId) throws AqualityException { List> parameters = new ArrayList<>(); parameters.add(new Pair<>("request_test_suite_id", suiteId.toString())); parameters.add(new Pair<>("request_test_id", testId.toString())); - return dtoMapper.mapObjects(CallStoredProcedure(syncSuiteQuery, parameters).toString()); + return dtoMapper.mapObjects(CallStoredProcedure(SYNC_SUITE_QUERY, parameters).toString()); } public List selectLatestResultsByMilestone(@NotNull Integer milestoneId) throws AqualityException { List> parameters = new ArrayList<>(); parameters.add(new Pair<>("request_milestone_id", milestoneId.toString())); - return dtoMapper.mapObjects(CallStoredProcedure(latestResultsByMilestone, parameters).toString()); + return dtoMapper.mapObjects(CallStoredProcedure(SELECT_LATEST_RESULTS_BY_MILESTONE, parameters).toString()); + } + + /** + * @param id test result id + * @param finalResultId ID of final result - Failed: 1, Passed: 2, Not Executed: 3, Pending: 5 + * @param failReason fail reason message + * @param finishDate test finish date + * @return updated test result + */ + public TestResultDto updateFinalResultIdAndFailReason( + @NotNull Integer id, + @NotNull Integer finalResultId, + String failReason, + Date finishDate) throws AqualityException { + List> parameters = new ArrayList<>(); + parameters.add(new Pair<>("request_id", id.toString())); + parameters.add(new Pair<>("request_final_result_id", finalResultId.toString())); + parameters.add(new Pair<>("request_fail_reason", failReason)); + parameters.add(new Pair<>( + "request_finish_date", + finishDate == null ? StringUtils.EMPTY : String.valueOf(DateUtils.toUnixTime(finishDate)))); + + return getSingleResult( + dtoMapper.mapObjects(CallStoredProcedure(FINISH_TEST_RESULT_QUERY, parameters).toString()), + id); } } diff --git a/src/main/java/main/utils/DateUtils.java b/src/main/java/main/utils/DateUtils.java index ca70bb7..6c147ce 100644 --- a/src/main/java/main/utils/DateUtils.java +++ b/src/main/java/main/utils/DateUtils.java @@ -7,6 +7,7 @@ import java.util.Date; public class DateUtils { + private static final int MILLISECONDS_PER_SECOND = 1000; public Date addMS(Date date, Integer ms) { @@ -64,4 +65,8 @@ public Date fromyyyyMMdd(String date){ return null; } } + + public static Long toUnixTime(Date date) { + return date != null ? date.getTime() / MILLISECONDS_PER_SECOND : null; + } } diff --git a/src/main/java/main/view/publicApi/PublicTestResultFinishServlet.java b/src/main/java/main/view/publicApi/PublicTestResultFinishServlet.java index 2990fb5..c6968e1 100644 --- a/src/main/java/main/view/publicApi/PublicTestResultFinishServlet.java +++ b/src/main/java/main/view/publicApi/PublicTestResultFinishServlet.java @@ -1,6 +1,7 @@ package main.view.publicApi; import main.Session; +import main.controllers.Project.ResultController; import main.exceptions.AqualityParametersException; import main.model.dto.project.TestResultDto; import main.view.BaseServlet; @@ -10,7 +11,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.util.Date; -import java.util.List; @WebServlet("/public/test/result/finish") public class PublicTestResultFinishServlet extends BaseServlet implements IPost { @@ -25,25 +25,12 @@ public void doPost(HttpServletRequest req, HttpServletResponse resp) { TestResultDto testResult = mapper.mapObject(TestResultDto.class, requestedJson); validatePost(testResult); + testResult.setFinish_date(new Date()); - TestResultDto testResultSearchTemplate = new TestResultDto(); - testResultSearchTemplate.setProject_id(testResult.getProject_id()); - testResultSearchTemplate.setId(testResult.getId()); + ResultController testResultController = session.controllerFactory.getHandler(testResult); + TestResultDto updatedTestResult = testResultController.updateWithFinalResultIdAndFailReason(testResult); - List oldResults = session.controllerFactory.getHandler(testResult).get(testResultSearchTemplate); - - if(oldResults.size() > 0) { - TestResultDto currentResult = oldResults.get(0); - currentResult.setFinal_result_id(testResult.getFinal_result_id()); - currentResult.setFail_reason(testResult.getFail_reason()); - currentResult.setFinish_date(new Date()); - - testResult = session.controllerFactory.getHandler(testResult).create(currentResult); - } else { - throw new AqualityParametersException("Test Result with %s id was not found!", testResult.getId()); - } - - setResponseBody(resp, testResult); + setResponseBody(resp, updatedTestResult); } catch (Exception e) { handleException(resp, e); } diff --git a/src/main/java/main/view/publicApi/PublicTestResultStartServlet.java b/src/main/java/main/view/publicApi/PublicTestResultStartServlet.java index 214b0fc..092b51c 100644 --- a/src/main/java/main/view/publicApi/PublicTestResultStartServlet.java +++ b/src/main/java/main/view/publicApi/PublicTestResultStartServlet.java @@ -26,11 +26,13 @@ public void doGet(HttpServletRequest req, HttpServletResponse resp) { validateGet(testResult); - List oldResults = session.controllerFactory.getHandler(testResult).get(testResult); + List oldResults = session.controllerFactory.getHandler(testResult).getRaw(testResult); - if(oldResults.size() > 0) { - TestResultDto pending = oldResults.stream().filter(result -> result.getPending().equals(1)).findFirst().orElse(null); - if(pending != null) { + if(!oldResults.isEmpty()) { + TestResultDto pending = oldResults.stream() + .filter(result -> result.getPending().equals(1)) + .findFirst().orElse(null); + if (pending != null) { testResult.setId(pending.getId()); } } diff --git a/src/main/java/main/view/publicApi/PublicTestServlet.java b/src/main/java/main/view/publicApi/PublicTestServlet.java index 8b13a2c..781bf42 100644 --- a/src/main/java/main/view/publicApi/PublicTestServlet.java +++ b/src/main/java/main/view/publicApi/PublicTestServlet.java @@ -41,8 +41,10 @@ private void validatePost(TestDto test) throws AqualityParametersException { throw new AqualityParametersException("You should specify 'id' or/and 'name' suite parameters!"); } - if(test.getSuites() == null || test.getSuites().size() != 1) { - throw new AqualityParametersException("You should specify 'suite' array with one element as {id: suite_id}. So the API will ensure this test is assigned to Suite."); + if(test.getSuites() == null || test.getSuites().size() != 1 || test.getSuites().get(0).getId() == null) { + throw new AqualityParametersException( + "You should specify 'suite' array with one element as {id: suite_id}. " + + "So the API will ensure this test is assigned to Suite."); } } diff --git a/src/main/resources/db_changelog/changelog.xml b/src/main/resources/db_changelog/changelog.xml index 4b5d986..31fdd41 100644 --- a/src/main/resources/db_changelog/changelog.xml +++ b/src/main/resources/db_changelog/changelog.xml @@ -38,4 +38,5 @@ + diff --git a/src/main/resources/db_changelog/db.changelog-1.5.1.xml b/src/main/resources/db_changelog/db.changelog-1.5.1.xml new file mode 100644 index 0000000..ffb324a --- /dev/null +++ b/src/main/resources/db_changelog/db.changelog-1.5.1.xml @@ -0,0 +1,115 @@ + + + + + + DROP procedure IF EXISTS `UPDATE_TEST_RESULT_WITH_FINAL_RESULT_ID_AND_FAIL_REASON`; + + # + + CREATE PROCEDURE `UPDATE_TEST_RESULT_WITH_FINAL_RESULT_ID_AND_FAIL_REASON`( + IN request_id VARCHAR(11), + IN request_final_result_id VARCHAR(11), + IN request_fail_reason mediumtext, + IN request_finish_date VARCHAR(500) + ) + BEGIN + UPDATE test_results + SET + finish_date = If(request_finish_date = '', finish_date, FROM_UNIXTIME(request_finish_date)), + final_result_updated = IF(request_final_result_id != final_result_id, NOW(), final_result_updated), + fail_reason = IF( + request_fail_reason = '', + fail_reason, + IF(request_fail_reason = '$blank', '', request_fail_reason) + ), + final_result_id = request_final_result_id, + updated = NOW() + WHERE id = request_id; + + SELECT * FROM test_results WHERE id = request_id; + END + + + + + + + + + + + + + DROP PROCEDURE IF EXISTS `INSERT_TEST_RESULT`; + + # + CREATE PROCEDURE `INSERT_TEST_RESULT`( + IN request_project_id VARCHAR(10), + IN request_id VARCHAR(10), + IN request_test_id VARCHAR(500), + IN request_final_result_id VARCHAR(500), + IN request_test_run_id VARCHAR(500), + IN request_log longtext, + IN request_debug VARCHAR(1), + IN request_finish_date VARCHAR(500), + IN request_start_date VARCHAR(500), + IN request_final_result_updated VARCHAR(500), + IN request_fail_reason mediumtext, + IN request_issue_id VARCHAR(11) + ) + BEGIN + INSERT INTO test_results ( + project_id, id, test_id, final_result_id, test_run_id, log, debug, start_date, + finish_date, final_result_updated, fail_reason, issue_id + ) + VALUES ( + request_project_id, + IF(request_id='', null, request_id), + request_test_id, + IF(request_final_result_id='',1,request_final_result_id), + IF(request_test_run_id = '', null, request_test_run_id), + IF(request_log = '', null, request_log), + IF(request_debug = '', 0, request_debug), + If(request_start_date = '', null, FROM_UNIXTIME(request_start_date)), + If(request_finish_date = '', null, FROM_UNIXTIME(request_finish_date)), + NOW(), + IF(request_fail_reason = '', null, request_fail_reason), + replace_empty(request_issue_id, null) + ) + ON DUPLICATE KEY UPDATE + test_id=IF(request_test_id = '',test_id,request_test_id), + log = IF(request_log = '', log, IF(request_log = '$blank', '', request_log)), + debug = IF(request_debug = '', debug, request_debug), + start_date = If(request_start_date = '', start_date, FROM_UNIXTIME(request_start_date)), + finish_date = If(request_finish_date = '', finish_date, FROM_UNIXTIME(request_finish_date)), + final_result_updated = IF( + request_final_result_id != final_result_id AND request_final_result_updated = '', + NOW(), + IF( + request_final_result_updated = '', + final_result_updated, + FROM_UNIXTIME(request_final_result_updated) + ) + ), + fail_reason = IF( + request_fail_reason = '', + fail_reason, + IF(request_fail_reason = '$blank', '', request_fail_reason) + ), + final_result_id = IF(request_final_result_id = '', final_result_id, request_final_result_id), + issue_id = apply_or_remove_id(request_issue_id, issue_id); + + SET @insert_id = IF(request_id = '', (SELECT LAST_INSERT_ID()), request_id); + + SELECT * FROM test_results WHERE id = @insert_id; + END + + + + + diff --git a/src/test/java/tests/workers/dao/project/TestResultDaoTest.java b/src/test/java/tests/workers/dao/project/TestResultDaoTest.java index f46cab4..ca34936 100644 --- a/src/test/java/tests/workers/dao/project/TestResultDaoTest.java +++ b/src/test/java/tests/workers/dao/project/TestResultDaoTest.java @@ -12,6 +12,7 @@ import tests.workers.dao.IDaoTest; import java.util.ArrayList; +import java.util.Date; import java.util.List; import static org.testng.Assert.assertEquals; @@ -62,6 +63,13 @@ public void selectLatestResultsByMilestoneTest() throws AqualityException { assertSQLToParams(currentSql, currentParameters); } + @Test + public void updateFinalResultIdAndFailReasonTest() throws AqualityException { + resultList.add(new TestResultDto()); + updateFinalResultIdAndFailReason(1, 1, "failReason", new Date()); + assertSQLToParams(currentSql, currentParameters); + } + @Override protected JSONArray CallStoredProcedure(String sql, List> parameters){ currentSql = sql;