Skip to content

Commit 6eaccd5

Browse files
authored
Merge pull request #803 from lasanthaDLPDS/master
Add last success column to the TG home page
2 parents 85cdac4 + 47c0b3b commit 6eaccd5

File tree

16 files changed

+262
-76
lines changed

16 files changed

+262
-76
lines changed

common/src/main/java/org/wso2/testgrid/common/Product.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.wso2.testgrid.common.util.StringUtil;
2222

2323
import java.io.Serializable;
24+
import java.sql.Timestamp;
2425
import java.util.ArrayList;
2526
import java.util.List;
2627
import javax.persistence.CascadeType;
@@ -71,6 +72,11 @@ public class Product extends AbstractUUIDEntity implements Serializable {
7172
@Column(name = "name", nullable = false, length = 50)
7273
private String name;
7374

75+
@Column(name = "last_success_timestamp")
76+
private Timestamp lastSuccessTimestamp;
77+
78+
@Column(name = "last_failure_timestamp")
79+
private Timestamp lastFailureTimestamp;
7480

7581
@OneToMany(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true)
7682
private List<DeploymentPattern> deploymentPatterns = new ArrayList<>();
@@ -111,6 +117,44 @@ public void setDeploymentPatterns(List<DeploymentPattern> deploymentPatterns) {
111117
this.deploymentPatterns = deploymentPatterns;
112118
}
113119

120+
/**
121+
* Returns the last success timestamp of the product build.
122+
*
123+
* @return timestamp
124+
*/
125+
public Timestamp getLastSuccessTimestamp() {
126+
return lastSuccessTimestamp == null ? null : new Timestamp(lastSuccessTimestamp.getTime());
127+
}
128+
129+
/**
130+
* Sets the last success timestamp of the product build.
131+
*
132+
* @param lastSuccessTimestamp timestamp
133+
*/
134+
public void setLastSuccessTimestamp(Timestamp lastSuccessTimestamp) {
135+
this.lastSuccessTimestamp =
136+
this.lastSuccessTimestamp == null ? null : new Timestamp(lastSuccessTimestamp.getTime());
137+
}
138+
139+
/**
140+
* Returns the last failure timestamp of the product build.
141+
*
142+
* @return timestamp
143+
*/
144+
public Timestamp getLastFailureTimestamp() {
145+
return lastFailureTimestamp == null ? null : new Timestamp(lastFailureTimestamp.getTime());
146+
}
147+
148+
/**
149+
* Sets the last failure timestamp of the product build.
150+
*
151+
* @param lastFailureTimestamp timestamp
152+
*/
153+
public void setLastFailureTimestamp(Timestamp lastFailureTimestamp) {
154+
this.lastFailureTimestamp =
155+
this.lastFailureTimestamp == null ? null : new Timestamp(lastFailureTimestamp.getTime());
156+
}
157+
114158
@Override
115159
public String toString() {
116160
String id = this.getId() != null ? this.getId() : "";
@@ -121,6 +165,8 @@ public String toString() {
121165
", name='", name, "\'",
122166
", createdTimestamp='", createdTimestamp, "\'",
123167
", modifiedTimestamp='", modifiedTimestamp, "\'",
168+
", lastSuccessTimestamp='", lastSuccessTimestamp, "\'",
169+
", lastFailureTimestamp='", lastFailureTimestamp, "\'",
124170
'}');
125171
}
126172
}

core/src/main/java/org/wso2/testgrid/core/command/FinalizeRunTestplan.java

Lines changed: 82 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,24 @@
2525
import org.wso2.testgrid.common.TestPlan;
2626
import org.wso2.testgrid.common.TestScenario;
2727
import org.wso2.testgrid.common.exception.CommandExecutionException;
28+
import org.wso2.testgrid.common.exception.TestGridException;
2829
import org.wso2.testgrid.common.util.FileUtil;
2930
import org.wso2.testgrid.common.util.TestGridUtil;
3031
import org.wso2.testgrid.dao.TestGridDAOException;
32+
import org.wso2.testgrid.dao.uow.ProductUOW;
3133
import org.wso2.testgrid.dao.uow.TestPlanUOW;
3234
import org.wso2.testgrid.logging.plugins.LogFilePathLookup;
3335

3436
import java.io.IOException;
37+
import java.nio.file.Files;
38+
import java.nio.file.Path;
3539
import java.nio.file.Paths;
3640
import java.util.ArrayList;
41+
import java.util.Iterator;
3742
import java.util.List;
3843
import java.util.Optional;
44+
import java.util.stream.Collectors;
45+
import java.util.stream.Stream;
3946

4047
/**
4148
* Resolves the invalid statuses caused by any failures.
@@ -57,22 +64,28 @@ public class FinalizeRunTestplan implements Command {
5764
aliases = { "-f" })
5865
private String testPlanYamlFilePath = "";
5966

67+
@Option(name = "--workspace",
68+
usage = "Workspace Of The Job",
69+
aliases = { "-w" })
70+
private String workspace = "";
71+
6072
private TestPlanUOW testPlanUOW;
73+
private ProductUOW productUOW;
6174
private List<TestPlan> testPlans;
6275

6376
public FinalizeRunTestplan() {
6477
testPlanUOW = new TestPlanUOW();
78+
productUOW = new ProductUOW();
6579
}
6680

6781
@Override
6882
public void execute() throws CommandExecutionException {
6983

7084
LogFilePathLookup.setLogFilePath(
7185
TestGridUtil.deriveTestGridLogFilePath(productName, TestGridConstants.TESTGRID_LOG_FILE_NAME));
72-
73-
if (Paths.get(testPlanYamlFilePath).toFile().exists()) {
74-
//Read test plan id from test-plan yaml file
75-
try {
86+
try {
87+
if (Paths.get(testPlanYamlFilePath).toFile().exists()) {
88+
//Read test plan id from test-plan yaml file
7689
TestPlan testPlan = FileUtil.readYamlFile(testPlanYamlFilePath, TestPlan.class);
7790
Optional<TestPlan> testPlanEntity = testPlanUOW.getTestPlanById(testPlan.getId());
7891
if (testPlanEntity.isPresent()) {
@@ -81,21 +94,17 @@ public void execute() throws CommandExecutionException {
8194
} else {
8295
testPlans = testPlanUOW.getTestPlansOlderThan(TIME_DURATION, TIME_UNIT);
8396
}
84-
} catch (IOException e) {
85-
logger.error("Error occurred while trying to read " + testPlanYamlFilePath);
86-
} catch (TestGridDAOException e) {
87-
logger.error("Error while fetching test plan from database.");
97+
98+
} else {
99+
testPlans = testPlanUOW.getTestPlansOlderThan(TIME_DURATION, TIME_UNIT);
88100
}
89-
} else {
90-
testPlans = testPlanUOW.getTestPlansOlderThan(TIME_DURATION, TIME_UNIT);
91-
}
92101

93-
logger.info("Finalizing test plan status...");
94-
boolean isExistsFailedScenarios = false;
95-
for (TestPlan testPlan : testPlans) {
96-
//Set statuses of scenarios
97-
for (TestScenario testScenario : testPlan.getTestScenarios()) {
98-
switch (testScenario.getStatus()) {
102+
logger.info("Finalizing test plan status...");
103+
boolean isExistsFailedScenarios = false;
104+
for (TestPlan testPlan : testPlans) {
105+
//Set statuses of scenarios
106+
for (TestScenario testScenario : testPlan.getTestScenarios()) {
107+
switch (testScenario.getStatus()) {
99108
case PENDING:
100109
testScenario.setStatus(Status.DID_NOT_RUN);
101110
break;
@@ -109,25 +118,34 @@ public void execute() throws CommandExecutionException {
109118
break;
110119
default:
111120
break;
121+
}
112122
}
113-
}
114-
//Set statuses of testplans
115-
switch (testPlan.getStatus()) {
123+
//Set statuses of testplans
124+
switch (testPlan.getStatus()) {
116125
case PENDING:
117126
testPlan.setStatus(Status.DID_NOT_RUN);
118127
persistTestPlan(testPlan);
119128
break;
120129
case RUNNING:
121130
if (isExistsFailedScenarios) {
122131
testPlan.setStatus(Status.FAIL);
132+
isExistsFailedScenarios = false;
123133
} else {
124134
testPlan.setStatus(Status.INCOMPLETE);
125135
}
126136
persistTestPlan(testPlan);
127137
break;
128138
default:
129139
break;
140+
}
130141
}
142+
updateProductStatus();
143+
} catch (IOException e) {
144+
logger.error("Error occurred while trying to read " + testPlanYamlFilePath, e);
145+
} catch (TestGridDAOException e) {
146+
logger.error("Error while fetching test plan from database.", e);
147+
} catch (TestGridException e) {
148+
logger.error("Error occured while updating the product status.", e);
131149
}
132150
}
133151

@@ -143,4 +161,48 @@ private void persistTestPlan(TestPlan testPlan) {
143161
logger.error("Error occurred while persisting the test plan. ", e);
144162
}
145163
}
164+
165+
/**
166+
* Update the last success timestamp of the product build or last failure timestamp of the product build
167+
* by considering status of test plans.
168+
*
169+
*/
170+
private void updateProductStatus() throws TestGridException {
171+
Path source = Paths.get(workspace, "test-plans");
172+
String productId;
173+
Boolean isCompleteBuild = true;
174+
try (Stream<Path> stream = Files.list(source).filter(Files::isRegularFile)) {
175+
List<Path> paths = stream.sorted().collect(Collectors.toList());
176+
for (Iterator<Path> iterator = paths.iterator(); iterator.hasNext(); ) {
177+
Path path = iterator.next();
178+
if (!path.toFile().exists()) {
179+
throw new TestGridException(
180+
"Test Plan File doesn't exist. File path is " + path.toAbsolutePath().toString());
181+
}
182+
TestPlan testPlan = FileUtil.readYamlFile(path.toAbsolutePath().toString(), TestPlan.class);
183+
Optional<TestPlan> testPlanEntity = testPlanUOW.getTestPlanById(testPlan.getId());
184+
if (testPlanEntity.isPresent()) {
185+
if (Status.FAIL.equals(testPlanEntity.get().getStatus())) {
186+
productId = testPlanEntity.get().getDeploymentPattern().getProduct().getId();
187+
productUOW.updateProductStatusTimestamp(Status.FAIL, productId);
188+
break;
189+
} else if ((Status.DID_NOT_RUN.equals(testPlanEntity.get().getStatus()) || Status.INCOMPLETE
190+
.equals(testPlanEntity.get().getStatus())) && isCompleteBuild) {
191+
isCompleteBuild = false;
192+
}
193+
} else {
194+
throw new TestGridException(
195+
"Test Plan doesn't exist in the TG database. Test Plan id: " + testPlan.getId());
196+
}
197+
if (!iterator.hasNext() && isCompleteBuild) {
198+
productId = testPlanEntity.get().getDeploymentPattern().getProduct().getId();
199+
productUOW.updateProductStatusTimestamp(Status.SUCCESS, productId);
200+
}
201+
}
202+
} catch (TestGridDAOException e) {
203+
logger.error("Error occured when updating the product table of TG", e);
204+
} catch (IOException e) {
205+
logger.error("Error occured when reading a test plan yaml file", e);
206+
}
207+
}
146208
}

dao/src/main/java/org/wso2/testgrid/dao/repository/ProductRepository.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,15 @@
2020
import com.google.common.collect.LinkedListMultimap;
2121
import org.wso2.testgrid.common.Product;
2222
import org.wso2.testgrid.common.ProductTestStatus;
23+
import org.wso2.testgrid.common.Status;
2324
import org.wso2.testgrid.common.util.StringUtil;
2425
import org.wso2.testgrid.dao.EntityManagerHelper;
2526
import org.wso2.testgrid.dao.SortOrder;
2627
import org.wso2.testgrid.dao.TestGridDAOException;
2728

2829
import java.sql.Timestamp;
2930
import java.util.ArrayList;
31+
import java.util.Date;
3032
import java.util.List;
3133
import java.util.Map;
3234
import javax.persistence.EntityManager;
@@ -147,4 +149,29 @@ private List<ProductTestStatus> getProductTestStatuses(List<Object[]> results) {
147149
}
148150
return productTestStatuses;
149151
}
152+
153+
/**
154+
* This method updates the last_success_timestamp column or last_failure_timestamp column with given timestamp.
155+
* The column is selected by considering product status.
156+
* ex:- UPDATE product SET last_failure_timestamp = <timestamp> where id = <product_id>;
157+
*
158+
* @param status Status of the product
159+
* @param timestamp Current timestamp
160+
* @param productId Id of the product
161+
*/
162+
public void updateProductStatusTimestamp(Status status, Date timestamp, String productId) {
163+
String queryStr = "UPDATE product SET ";
164+
if (status.equals(Status.SUCCESS)) {
165+
queryStr += "last_success_timestamp = ";
166+
} else if (status.equals(Status.FAIL)) {
167+
queryStr += "last_failure_timestamp = ";
168+
}
169+
170+
// Begin entity manager transaction
171+
entityManager.getTransaction().begin();
172+
entityManager.createNativeQuery(
173+
StringUtil.concatStrings(queryStr, "'", timestamp, "' where id = '", productId, "';")).executeUpdate();
174+
// Commit transaction
175+
entityManager.getTransaction().commit();
176+
}
150177
}

dao/src/main/java/org/wso2/testgrid/dao/uow/ProductUOW.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
import org.wso2.testgrid.common.Product;
2121
import org.wso2.testgrid.common.ProductTestStatus;
22+
import org.wso2.testgrid.common.Status;
2223
import org.wso2.testgrid.dao.EntityManagerHelper;
2324
import org.wso2.testgrid.dao.TestGridDAOException;
2425
import org.wso2.testgrid.dao.repository.ProductRepository;
@@ -110,4 +111,14 @@ public Product persistProduct(String name) throws TestGridDAOException {
110111
public List<ProductTestStatus> getProductTestHistory(Timestamp date) throws TestGridDAOException {
111112
return productRepository.getProductTestHistory(date);
112113
}
114+
115+
/**
116+
* This method update the last success timestamp or last failure timestamp according to the product status.
117+
*
118+
* @param status status of the product
119+
* @param productId Id of the product
120+
*/
121+
public void updateProductStatusTimestamp(Status status, String productId) throws TestGridDAOException {
122+
productRepository.updateProductStatusTimestamp(status, new Timestamp(System.currentTimeMillis()), productId);
123+
}
113124
}

jenkins/pipelines/test-jobs/wso2apim-2.1.0-LTS/Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pipeline {
140140
sh """
141141
cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
142142
./testgrid finalize-run-testplan \
143-
--product ${PRODUCT}
143+
--product ${PRODUCT --workspace ${PWD}}
144144
"""
145145

146146
sh """

jenkins/pipelines/test-jobs/wso2apim-2.2.0-LTS/Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ pipeline {
133133
sh """
134134
cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
135135
./testgrid finalize-run-testplan \
136-
--product ${PRODUCT}
136+
--product ${PRODUCT} --workspace ${PWD}
137137
"""
138138

139139
sh """

jenkins/pipelines/test-jobs/wso2ei-6.1.1-LTS/Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ pipeline {
126126
sh """
127127
cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
128128
./testgrid finalize-run-testplan \
129-
--product ${PRODUCT}
129+
--product ${PRODUCT} --workspace ${PWD}
130130
"""
131131

132132
sh """

jenkins/pipelines/test-jobs/wso2is-5.3.0-LTS/Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ pipeline {
125125
sh """
126126
cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
127127
./testgrid finalize-run-testplan \
128-
--product ${PRODUCT}
128+
--product ${PRODUCT} --workspace ${PWD}
129129
"""
130130

131131
sh """

jenkins/pipelines/test-jobs/wso2is-5.5.0-LTS/Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ pipeline {
126126
sh """
127127
cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
128128
./testgrid finalize-run-testplan \
129-
--product ${PRODUCT}
129+
--product ${PRODUCT} --workspace ${PWD}
130130
"""
131131

132132
sh """

jenkins/pipelines/test-jobs/wso2is5.4.0LTS/Jenkinsfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ pipeline {
125125
sh """
126126
cd ${TESTGRID_HOME}/testgrid-dist/${TESTGRID_NAME}
127127
./testgrid finalize-run-testplan \
128-
--product ${PRODUCT}
128+
--product ${PRODUCT} --workspace ${PWD}
129129
"""
130130

131131
sh """

0 commit comments

Comments
 (0)