How to run the tests (moodle 45)

Versión 1 (Emilio Penna, Jueves, 19 de Marzo de 2026 10:03:19 -0300)

1 1
h1. How to run the tests (moodle 45)
2 1
3 1
h1. Moodle Quiz Load Testing — Setup and Procedure (Moodle 4.5, 2026)
4 1
5 1
This page describes how to set up and run the quiz load tests.
6 1
For actual results and infrastructure sizing data, see: [[Load_test_results_moodle45_2026]]
7 1
8 1
Attached to this page:
9 1
* Moodle quiz backup (16-question quiz, 8 pages)
10 1
* Test users file (CSV, for bulk upload and enrollment)
11 1
* JMeter script (jmx)
12 1
13 1
---
14 1
15 1
h2. Setting up test data in Moodle
16 1
17 1
# Create a course for the test (or use an existing one).
18 1
# Restore the quiz backup (@.mbz@ file) into that course.
19 1
# Upload test users via _Site administration > Users > Accounts > Upload users_.
20 1
** The CSV file contains 5000 users. Edit the @course@ column to match your course shortname.
21 1
** Set "Force password change" to _None_.
22 1
# Enroll all users in the course (handled by the upload if the CSV includes the course column).
23 1
24 1
After the test, verify that attempts and answers were recorded correctly in the quiz results.
25 1
26 1
*Resetting between runs:* if a test run is interrupted before finishing, attempts remain "in progress".
27 1
Users cannot start a new attempt in that state. Reset with:
28 1
29 1
<pre>
30 1
UPDATE mdl_quiz_attempts SET state='finished' WHERE quiz=<quiz_id>;
31 1
</pre>
32 1
33 1
---
34 1
35 1
h2. JMeter script configuration
36 1
37 1
The script requires the JMeter Plugins Manager. Download @plugins-manager.jar@ from
38 1
https://jmeter-plugins.org/install/Install/ and place it in @lib/ext/@ (restart JMeter).
39 1
40 1
Tested with JMeter 5.6.3 and Moodle 4.5.
41 1
42 1
Open the @.jmx@ file and adjust:
43 1
44 1
# *Test Plan* — set @course_id@, @quiz_id@, and server hostname.
45 1
# *CSV Data Set Config* — set the path to the users CSV file.
46 1
# *Thread Group* — set number of threads (VUs) and ramp-up time.
47 1
** Start with 1 thread to confirm the test runs without errors before scaling up.
48 1
** We tested up to 3000 threads with 180 s ramp-up.
49 1
# *Synchronizing Timer* (before startattempt) — holds all VUs at the exam start point until
50 1
  the configured number arrive, then releases them together. This simulates the real-world
51 1
  burst when all students click "Start attempt" at the same time. Set the number of simultaneous
52 1
  threads to match your VU count.
53 1
# *Gaussian Random Timer* (after startattempt, σ=30s, offset=5s) — introduces post-start
54 1
  dispersion simulating students reading and answering at different rates.
55 1
56 1
---
57 1
58 1
h2. Running the tests
59 1
60 1
From the command line (recommended for load tests — GUI mode has overhead):
61 1
62 1
<pre>
63 1
./jmeter -n -t /path/to/moo4quiz.jmx -l /path/to/output.jtl \
64 1
  -Xms8g -Xmx8g -XX:+UseG1GC
65 1
</pre>
66 1
67 1
*JMeter machine sizing:* use a dedicated machine. We used 32 GB RAM / 8 CPU.
68 1
With a single client we ran up to 2000 VUs reliably. For 3000 VUs we did not observe
69 1
client-side errors, but if you do, consider splitting the load across two JMeter instances
70 1
or using JMeter's distributed testing mode.
71 1
72 1
---
73 1
74 1
h2. Server monitoring during tests
75 1
76 1
Capture server-side metrics during each run to correlate with JMeter results.
77 1
A simple shell script running at 10-second intervals collecting the following is sufficient:
78 1
79 1
* @uptime@ — load average (1, 5, 15 min)
80 1
* @free -m@ — RAM and swap used
81 1
* @ps aux | grep apache@ — Apache process count
82 1
* @curl -s 127.0.0.1/fpm-status@ — PHP-FPM pool status (total, busy, idle workers)
83 1
* @ss -s@ or @netstat@ — HTTPS connections (port 443), MySQL TCP connections
84 1
85 1
Write output as CSV (one line per interval) for easy post-processing.
86 1
87 1
For the database server, @nmon -f -s 5@ provides CPU, memory, disk I/O, and network at
88 1
5-second granularity.
89 1
90 1
---
91 1
92 1
h2. Tips and lessons learned
93 1
94 1
* *Repeat each test at least twice.* On shared VMware infrastructure, hypervisor contention
95 1
  from other VMs introduces variability. Two identical runs let you distinguish real behavior
96 1
  from noise.
97 1
* *The startattempt spike is the critical moment.* Everything else in the quiz is easy for
98 1
  the server. Focus your analysis on the synchronized exam start — that is where the system
99 1
  will fail first.
100 1
* *mod_cache on the reverse proxy* improves static asset delivery (10–35% latency reduction)
101 1
  but can worsen the startattempt spike by delivering pre-exam pages faster, clustering VUs
102 1
  more tightly at the synchronization point.
103 1
* *CPU, not RAM, is the bottleneck* with PHP-FPM + OPcache. Don't over-provision RAM at the
104 1
  expense of CPU cores. See [[Load_test_results_moodle45_2026]] for detailed data.
105 1
* *InnoDB buffer pool sizing matters.* If the working dataset fits in the buffer pool,
106 1
  the database server will show near-zero read I/O during the test. Ensure
107 1
  @innodb_buffer_pool_size@ is set appropriately (we used 16 GB RAM on the DB server).
108 1
* *Check OPcache hit rate* during tests (@opcache_get_status()@). With a warm cache,
109 1
  hit rate should be above 99%. A cold OPcache at test start will produce artificially
110 1
  poor results for the first few requests.