Skip to content

Commit 1a69c53

Browse files
committedMar 17, 2025
Merge remote-tracking branch 'origin/main'
2 parents f315d5c + c4f3cf6 commit 1a69c53

File tree

8 files changed

+128
-31
lines changed

8 files changed

+128
-31
lines changed
 

‎README.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This repository contains performance testing scripts and configurations for OpenMRS using Gatling.
44

55
The latest report can be found
6-
at [openmrs.github.io/openmrs-contrib-performance-test](https://openmrs.github.io/openmrs-contrib-performance-test/)
6+
at [here](https://o3-performance.openmrs.org/)
77

88
## Table of Contents
99

@@ -31,13 +31,15 @@ and easy-to-use framework for simulating user load and measuring system performa
3131

3232
To run the performance tests locally, follow these steps:
3333

34-
1. Start OpenMRS on port 80. (Use the docker file: [src/test/resources/docker-compose.yml](src/test/resources/docker-compose.yml) It contains demo patients for the test. [Learn more](#generating-demo-patient-data))
35-
36-
For using the docker file, run the following command:
37-
```bash
34+
1. Install dependencies (and compile)
35+
```bash
36+
./mvnw install -DskipTests
37+
```
38+
2. Start OpenMRS on port 80. (Use the docker file: [src/test/resources/docker-compose.yml](src/test/resources/docker-compose.yml) It contains demo patients for the test. [Learn more](#generating-demo-patient-data))
39+
```bash
3840
docker compose -f src/test/resources/docker-compose.yml up
39-
```
40-
2. Execute the following command in your terminal:
41+
```
42+
3. Execute the following command in your terminal:
4143

4244
**Standard** `export SIMULATION_PRESET='standard' && ./mvnw gatling:test` \
4345
**dev** `export SIMULATION_PRESET=dev TIER_COUNT=2 TIER_DURATION_MINUTES=1 USER_INCREMENT_PER_TIER=10 && ./mvnw gatling:test`

‎pom.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
<properties>
1111
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1212
<gatling.version>3.13.4</gatling.version>
13-
<gatling-maven-plugin.version>4.15.1</gatling-maven-plugin.version>
13+
<gatling-maven-plugin.version>4.16.1</gatling-maven-plugin.version>
1414
<maven-compiler-plugin.version>3.14.0</maven-compiler-plugin.version>
1515
<maven-resources-plugin.version>3.3.1</maven-resources-plugin.version>
1616
<maven-jar-plugin.version>3.4.2</maven-jar-plugin.version>
@@ -29,7 +29,7 @@
2929
<dependency>
3030
<groupId>com.fasterxml.jackson.core</groupId>
3131
<artifactId>jackson-databind</artifactId>
32-
<version>2.18.2</version>
32+
<version>2.18.3</version>
3333
</dependency>
3434
<dependency>
3535
<groupId>org.junit.jupiter</groupId>
@@ -40,12 +40,12 @@
4040
<dependency>
4141
<groupId>org.slf4j</groupId>
4242
<artifactId>slf4j-api</artifactId>
43-
<version>2.0.16</version>
43+
<version>2.0.17</version>
4444
</dependency>
4545
<dependency>
4646
<groupId>ch.qos.logback</groupId>
4747
<artifactId>logback-classic</artifactId>
48-
<version>1.5.16</version>
48+
<version>1.5.17</version>
4949
</dependency>
5050
</dependencies>
5151

‎src/test/java/org/openmrs/performance/Constants.java

+4
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,8 @@ public class Constants {
5353
public static final String DIABETIC_KETOSIS_CONCEPT = "123107AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
5454
public static final String DIABETIC_FOOT_ULCER_CONCEPT = "149069AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
5555

56+
// Vitals
57+
public static final String VITALS_FORM_UUID = "9f26aad4-244a-46ca-be49-1196df1a8c9a";
58+
public static final String VITALS_LOCATION_UUID = "ba685651-ed3b-4e63-9b35-78893060758a";
59+
public static final String VITALS_ENCOUNTER_TYPE_UUID = "67a71486-1a54-468f-ac3e-7091a9a79584";
5660
}

‎src/test/java/org/openmrs/performance/http/DoctorHttpService.java

+66-1
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,46 @@
77

88
import java.time.ZonedDateTime;
99
import java.time.format.DateTimeFormatter;
10+
import java.util.ArrayList;
1011
import java.util.Collections;
1112
import java.util.HashMap;
1213
import java.util.List;
1314
import java.util.Map;
1415

1516
import static io.gatling.javaapi.core.CoreDsl.StringBody;
1617
import static io.gatling.javaapi.core.CoreDsl.bodyString;
17-
import static io.gatling.javaapi.core.CoreDsl.exec;
1818
import static io.gatling.javaapi.core.CoreDsl.jsonPath;
19+
import static io.gatling.javaapi.http.HttpDsl.RawFileBodyPart;
20+
import static io.gatling.javaapi.http.HttpDsl.StringBodyPart;
1921
import static io.gatling.javaapi.http.HttpDsl.http;
2022
import static org.openmrs.performance.Constants.ALLERGY_REACTION_UUID;
23+
import static org.openmrs.performance.Constants.ARTERIAL_BLOOD_OXYGEN_SATURATION;
2124
import static org.openmrs.performance.Constants.CARE_SETTING_UUID;
2225
import static org.openmrs.performance.Constants.CLINICIAN_ENCOUNTER_ROLE;
2326
import static org.openmrs.performance.Constants.CODED_ALLERGEN_UUID;
2427
import static org.openmrs.performance.Constants.DAYS;
2528
import static org.openmrs.performance.Constants.DEFAULT_DOSING_TYPE;
29+
import static org.openmrs.performance.Constants.DIASTOLIC_BLOOD_PRESSURE;
2630
import static org.openmrs.performance.Constants.DRUG_ORDER;
31+
import static org.openmrs.performance.Constants.HEIGHT_CM;
32+
import static org.openmrs.performance.Constants.MID_UPPER_ARM_CIRCUMFERENCE;
2733
import static org.openmrs.performance.Constants.ONCE_DAILY;
2834
import static org.openmrs.performance.Constants.ORAL;
2935
import static org.openmrs.performance.Constants.ORDER;
3036
import static org.openmrs.performance.Constants.OUTPATIENT_CLINIC_LOCATION_UUID;
37+
import static org.openmrs.performance.Constants.PULSE;
38+
import static org.openmrs.performance.Constants.RESPIRATORY_RATE;
3139
import static org.openmrs.performance.Constants.SEVERITY_UUID;
40+
import static org.openmrs.performance.Constants.SYSTOLIC_BLOOD_PRESSURE;
3241
import static org.openmrs.performance.Constants.TABLET;
42+
import static org.openmrs.performance.Constants.TEMPERATURE_C;
3343
import static org.openmrs.performance.Constants.VISIT_NOTE_CONCEPT_UUID;
3444
import static org.openmrs.performance.Constants.VISIT_NOTE_ENCOUNTER_TYPE_UUID;
3545
import static org.openmrs.performance.Constants.VISIT_NOTE_FORM_UUID;
46+
import static org.openmrs.performance.Constants.VITALS_ENCOUNTER_TYPE_UUID;
47+
import static org.openmrs.performance.Constants.VITALS_FORM_UUID;
48+
import static org.openmrs.performance.Constants.VITALS_LOCATION_UUID;
49+
import static org.openmrs.performance.Constants.WEIGHT_KG;
3650

3751
public class DoctorHttpService extends HttpService {
3852

@@ -224,6 +238,19 @@ public HttpRequestActionBuilder getAllowedFileExtensions() {
224238
.get("/openmrs/ws/rest/v1/systemsetting?&v=custom:(value)&q=attachments.allowedFileExtensions");
225239
}
226240

241+
public HttpRequestActionBuilder uploadAttachment(String patientUuid) {
242+
return http("Upload Attachment Request")
243+
.post("/openmrs/ws/rest/v1/attachment")
244+
.bodyPart(StringBodyPart("fileCaption", "Test Image"))
245+
.bodyPart(StringBodyPart("patient", patientUuid))
246+
.bodyPart(
247+
RawFileBodyPart("file", "Sample_1MB_image.jpg")
248+
.contentType("image/jpg")
249+
.fileName("Sample_1MB_image.jpg")
250+
)
251+
.asMultipartForm();
252+
}
253+
227254
public HttpRequestActionBuilder getLabResults(String patientUuid) {
228255
return http("Get Lab Results of Patient")
229256
.get("/openmrs/ws/fhir2/R4/Observation?category=laboratory&patient=" + patientUuid + "&_count=100&_summary=data")
@@ -240,6 +267,11 @@ public HttpRequestActionBuilder getImmunizations(String patientUuid) {
240267
.get("/openmrs/ws/fhir2/R4/Immunization?patient=" + patientUuid + "&_summary=data");
241268
}
242269

270+
public HttpRequestActionBuilder getPrograms() {
271+
return http("Get Programs")
272+
.get("/openmrs/ws/rest/v1/program?v=custom:(uuid,display,allWorkflows,concept:(uuid,display))");
273+
}
274+
243275
public HttpRequestActionBuilder searchForDrug(String searchQuery) {
244276
String customRepresentation = """
245277
custom:(uuid,display,name,strength,
@@ -353,4 +385,37 @@ public HttpRequestActionBuilder saveDiagnosis(String patientUuid, String encount
353385
}
354386
}
355387

388+
public HttpRequestActionBuilder saveVitalsData(String patientUuid) {
389+
ZonedDateTime now = ZonedDateTime.now();
390+
String encounterDatetime = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSSZ"));
391+
392+
Map<String, Object> encounter = new HashMap<>();
393+
encounter.put("form", VITALS_FORM_UUID);
394+
encounter.put("patient", patientUuid);
395+
encounter.put("location", VITALS_LOCATION_UUID);
396+
encounter.put("encounterType", VITALS_ENCOUNTER_TYPE_UUID);
397+
encounter.put("encounterDatetime", encounterDatetime);
398+
399+
List<Map<String, Object>> observations = new ArrayList<>();
400+
observations.add(Map.of("concept", SYSTOLIC_BLOOD_PRESSURE, "value", 34));
401+
observations.add(Map.of("concept", DIASTOLIC_BLOOD_PRESSURE, "value", 44));
402+
observations.add(Map.of("concept", RESPIRATORY_RATE, "value", 100));
403+
observations.add(Map.of("concept", ARTERIAL_BLOOD_OXYGEN_SATURATION, "value", 20));
404+
observations.add(Map.of("concept", PULSE, "value", 120));
405+
observations.add(Map.of("concept", TEMPERATURE_C, "value", 28));
406+
observations.add(Map.of("concept", WEIGHT_KG, "value", 60));
407+
observations.add(Map.of("concept", HEIGHT_CM, "value", 121));
408+
observations.add(Map.of("concept", MID_UPPER_ARM_CIRCUMFERENCE, "value", 34));
409+
410+
encounter.put("obs", observations);
411+
412+
try {
413+
String body = new ObjectMapper().writeValueAsString(encounter); // Convert Map to JSON
414+
return http("Save Vitals").post("/openmrs/ws/rest/v1/encounter").body(StringBody(body));
415+
}
416+
catch (JsonProcessingException e) {
417+
throw new RuntimeException("Error converting visitNote to JSON", e);
418+
}
419+
}
420+
356421
}

‎src/test/java/org/openmrs/performance/http/HttpService.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package org.openmrs.performance.http;
22

33
import io.gatling.javaapi.http.HttpRequestActionBuilder;
4-
54
import java.util.Set;
65
import java.util.StringJoiner;
76

@@ -115,4 +114,6 @@ public HttpRequestActionBuilder getActiveOrders(String patientUuid) {
115114
return http("Get Active Orders")
116115
.get("/openmrs/ws/rest/v1/order?patient="+patientUuid+"&careSetting=6f0c9a92-6f24-11e3-af88-005056821db0&status=ACTIVE&orderType=131168f4-15f5-102d-96e4-000c29c2a5d7&v=custom:(uuid,dosingType,orderNumber,accessionNumber,patient:ref,action,careSetting:ref,previousOrder:ref,dateActivated,scheduledDate,dateStopped,autoExpireDate,orderType:ref,encounter:ref,orderer:(uuid,display,person:(display)),orderReason,orderReasonNonCoded,orderType,urgency,instructions,commentToFulfiller,drug:(uuid,display,strength,dosageForm:(display,uuid),concept),dose,doseUnits:ref,frequency:ref,asNeeded,asNeededCondition,quantity,quantityUnits:ref,numRefills,dosingInstructions,duration,durationUnits:ref,route:ref,brandName,dispenseAsWritten)");
117116
}
117+
118+
118119
}

‎src/test/java/org/openmrs/performance/registries/DoctorRegistry.java

+35-18
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,7 @@
2727
import static org.openmrs.performance.Constants.WEIGHT_KG;
2828
import static org.openmrs.performance.utils.CommonUtils.extractConceptIds;
2929

30-
31-
32-
public class DoctorRegistry extends Registry<DoctorHttpService>{
30+
public class DoctorRegistry extends Registry<DoctorHttpService> {
3331

3432
public DoctorRegistry() {
3533
super(new DoctorHttpService());
@@ -75,6 +73,10 @@ public ChainBuilder openVitalsAndBiometricsTab(String patientUuid) {
7573
return exec(httpService.getPatientObservations(patientUuid, vitals))
7674
.exec(httpService.getPatientObservations(patientUuid, biometrics));
7775
}
76+
77+
public ChainBuilder recordVitals(String patientUuid){
78+
return exec(httpService.saveVitalsData(patientUuid));
79+
}
7880

7981
public ChainBuilder openMedicationsTab(String patientUuid) {
8082
return exec(httpService.getDrugOrders(patientUuid));
@@ -102,19 +104,19 @@ public ChainBuilder openLabResultsTab(String patientUuid) {
102104
public ChainBuilder openAllergiesTab(String patientUuid) {
103105
return exec(httpService.getAllergies(patientUuid));
104106
}
105-
106-
public ChainBuilder openAllergiesForm(){
107+
108+
public ChainBuilder openAllergiesForm() {
107109
return exec(
108-
httpService.getAllergens("Drug",DRUG_ALLERGEN_UUID),
109-
httpService.getAllergens("Environment",ENVIRONMENTAL_ALLERGEN_UUID),
110-
httpService.getAllergens("Food",FOOD_ALLERGEN_UUID),
111-
httpService.getAllergens("Allergic Reactions",ALLERGY_REACTION_UUID)
110+
httpService.getAllergens("Drug", DRUG_ALLERGEN_UUID),
111+
httpService.getAllergens("Environment", ENVIRONMENTAL_ALLERGEN_UUID),
112+
httpService.getAllergens("Food", FOOD_ALLERGEN_UUID),
113+
httpService.getAllergens("Allergic Reactions", ALLERGY_REACTION_UUID)
112114
);
113115
}
114-
115-
public ChainBuilder recordAllergy(String patientUuid) {
116+
117+
public ChainBuilder recordAllergy(String patientUuid) {
116118
return exec(
117-
httpService.saveAllergy(patientUuid)
119+
httpService.saveAllergy(patientUuid)
118120
);
119121
}
120122

@@ -131,32 +133,47 @@ public ChainBuilder openAttachmentsTab(String patientUuid) {
131133
.exec(httpService.getAllowedFileExtensions());
132134
}
133135

136+
137+
public ChainBuilder openProgramsTab(String patientUuid) {
138+
return exec(httpService.getPrograms())
139+
.exec(httpService.getProgramEnrollments(patientUuid));
140+
}
141+
142+
public ChainBuilder addAttachment(String patientUuid){
143+
return exec(httpService.uploadAttachment(patientUuid))
144+
.exec(httpService.getAttachments(patientUuid));
145+
}
146+
134147
public ChainBuilder openVisitsTab(String patientUuid) {
135148
return exec(httpService.getVisitsOfPatient(patientUuid))
136149
.exec(httpService.getActiveOrders(patientUuid))
137150
.exec(httpService.getLabResults(patientUuid));
138151
}
139152

153+
public ChainBuilder openAppointmentsTab(String patientUuid) {
154+
return exec(httpService.getAppointments(patientUuid));
155+
}
156+
140157
public ChainBuilder addDrugOrder(String patientUuid, String visitUuid, String currentUserUuid) {
141158
String asprin_162_5mg = "a722710f-403b-451f-804b-09f8624b0838";
142159
String asprinConcept = "71617AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
143160
return exec(
144161
httpService.getActiveVisitOfPatient(patientUuid),
145162
httpService.searchForDrug("asprin"),
146163
httpService.searchForDrug("Tylenol"),
147-
httpService.saveOrder(patientUuid, visitUuid, currentUserUuid, asprin_162_5mg, asprinConcept)
164+
httpService.saveOrder(patientUuid, visitUuid, currentUserUuid, asprin_162_5mg, asprinConcept)
148165
);
149-
166+
150167
}
151-
168+
152169
public ChainBuilder addVisitNote(String patientUuid, String currentUserUuid) {
153170
String visitNoteText = "Patient visit note";
154171
String certainty = "PROVISIONAL";
155172
String encounterUuid = "#{encounterUuid}";
156173

157174
return exec(
158-
httpService.saveVisitNote(patientUuid, currentUserUuid, visitNoteText),
159-
httpService.saveDiagnosis(patientUuid, encounterUuid, DIABETIC_KETOSIS_CONCEPT, certainty, 1),
160-
httpService.saveDiagnosis(patientUuid, encounterUuid, DIABETIC_FOOT_ULCER_CONCEPT, certainty, 2));
175+
httpService.saveVisitNote(patientUuid, currentUserUuid, visitNoteText),
176+
httpService.saveDiagnosis(patientUuid, encounterUuid, DIABETIC_KETOSIS_CONCEPT, certainty, 1),
177+
httpService.saveDiagnosis(patientUuid, encounterUuid, DIABETIC_FOOT_ULCER_CONCEPT, certainty, 2));
161178
}
162179
}

‎src/test/java/org/openmrs/performance/scenarios/VisitPatientScenario.java

+8
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ public ScenarioBuilder getScenarioBuilder() {
3030
.pause(2)
3131
.exec(registry.openVitalsAndBiometricsTab("#{patient_uuid}"))
3232
.pause(5)
33+
.exec(registry.recordVitals("#{patient_uuid}"))
34+
.pause(5)
3335
.exec(registry.openMedicationsTab("#{patient_uuid}"))
3436
.pause(5)
3537
.exec(registry.openOrdersTab("#{patient_uuid}"))
@@ -48,6 +50,12 @@ public ScenarioBuilder getScenarioBuilder() {
4850
.pause(5)
4951
.exec(registry.openAttachmentsTab("#{patient_uuid}"))
5052
.pause(5)
53+
.exec(registry.openProgramsTab("#{patient_uuid}"))
54+
.pause(5)
55+
.exec(registry.addAttachment("#{patient_uuid}"))
56+
.pause(5)
57+
.exec(registry.openAppointmentsTab("#{patient_uuid}"))
58+
.pause(5)
5159
.exec(registry.addDrugOrder("#{patient_uuid}", "#{visitUuid}", "#{currentUserUuid}"))
5260
.pause(5)
5361
.exec(registry.addVisitNote("#{patient_uuid}", "#{currentUserUuid}"))
1010 KB
Loading

0 commit comments

Comments
 (0)
Failed to load comments.