diff --git a/.gitignore b/.gitignore
index 4a93177f0..960e65c8d 100755
--- a/.gitignore
+++ b/.gitignore
@@ -42,7 +42,7 @@ tank_vmManager/settings.xml
tank.mwb
agent/http_client_3/settings.xml
agent/http_client_4/settings.xml
-agent/ok_http_client/settings.xml
+agent/http_client_jdk/settings.xml
# Byte-compiled / optimized / DLL files
__pycache__/
diff --git a/agent/agent_common/src/main/java/com/intuit/tank/http/BaseResponse.java b/agent/agent_common/src/main/java/com/intuit/tank/http/BaseResponse.java
index 786e930ae..ea11fb8af 100644
--- a/agent/agent_common/src/main/java/com/intuit/tank/http/BaseResponse.java
+++ b/agent/agent_common/src/main/java/com/intuit/tank/http/BaseResponse.java
@@ -74,11 +74,22 @@ public String getLogMsg() {
}
this.responseLogMsg = sb.toString();
} catch (Exception ex) {
- LOG.error("Error processing response: " + ex.getMessage(), ex);
+ LOG.error("Error processing response: {}", ex.getMessage(), ex);
}
return responseLogMsg;
}
+ public String convertToCSV() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(this.httpCode).append(",");
+ sb.append(this.rspMessage).append(",");
+ sb.append(responseTime).append(",");
+ sb.append(getResponseSize()).append(",");
+ headers.forEach((key, value) -> sb.append(key).append(" = ").append(value.replace(",", "")).append(","));
+ cookies.forEach((key, value) -> sb.append(key).append(" = ").append(value).append(","));
+ return sb.toString();
+ }
+
/**
* Common codes are 200 OK, 202 accepted, 204 no content, 400 bad request,
* 404 not found, 500 internal server error, 503 Service Unavailable
diff --git a/agent/agent_startup_pkg/tank_agent/startAgent.sh b/agent/agent_startup_pkg/tank_agent/startAgent.sh
index 3b799d01a..be2a8aca0 100755
--- a/agent/agent_startup_pkg/tank_agent/startAgent.sh
+++ b/agent/agent_startup_pkg/tank_agent/startAgent.sh
@@ -1,4 +1,4 @@
#!/bin/sh
vm_arguments="-Dnetworkaddress.cache.ttl=5 -Dnetworkaddress.cache.negative.ttl=0";
-java -cp apiharness-1.0-all.jar $2 $vm_arguments com.intuit.tank.harness.APITestHarness $1
+java -cp apiharness-1.0-all.jar "${@:2}" $vm_arguments com.intuit.tank.harness.APITestHarness $1
echo DONE
diff --git a/agent/http_client_4/src/main/java/com/intuit/tank/httpclient4/TankHttpClient4.java b/agent/http_client_4/src/main/java/com/intuit/tank/httpclient4/TankHttpClient4.java
index 838e18cfa..5196e9bd9 100644
--- a/agent/http_client_4/src/main/java/com/intuit/tank/httpclient4/TankHttpClient4.java
+++ b/agent/http_client_4/src/main/java/com/intuit/tank/httpclient4/TankHttpClient4.java
@@ -95,6 +95,7 @@ public Object createHttpClient() {
UserTokenHandler userTokenHandler = (httpContext) -> httpContext.getAttribute(HttpClientContext.USER_TOKEN);
// default this implementation will create no more than than 2 concurrent connections per given route and no more 20 connections in total
return HttpClients.custom()
+ .setConnectionManagerShared(true)
.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
.setUserTokenHandler(userTokenHandler)
.evictIdleConnections(1L, TimeUnit.MINUTES)
diff --git a/api/src/main/resources/settings.xml b/api/src/main/resources/settings.xml
index 87adc28c1..d1459f751 100644
--- a/api/src/main/resources/settings.xml
+++ b/api/src/main/resources/settings.xml
@@ -212,11 +212,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/api/src/test/resources/settings.xml b/api/src/test/resources/settings.xml
index fdcba513c..1c0df9472 100644
--- a/api/src/test/resources/settings.xml
+++ b/api/src/test/resources/settings.xml
@@ -212,11 +212,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/assets/settings-all-in-one.xml b/assets/settings-all-in-one.xml
index 15d8bd18f..e0fa37a74 100644
--- a/assets/settings-all-in-one.xml
+++ b/assets/settings-all-in-one.xml
@@ -163,11 +163,11 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/aws-config/tank_agent.yml b/aws-config/tank_agent.yml
index beede6806..735ce1db6 100644
--- a/aws-config/tank_agent.yml
+++ b/aws-config/tank_agent.yml
@@ -11,7 +11,7 @@ Parameters:
InstanceType:
Description: Amazon EC2 instance type
Type: 'String'
- Default: 'c5.large'
+ Default: 'm8g.large'
KeyName:
Type: 'AWS::EC2::KeyPair::KeyName'
Description: Amazon EC2 Key Pair
diff --git a/pom.xml b/pom.xml
index 0ea2337ac..eb8ab0022 100644
--- a/pom.xml
+++ b/pom.xml
@@ -30,10 +30,10 @@
self_signed_tank.p12
6.5.1.Final
- 2.25.56
- 2.15.3
+ 2.29.35
+ 2.18.2
- 11.0.1
+ 11.0.2
5.1.3.Final
4.1.0
diff --git a/proxy-parent/owasp-proxy/pom.xml b/proxy-parent/owasp-proxy/pom.xml
index 7d6fbd1e3..e3e90dafd 100755
--- a/proxy-parent/owasp-proxy/pom.xml
+++ b/proxy-parent/owasp-proxy/pom.xml
@@ -32,14 +32,14 @@
org.bouncycastle
- bcprov-jdk15on
- 1.47
+ bcprov-jdk18on
+ 1.79
org.bouncycastle
- bcpkix-jdk15on
- 1.47
+ bcpkix-jdk18on
+ 1.79
org.apache.httpcomponents
@@ -48,7 +48,7 @@
org.springframework
spring-jdbc
- 2.5.6
+ 6.2.0
compile
diff --git a/proxy-parent/owasp-proxy/src/main/java/org/owasp/proxy/http/dao/JdbcMessageDAO.java b/proxy-parent/owasp-proxy/src/main/java/org/owasp/proxy/http/dao/JdbcMessageDAO.java
index 024f3b981..74fd79ef8 100644
--- a/proxy-parent/owasp-proxy/src/main/java/org/owasp/proxy/http/dao/JdbcMessageDAO.java
+++ b/proxy-parent/owasp-proxy/src/main/java/org/owasp/proxy/http/dao/JdbcMessageDAO.java
@@ -42,10 +42,10 @@
import org.springframework.dao.DataAccessException;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcDaoSupport;
-import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
-import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
@@ -66,11 +66,11 @@ public class JdbcMessageDAO extends NamedParameterJdbcDaoSupport implements
private static final String RESPONSE_HEADER_TIME = "headerTime";
private static final String RESPONSE_CONTENT_TIME = "contentTime";
- private static final ParameterizedRowMapper REQUEST_MAPPER = new RequestMapper();
- private static final ParameterizedRowMapper RESPONSE_MAPPER = new ResponseMapper();
- private static final ParameterizedRowMapper CONTENT_MAPPER = new ContentMapper();
- private static final ParameterizedRowMapper ID_MAPPER = new IdMapper();
- private static final ParameterizedRowMapper CONVERSATION_MAPPER = new ConversationMapper();
+ private static final RowMapper REQUEST_MAPPER = new RequestMapper();
+ private static final RowMapper RESPONSE_MAPPER = new ResponseMapper();
+ private static final RowMapper CONTENT_MAPPER = new ContentMapper();
+ private static final RowMapper ID_MAPPER = new IdMapper();
+ private static final RowMapper CONVERSATION_MAPPER = new ConversationMapper();
private final static String INSERT_CONTENT = "INSERT INTO contents (content, size) VALUES (:content, :size)";
@@ -188,9 +188,8 @@ public Collection listConversationsSince(int id)
MapSqlParameterSource params = new MapSqlParameterSource();
try {
params.addValue(ID, id, Types.INTEGER);
- SimpleJdbcTemplate template = new SimpleJdbcTemplate(
- getNamedParameterJdbcTemplate());
- return template.query(SELECT_CONVERSATIONS, ID_MAPPER, params);
+ NamedParameterJdbcTemplate template = getNamedParameterJdbcTemplate();
+ return template.query(SELECT_CONVERSATIONS, params, ID_MAPPER);
} catch (EmptyResultDataAccessException erdae) {
return Collections.emptyList();
}
@@ -205,9 +204,8 @@ public int getMessageContentId(int headerId) throws DataAccessException {
try {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue(ID, headerId, Types.INTEGER);
- SimpleJdbcTemplate template = new SimpleJdbcTemplate(
- getNamedParameterJdbcTemplate());
- return template.queryForInt(SELECT_CONTENT_ID, params);
+ NamedParameterJdbcTemplate template = getNamedParameterJdbcTemplate();
+ return template.queryForObject(SELECT_CONTENT_ID, params, Integer.class);
} catch (EmptyResultDataAccessException erdae) {
return -1;
}
@@ -222,9 +220,8 @@ public int getMessageContentSize(int id) throws DataAccessException {
try {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue(ID, id, Types.INTEGER);
- SimpleJdbcTemplate template = new SimpleJdbcTemplate(
- getNamedParameterJdbcTemplate());
- return template.queryForInt(SELECT_CONTENT_SIZE, params);
+ NamedParameterJdbcTemplate template = getNamedParameterJdbcTemplate();
+ return template.queryForObject(SELECT_CONTENT_SIZE, params, Integer.class);
} catch (EmptyResultDataAccessException erdae) {
return -1;
}
@@ -239,10 +236,8 @@ public Conversation getConversation(int id) throws DataAccessException {
try {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue(ID, id, Types.INTEGER);
- SimpleJdbcTemplate template = new SimpleJdbcTemplate(
- getNamedParameterJdbcTemplate());
- return template.queryForObject(SELECT_SUMMARY, CONVERSATION_MAPPER,
- params);
+ NamedParameterJdbcTemplate template = getNamedParameterJdbcTemplate();
+ return template.queryForObject(SELECT_SUMMARY, params, CONVERSATION_MAPPER);
} catch (EmptyResultDataAccessException erdae) {
return null;
}
@@ -286,10 +281,8 @@ public byte[] loadMessageContent(int id) throws DataAccessException {
try {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue(ID, id, Types.INTEGER);
- SimpleJdbcTemplate template = new SimpleJdbcTemplate(
- getNamedParameterJdbcTemplate());
- return template.queryForObject(SELECT_CONTENT, CONTENT_MAPPER,
- params);
+ NamedParameterJdbcTemplate template = getNamedParameterJdbcTemplate();
+ return template.queryForObject(SELECT_CONTENT, params, CONTENT_MAPPER);
} catch (EmptyResultDataAccessException erdae) {
return null;
}
@@ -319,10 +312,8 @@ public RequestHeader loadRequestHeader(int id) throws DataAccessException {
MapSqlParameterSource params = new MapSqlParameterSource();
try {
params.addValue(ID, id, Types.INTEGER);
- SimpleJdbcTemplate template = new SimpleJdbcTemplate(
- getNamedParameterJdbcTemplate());
- return template.queryForObject(SELECT_REQUEST, REQUEST_MAPPER,
- params);
+ NamedParameterJdbcTemplate template = getNamedParameterJdbcTemplate();
+ return template.queryForObject(SELECT_REQUEST, params, REQUEST_MAPPER);
} catch (EmptyResultDataAccessException erdae) {
return null;
}
@@ -354,10 +345,8 @@ public MutableResponseHeader loadResponseHeader(int id)
try {
MapSqlParameterSource params = new MapSqlParameterSource();
params.addValue(ID, id, Types.INTEGER);
- SimpleJdbcTemplate template = new SimpleJdbcTemplate(
- getNamedParameterJdbcTemplate());
- return template.queryForObject(SELECT_RESPONSE, RESPONSE_MAPPER,
- params);
+ NamedParameterJdbcTemplate template = getNamedParameterJdbcTemplate();
+ return template.queryForObject(SELECT_RESPONSE, params, RESPONSE_MAPPER);
} catch (EmptyResultDataAccessException erdae) {
return null;
}
@@ -478,7 +467,7 @@ private void saveMessageHeader(MutableMessageHeader header, int contentId) {
}
private static class RequestMapper implements
- ParameterizedRowMapper {
+ RowMapper {
public MutableBufferedRequest mapRow(ResultSet rs, int rowNum)
throws SQLException {
@@ -504,7 +493,7 @@ public MutableBufferedRequest mapRow(ResultSet rs, int rowNum)
}
private static class ResponseMapper implements
- ParameterizedRowMapper {
+ RowMapper {
public MutableBufferedResponse mapRow(ResultSet rs, int rowNum)
throws SQLException {
@@ -529,14 +518,14 @@ public MutableBufferedResponse mapRow(ResultSet rs, int rowNum)
}
private static class ContentMapper implements
- ParameterizedRowMapper {
+ RowMapper {
public byte[] mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getBytes(CONTENT);
}
}
- private static class IdMapper implements ParameterizedRowMapper {
+ private static class IdMapper implements RowMapper {
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
return Integer.valueOf(rs.getInt(ID));
@@ -544,7 +533,7 @@ public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
}
private static class ConversationMapper implements
- ParameterizedRowMapper {
+ RowMapper {
public Conversation mapRow(ResultSet rs, int rowNum)
throws SQLException {
diff --git a/proxy-parent/owasp-proxy/src/main/java/org/owasp/proxy/util/BouncyCastleCertificateUtils.java b/proxy-parent/owasp-proxy/src/main/java/org/owasp/proxy/util/BouncyCastleCertificateUtils.java
index 4cd25d7da..5aa559ad4 100644
--- a/proxy-parent/owasp-proxy/src/main/java/org/owasp/proxy/util/BouncyCastleCertificateUtils.java
+++ b/proxy-parent/owasp-proxy/src/main/java/org/owasp/proxy/util/BouncyCastleCertificateUtils.java
@@ -34,14 +34,10 @@
import javax.security.auth.x500.X500Principal;
-import org.bouncycastle.asn1.x509.BasicConstraints;
-import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
-import org.bouncycastle.asn1.x509.KeyPurposeId;
-import org.bouncycastle.asn1.x509.X509Extensions;
+import org.bouncycastle.asn1.x509.*;
import org.bouncycastle.jce.X509KeyUsage;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.bouncycastle.x509.extension.AuthorityKeyIdentifierStructure;
-import org.bouncycastle.x509.extension.SubjectKeyIdentifierStructure;
@SuppressWarnings("deprecation")
public class BouncyCastleCertificateUtils {
@@ -116,7 +112,7 @@ private static void addCertificateExtensions(PublicKey pubKey,
// new SubjectKeyIdentifierExtension(new KeyIdentifier(pubKey)
// .getIdentifier()));
certGen.addExtension(X509Extensions.SubjectKeyIdentifier, false,
- new SubjectKeyIdentifierStructure(pubKey));
+ SubjectKeyIdentifier.getInstance(pubKey));
//
// ext.set(AuthorityKeyIdentifierExtension.NAME,
// new AuthorityKeyIdentifierExtension(
diff --git a/rest-mvc/impl/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/JobController.java b/rest-mvc/impl/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/JobController.java
index 011791b41..eb361e860 100644
--- a/rest-mvc/impl/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/JobController.java
+++ b/rest-mvc/impl/src/main/java/com/intuit/tank/rest/mvc/rest/controllers/JobController.java
@@ -89,7 +89,7 @@ public ResponseEntity getJobsByProject(@PathVariable @Parameter(de
" - passing only projectName creates jobs named: '{projectName}_{total_users}\\_users\\_{timestamp}' \n\n" +
" - rampTime and simulationTime are accepted as time strings i.e 60s, 12m, 24h \n\n" +
" - stopBehavior is matched against accepted values ( END_OF_STEP, END_OF_SCRIPT, END_OF_SCRIPT_GROUP, END_OF_TEST ) \n\n" +
- " - vmInstance matches against AWS EC2 Instance Types i.e c5.large, c5.xlarge, etc \n\n"+
+ " - vmInstance matches against AWS EC2 Instance Types i.e m8g.large, m8g.xlarge, etc \n\n"+
" - workloadType can be set to increasing (linear workload) or standard (nonlinear workload) \n\n"+
" - targetRampRate, targetRatePerAgent, and jobRegions.percentage fields apply to standard workloadType jobs (nonlinear) \n\n"+
" - projectId, userIntervalIncrement and numUsersPerAgent are accepted as integers \n\n" +
diff --git a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/ActionComponents.java b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/ActionComponents.java
index 2f8a9f2e8..23ec6013b 100644
--- a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/ActionComponents.java
+++ b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/ActionComponents.java
@@ -185,6 +185,8 @@ private void createToolBar(JComboBox testPlanChooser, JComboBox step.getResponse() != null)
+ .map(step -> step.getRequest().getRequestUrl() + "," + step.getResponse().convertToCSV())
+ .forEach(pw::println);
+ } catch ( FileNotFoundException e) {
+ LOG.error("Error exporting CSV: {}", String.valueOf(e));
+ }
+ }
+
}
diff --git a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java
index a62692e25..17ead38f8 100644
--- a/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java
+++ b/tools/agent_debugger/src/main/java/com/intuit/tank/tools/debugger/PanelBuilder.java
@@ -184,7 +184,7 @@ static Component createContentPanel(final AgentDebuggerFrame frame) {
public void mousePressed(MouseEvent e) {
scriptEditorTA.grabFocus();
try {
- int offs = scriptEditorTA.viewToModel(e.getPoint());
+ int offs = scriptEditorTA.viewToModel2D(e.getPoint());
if (offs > -1) {
int line = scriptEditorTA.getLineOfOffset(offs);
if (frame.getSteps().size() > line) {
diff --git a/tools/agent_debugger/src/main/resources/gfx/16/database_table.png b/tools/agent_debugger/src/main/resources/gfx/16/database_table.png
new file mode 100644
index 000000000..03c52ee23
Binary files /dev/null and b/tools/agent_debugger/src/main/resources/gfx/16/database_table.png differ
diff --git a/web/web_support/src/main/java/com/intuit/tank/project/JobMaker.java b/web/web_support/src/main/java/com/intuit/tank/project/JobMaker.java
index de4bfe26e..f266cef82 100644
--- a/web/web_support/src/main/java/com/intuit/tank/project/JobMaker.java
+++ b/web/web_support/src/main/java/com/intuit/tank/project/JobMaker.java
@@ -47,7 +47,6 @@
import com.intuit.tank.util.TestParameterContainer;
import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent;
import com.intuit.tank.vm.api.enumerated.TerminationPolicy;
-import com.intuit.tank.vm.common.util.MethodTimer;
import com.intuit.tank.vm.event.JobEvent;
import com.intuit.tank.vm.settings.TankConfig;
import com.intuit.tank.vm.settings.VmInstanceType;
@@ -81,7 +80,7 @@ public class JobMaker implements Serializable {
@Inject
private UsersAndTimes usersAndTimes;
- private JobInstance proposedJobInstance;
+ protected JobInstance proposedJobInstance;
private String jobDetails;
@@ -358,21 +357,18 @@ public void createJobInstance() {
proposedJobInstance.getJobRegionVersions().addAll(getVersions(jobRegionDao, jobRegions));
JobValidator validator = new JobValidator(workload.getTestPlans(), proposedJobInstance.getVariables(),
false);
- long maxDuration = 0;
- for (TestPlan plan : workload.getTestPlans()) {
- maxDuration = Math.max(validator.getDurationMs(plan.getName()), maxDuration);
- }
+ long maxDuration = workload.getTestPlans().stream()
+ .mapToLong(plan -> validator.getDurationMs(plan.getName()))
+ .max().orElse(0);
TestParameterContainer times = TestParamUtil.evaluateTestTimes(maxDuration, projectBean
.getJobConfiguration().getRampTimeExpression(), projectBean.getJobConfiguration()
.getSimulationTimeExpression());
proposedJobInstance.setExecutionTime(maxDuration);
proposedJobInstance.setRampTime(times.getRampTime());
proposedJobInstance.setSimulationTime(times.getSimulationTime());
- int totalVirtualUsers = 0;
- for (JobRegion region : jobRegions) {
- totalVirtualUsers += TestParamUtil.evaluateExpression(region.getUsers(), maxDuration,
- times.getSimulationTime(), times.getRampTime());
- }
+ int totalVirtualUsers = jobRegions.stream()
+ .mapToInt(region -> (int) TestParamUtil.evaluateExpression(region.getUsers(), maxDuration,
+ times.getSimulationTime(), times.getRampTime())).sum();
proposedJobInstance.setTotalVirtualUsers(totalVirtualUsers);
}
}
@@ -382,7 +378,7 @@ public String getJobDetails() {
try {
jobDetails = createJobDetails();
} catch (Exception e) {
- LOG.error("Error building jobDetails: " + e, e);
+ LOG.error("Error building jobDetails: {}", e, e);
return "Error building jobDetails: ";
}
}
@@ -401,27 +397,19 @@ private String createJobDetails() {
public void addJobToQueue() {
if (proposedJobInstance != null) {
- MethodTimer mt = new MethodTimer(LOG, this.getClass(), "addJobToQueue");
JobQueueDao jobQueueDao = new JobQueueDao();
Workload workload = projectBean.getWorkload();
JobQueue queue = jobQueueDao.findOrCreateForProjectId(projectBean.getProject().getId());
proposedJobInstance.setJobDetails(jobDetails);
- mt.markAndLog("Create Job Details");
queue.addJob(proposedJobInstance);
- mt.markAndLog("Add job to queue");
jobQueueDao.saveOrUpdate(queue);
- mt.markAndLog("save queue");
storeScript(Integer.toString(proposedJobInstance.getId()), workload, proposedJobInstance);
- mt.markAndLog("store script");
messages.info("Job has been submitted successfully");
jobQueueEvent.fire(queue);
- mt.markAndLog("fire queue event");
jobEventProducer.fire(new JobEvent(Integer.toString(proposedJobInstance.getId()), "",
JobLifecycleEvent.QUEUE_ADD));
- mt.markAndLog("fire job event QUEUE_ADD");
setName(null);
proposedJobInstance = null;
- mt.endAndLog();
}
}
@@ -458,10 +446,8 @@ public boolean isValid() {
return false;
}
if(proposedJobInstance.getIncrementStrategy().equals(IncrementStrategy.standard)){
- int regionPercentage = 0;
- for (JobRegion r : projectBean.getWorkload().getJobConfiguration().getJobRegions()) {
- regionPercentage += Integer.parseInt(r.getPercentage());
- }
+ int regionPercentage = projectBean.getWorkload().getJobConfiguration().getJobRegions().stream()
+ .mapToInt(r -> Integer.parseInt(r.getPercentage())).sum();
if (regionPercentage != 100) {
return false;
}
@@ -470,16 +456,9 @@ public boolean isValid() {
}
private boolean hasScripts() {
- Workload workload = projectBean.getWorkload();
- workload.getTestPlans();
- for (TestPlan plan : workload.getTestPlans()) {
- for (ScriptGroup group : plan.getScriptGroups()) {
- if (!group.getScriptGroupSteps().isEmpty()) {
- return true;
- }
- }
- }
- return false;
+ return projectBean.getWorkload().getTestPlans().stream()
+ .flatMap(testPlan -> testPlan.getScriptGroups().stream())
+ .anyMatch(scriptGroup -> !scriptGroup.getScriptGroupSteps().isEmpty());
}
/**
diff --git a/web/web_support/src/test/java/com/intuit/tank/project/JobDetailFormatterTest.java b/web/web_support/src/test/java/com/intuit/tank/project/JobDetailFormatterTest.java
index 078ec0634..6513c8f93 100644
--- a/web/web_support/src/test/java/com/intuit/tank/project/JobDetailFormatterTest.java
+++ b/web/web_support/src/test/java/com/intuit/tank/project/JobDetailFormatterTest.java
@@ -83,8 +83,8 @@ public void getSimulationTime() {
@Test
public void getVmDetails() {
- String vmDetails = JobDetailFormatter.getVmDetails(new TankConfig(), "c5.xlarge");
- assertEquals("c5.xlarge (cpus=4 ecus=16 memory=8.0 cost=$0.17 per hour)", vmDetails);
+ String vmDetails = JobDetailFormatter.getVmDetails(new TankConfig(), "m8g.xlarge");
+ assertEquals("m8g.xlarge (cpus=4 ecus=16 memory=16.0 cost=$0.1795 per hour)", vmDetails);
}
/**
diff --git a/web/web_support/src/test/java/com/intuit/tank/project/JobMakerTest.java b/web/web_support/src/test/java/com/intuit/tank/project/JobMakerTest.java
new file mode 100644
index 000000000..1ae4e75af
--- /dev/null
+++ b/web/web_support/src/test/java/com/intuit/tank/project/JobMakerTest.java
@@ -0,0 +1,181 @@
+package com.intuit.tank.project;
+
+import com.intuit.tank.PreferencesBean;
+import com.intuit.tank.ProjectBean;
+import com.intuit.tank.auth.TankSecurityContext;
+import com.intuit.tank.util.Messages;
+import com.intuit.tank.vm.api.enumerated.IncrementStrategy;
+import com.intuit.tank.vm.api.enumerated.TerminationPolicy;
+import com.intuit.tank.vm.event.JobEvent;
+import jakarta.enterprise.context.ConversationScoped;
+import jakarta.enterprise.event.Event;
+import org.apache.commons.lang3.time.FastDateFormat;
+import org.jboss.weld.junit5.auto.ActivateScopes;
+import org.jboss.weld.junit5.auto.EnableAutoWeld;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.*;
+
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+
+@EnableAutoWeld
+@ActivateScopes(ConversationScoped.class)
+public class JobMakerTest {
+
+ @InjectMocks
+ private JobMaker jobMaker;
+
+ @Mock
+ private Event jobQueueEvent;
+
+ @Mock
+ private Event jobEventProducer;
+
+ @Mock
+ private Messages messages;
+
+ @Mock
+ private PreferencesBean preferences;
+
+ @Mock
+ private UsersAndTimes usersAndTimes;
+
+ @Mock
+ private TankSecurityContext securityContext;
+
+ private AutoCloseable closeable;
+
+ @BeforeEach
+ void initService() {
+ closeable = MockitoAnnotations.openMocks(this);
+ }
+
+ @AfterEach
+ void closeService() throws Exception {
+ closeable.close();
+ }
+
+ @Test
+ public void testGetName() {
+ ProjectBean mockProjectBean = mock(ProjectBean.class);
+ JobConfiguration mockJobConfiguration = mock(JobConfiguration.class);
+ Mockito.when(mockJobConfiguration.getIncrementStrategy()).thenReturn(IncrementStrategy.increasing);
+ Mockito.when(mockJobConfiguration.getWorkload()).thenReturn(mock(Workload.class));
+ Mockito.when(mockProjectBean.getJobConfiguration()).thenReturn(mockJobConfiguration);
+ Mockito.when(usersAndTimes.getTotalUsers()).thenReturn(10);
+ Mockito.when(preferences.getTimestampFormat()).thenReturn(FastDateFormat.getInstance("yyyy.MM.dd-HH:mm:ss.S z"));
+ jobMaker.init(mockProjectBean);
+ assertTrue(jobMaker.getName().contains("_10_users_"));
+
+ Mockito.when(mockJobConfiguration.getIncrementStrategy()).thenReturn(IncrementStrategy.standard);
+ jobMaker.init(mockProjectBean);
+ assertTrue(jobMaker.getName().contains("_nonlinear_"));
+ }
+
+ @Test
+ public void testSetVmInstanceType() {
+ jobMaker.setVmInstanceType("");
+
+ ProjectBean projectBean = mock(ProjectBean.class);
+ JobConfiguration mockJobConfiguration = mock(JobConfiguration.class);
+ Mockito.when(projectBean.getJobConfiguration()).thenReturn(mockJobConfiguration);
+ jobMaker.init(projectBean);
+ jobMaker.setVmInstanceType("m8g.2xlarge");
+ }
+
+ @Test void testTargetRatePerAgent() {
+ ProjectBean mockProjectBean = mock(ProjectBean.class);
+ JobConfiguration jobConfiguration = new JobConfiguration();
+ Mockito.when(mockProjectBean.getJobConfiguration()).thenReturn(jobConfiguration);
+ jobMaker.init(mockProjectBean);
+ jobMaker.setTargetRatePerAgent(10.0);
+ assertEquals(10.0, jobMaker.getTargetRatePerAgent());
+ }
+
+ @Test
+ public void testCreateJobInstance() {
+ ProjectBean mockProjectBean = mock(ProjectBean.class);
+ JobConfiguration mockJobConfiguration = mock(JobConfiguration.class);
+ Workload mockWorkload = mock(Workload.class);
+ Mockito.when(mockWorkload.getJobConfiguration()).thenReturn(mockJobConfiguration);
+ Mockito.when(mockJobConfiguration.getIncrementStrategy()).thenReturn(IncrementStrategy.increasing);
+ Mockito.when(mockJobConfiguration.getWorkload()).thenReturn(mockWorkload);
+ Mockito.when(mockJobConfiguration.getDataFileIds()).thenReturn(Set.of(1));
+ Mockito.when(mockJobConfiguration.getNotifications()).thenReturn(Set.of(new JobNotification()));
+ Mockito.when(mockProjectBean.getWorkload()).thenReturn(mockWorkload);
+ Mockito.when(mockProjectBean.getJobConfiguration()).thenReturn(mockJobConfiguration);
+ Mockito.when(mockProjectBean.doSave()).thenReturn(Boolean.TRUE);
+ jobMaker.init(mockProjectBean);
+ Mockito.when(preferences.getTimestampFormat()).thenReturn(FastDateFormat.getInstance("yyyy.MM.dd-HH:mm:ss.S z"));
+ Mockito.when(securityContext.getCallerPrincipal()).thenReturn(() -> "TEST_USER");
+ try (MockedStatic mockedStatic = Mockito.mockStatic(JobDetailFormatter.class)) {
+ mockedStatic.when(() -> JobDetailFormatter.createJobDetails(any(), any(), any())).thenReturn("TEST_JOB_DETAILS");
+ jobMaker.createJobInstance();
+ assertEquals("TEST_JOB_DETAILS", jobMaker.getJobDetails());
+ }
+ }
+
+ @Test
+ public void testAddJobToQueue() {
+ jobMaker.proposedJobInstance = new JobInstance();
+ ProjectBean mockProjectBean = mock(ProjectBean.class);
+ JobConfiguration mockJobConfiguration = mock(JobConfiguration.class);
+ Workload mockWorkload = mock(Workload.class);
+ Project mockProject = mock(Project.class);
+ Mockito.when(mockProjectBean.getProject()).thenReturn(mockProject);
+ Mockito.when(mockJobConfiguration.getIncrementStrategy()).thenReturn(IncrementStrategy.increasing);
+ Mockito.when(mockJobConfiguration.getWorkload()).thenReturn(mockWorkload);
+ Mockito.when(mockProjectBean.getJobConfiguration()).thenReturn(mockJobConfiguration);
+ Mockito.when(mockProjectBean.getWorkload()).thenReturn(mockWorkload);
+ Mockito.when(mockWorkload.getProject()).thenReturn(mockProject);
+ Mockito.when(usersAndTimes.getTotalUsers()).thenReturn(10);
+ Mockito.when(preferences.getTimestampFormat()).thenReturn(FastDateFormat.getInstance("yyyy.MM.dd-HH:mm:ss.S z"));
+ jobMaker.init(mockProjectBean);
+ jobMaker.addJobToQueue();
+ assertNull(jobMaker.getProposedJobInstance());
+ }
+
+ @Test
+ public void testIsValid() {
+ jobMaker.proposedJobInstance = null;
+ assertFalse(jobMaker.isValid());
+
+ jobMaker.proposedJobInstance = new JobInstance();
+ assertFalse(jobMaker.isValid());
+
+ jobMaker.setName("TEST");
+ jobMaker.getProposedJobInstance().setIncrementStrategy(IncrementStrategy.increasing);
+ assertFalse(jobMaker.isValid());
+
+ jobMaker.getProposedJobInstance().setIncrementStrategy(IncrementStrategy.standard);
+ jobMaker.getProposedJobInstance().setTerminationPolicy(TerminationPolicy.time);
+ jobMaker.getProposedJobInstance().setSimulationTime(0);
+ assertFalse(jobMaker.isValid());
+
+ jobMaker.getProposedJobInstance().setSimulationTime(10);
+ ProjectBean mockProjectBean = mock(ProjectBean.class);
+ Workload mockWorkload = mock(Workload.class);
+ Mockito.when(mockProjectBean.getWorkload()).thenReturn(mockWorkload);
+ jobMaker.init(mockProjectBean);
+ assertFalse(jobMaker.isValid());
+
+ TestPlan testPlan = TestPlan.builder().build();
+ ScriptGroup scriptGroup = ScriptGroup.builder().build();
+ scriptGroup.addScriptGroupStep(ScriptGroupStep.builder().build());
+ testPlan.addScriptGroup(scriptGroup);
+ Mockito.when(mockWorkload.getTestPlans()).thenReturn(List.of(testPlan));
+ JobConfiguration mockJobConfiguration = mock(JobConfiguration.class);
+ Mockito.when(mockWorkload.getJobConfiguration()).thenReturn(mockJobConfiguration);
+ assertFalse(jobMaker.isValid());
+
+ Mockito.when(mockJobConfiguration.getJobRegions()).thenReturn(
+ Set.of(JobRegion.builder().percentage("100").build()));
+ assertTrue(jobMaker.isValid());
+ }
+}