Skip to content
Erik Ostermueller edited this page Mar 12, 2023 · 64 revisions

Running the load-test-in-a-box

If you want to run load-test-in-a-box with the prepackaged source, use these instructions.

If you instead want to build the load-test-in-a-box uber jar, keep reading this page :-)

Prerequisites to Build load-test-in-a-box Uber Jar

  • git / git must be in the path
  • java 8+ / java must be in the path
  • Maven / mvn must be in the path
  • node / npm and node must be in the path
  • To build on windows, install msys2 -- this is because the build scripts are in bash. (got time to port these scripts to apache ANT? link )

Why so complicated?

Why is the build so complicated, requiring lots of doc (this page) to explain?

Not only is it complicated, the main build takes 30-ish minutes. Why?

  • It's complicated because load-test-in-a-box was designed to operate without internet access. See the No Friction Distribution policy which encourages wider distribution.
  • The full build takes 30-ish minutes because
    • several other packages are used (jmeter, glowroot, maven, others) ....and that requires downloads, installs, etc...
    • Building data for a 700mb h2 db takes time. This db has a few million of rows (built on the postgres pgbench schema ) to show realistic db performance successes and failures.
  • Yes, compile-time dependencies are packaged in a maven repo inside the uber jar file. Additionally, the builder needs to launch a 'provisional' uber jar(aka the agent) , launch the SUT/LG and shut them both down, so that RUNTIME dependencies (like maven plugins used to compile/run the SUT) can be downloaded and subsequently packaged into the uber jar. Additionally, this process also compiles and builds the SUT which is NOT done by simpleBuild.sh. So yes it's complicated, but this page should make it easier. Also, understanding the architecture helps understand what pieces are built and packaged.

Build

These steps generally do not require a deep understanding of the load-test-in-a-box No Friction Deployment -- but they can certainly help you understand it.

WARNING: the "cleanAndBuild.sh" build will delete your maven local repository (%USERPROFILE%.m2\repository or $HOME/.m2/repository).

Full Build (takes 30-ish minutes)

Once a full build is done, simpleBuild.sh takes about 1-2 minutes to run -- it builds the angular UI and the load-test-in-a-box java agent.

git clone https://github.com/eostermueller/load-test-in-a-box.git
cd load-test-in-a-box/build
chmod +x *.sh
./cleanAndBuild.sh

At this point, the load-test-in-a-box.jar will get created but it's not ready it -- only compile-time jar dependencies will be packaged. To also package runtime jar dependencies, you'll need to:

  1. Delete the existing installation folder and all files downstream. %USERPROFILE%\.load-test-in-a-box or $HOME/.load-test-in-a-box
  2. Launch by running java -jar load-test-in-a-box.jar (in load-test-in-a-box/backend/target)
  3. Edit the load-test-in-a-box.json in the installation folder that gets created in the above step. Set mavenOnline to true and snail4jMavenRepo to false. This downloads SUT runtime dependencies from the internet to the local maven repo, which is essentially a collecting point for jar files to be packaged in load-test-in-a-box.jar ("Motivation").
  4. Kill and restart the java -jar load-test-in-a-box.jar to pickup the above setting.
  5. Navigate in your browser to localhost:9876 and launch the SUT -- just put a check in the box, and wait for the SUT to fully start.
  6. Optionally, confirm download activity of runtime dependencies in log files in $HOME/.load-test-in-a-box/log
  7. Shut down the java -jar so the jar can be overwritten.
  8. run load-test-in-a-box/build/packageAndFinalBuild.sh to recreate the jar with both compile-time and run-time dependencies.
  9. To test, delete the local maven repo, delete the $HOME/.load-test-in-a-box, then launch the uber jar, check the box to start the SUT and make sure it starts correctly and the markdown renders ok.

Source Tree -- Big Picture

The instructions above will create the folder structure below. I've labeled A,B,C,D on the spots where most development will happen. If you want (and you do) to avoid repeatedly executing the 30 minute build process mentioned above, look for the A,B,C and D "quick build" instructions below.

     ├───load-test-in-a-box
  A  │   ├───backend → The “agent”.  REST api for launching SUT, H2, Wiremock
     │   ├───build → I use these bash scripts every day from MSWindows MSYS2 bash shell.
  B  │   ├───frontend → Angular 9 source code for UI
     │   ├───jmeterFiles → jmeter .jmx “plan” files for applying load.
     │   ├───processManager → maven configuration for launching SUT, H2, Wiremock
     │   ├───wiremock → configuration for defining rq/rs to HTTP mock server.
  C  │   └───workload → REST api use to instantaneously alter the running workload.
  D  └───load-test-in-a-box_sut_sample → java performance defects/fixes, aka the workload.
     ├───load-test-in-a-box_m2-plugin_h2 → A launcher for more recent version of H2
     ├───javaPerformanceTroubleshooting → Build/population of 700mb H2 db.

Quick Build - Introduction

All these Quick Build sections, with the exception of Quick Build D1, requires that you do the full 30 minute build above FIRST FIRST FIRST.

Quick Build A - Build the load-test-in-a-box Java code.

Approximate build time: 60-ish seconds. To launch a Quick Build A:

cd load-test-in-a-box/build
./simpleBuild.sh

...and the output is the Spring Boot uber jar file in load-test-in-a-box/backend/target/ Launch it with "java -jar myUber.jar" and then navigate to http://localhost:8675 to see the load-test-in-a-box browser UI.

Quick Debug A: Debug a built uber jar

Once you've built an uber jar, you can debug it. It's very uncool, but I use Eclipse.

Go to Run / Debug Configurations and create a new configuration for a "Remote Java Application", listening on port 8000 (the default).

Launch the jar like this:

java -Xdebug -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=y -jar load-test-in-a-box/backend/target/lookForUberJarName.jar

...and then launch the Eclipse configuration created above.

Quick Build B: Angular UI Code

Approximate build time: 10-ish seconds.

This requires a bit of explanation. You can take the safe route for building your UI code and just run Quick Build A, above. It will successfully deploy Angular code changes into the uber jar.....but waiting 60 seconds to see the results of a trivial UI tweak will suck the life from your soul, guaranteed. To save your soul from imminent death, read on for details.

You can use any editor you want for TypeScript/Angular/HTML changes, but I use MS visual code. https://code.visualstudio.com/ I launch the UI like this:

cd load-test-in-a-box/frontend/src/main/web
code .

Now, meet Angular's --liveReload parameter that will save your soul. Just save changes to your UI files (most things downstream from load-test-in-a-box/frontend), and the build will auto-compiles/deploy all client changes, but read read on for one key caveat.

The tasty magic inside ./frontend/src/main/web/proxy.conf.json makes this possible, which was shamelessly stolenFrom here.

Step 1: Start the backend spring boot (defaults to port 8679)

cd load-test-in-a-box\build
java -jar ..\backend\target\backend-0.0.2-SNAPSHOT.jar

Step 2: Start the Angular UI in "--liveReload" mode. Live changes to the angular project (load-test-in-a-box/frontend/*) will be automatically rendered.

cd load-test-in-a-box/frontend/src/main/web
npm start

Step 3: Launch Browser to localhost:4200 instead of localhost:8675

At this point, there will be two Angular deployments at your fingertips!!!! Very Weird, but true. The UI at localhost:4200 will be freshly updated code. The UI at localhost:8675 will be out of date -- Beware!!!

Step 4: autoload

Now, leave the "npm start" cmd.exe window open, as well as the browser opened to "localhost:4200" If you make and save another code change in your ts/html editor, ng will automatically recompile and reload your changes. magic. This is immensely helpful for experimenting with HTML layouts, .css, angular approaches, whatever.

Quick Build D1: System Under Test (SUT) / Just for Experimentation

Wanna see your own code run in load-test-in-a-box?

The next section, Quick Build D2, is for making a PR to add code that will be distributed with load-test-in-a-box.

This section, Quick Build D1, is for experimenting for yourself.

Step 1

Follow the quickstart instructions to launch load-test-in-a-box.

Step 2

Add code that you like to load test to the maven project here: %USERPROFILE%.load-test-in-a-box\sutApp (or $HOME/.load-test-in-a-box/sutApp on linux)

Step 3

Annotate the code added in the above step with @Load like in this example

Feel free to compile it your self, but load-test-in-a-box will attempt compile it before launching.

Step 4

Browser to localhost:8675, restart the system under test by removing the check box, adding to back. TODO ADD SCREENSHOT

Step 5

Also, in the UI, put a check box next to the code/annotation you just added. TODO ADD SCREENSHOT

Quick Build D2: System Under Test (SUT) / Contributing to load-test-in-a-box

Wanna see your own code run in load-test-in-a-box?

Quick Build D1 is for experimenting for yourself.

This section, Quick Build D2, is for making a PR to add code that will be distributed with load-test-in-a-box.

Step 1

Add code that you like to load test to the maven project here: tjp2 (see the Source Tree section above to find where tjp2 is).

Step 2

Annotate your code with @Load like in this example

Step 3

cd load-test-in-a-box/build
./postInstallDepsRefresh.sh
./simpleBuild.sh

Step 4

The above steps have helped you add sample perf defects/fixes and package them inside the uber jar. However, once you launch the uber jar, load-test-in-a-box installation process that runs at uber jar startup will not install them.....until you first delete the previous/old code yourself. Here's how you do that:

rm -rf $HOME/.load-test-in-a-box/sutApp              #linux/mac
rmdir /q /s %USERPROFILE\.load-test-in-a-box\sut     #Windows

Step 5

launch the uber jar:

cd load-test-in-a-box/build
java -jar ..\backend\target\<name of uber jar file>

Browser to localhost:9876, restart the system under test by removing the check box, adding to back. TODO ADD SCREENSHOT

Step 6

Also, in the UI, put a check box next to the code you want to run. TODO ADD SCREENSHOT

Browser to localhost:9876, restart the system under test by removing the check box, adding to back. TODO ADD SCREENSHOT

Step 5

Also, in the UI, put a check box next to the code you want to run. TODO ADD SCREENSHOT

Quick Build C: The Workload Java API

Workload API source code is here:

load-test-in-a-box/workload

WARNING: NOT following these instructions has caused me hours/perhaps days of murky problems and confusion.

The Workload API supports a REST API that

  • Uses this API to discover all code annotated with the @Load annotation. Here is an example of some code annotated like this.
  • displays list for the end user of code to run.
  • Allows end user to instantaneously change which code is running, so performance differences can more easily be compared, as in "that code was slow, this is fast"
  • Display names of class/method of current running code.

load-test-in-a-box/workload/pom.xml builds a jar file and installs it to your default local Maven repository. The following steps make that jar file available to load-test-in-a-box's copy of the Maven repository. Yes this project literally has its own copy, stored in %USERPROFILE%.load-test-in-a-box\repository, or $HOME/.load-test-in-a-box/repository on linux/mac.

Step 1

Make your code changes, JUnit tests, whatever.

Step 2

To make sure your code compiles and JUnit tests runs, run Quick Build A If your IDE compile works, and you shamelessly don't care about Junit test, then you can skip this.

Step 3

Once you've deployed your changes to the workload jar file, the "maven repo zip" needs to be created with your changes. cd load-test-in-a-box/build ./packageMavenRepo.sh

Step 4

The maven repo comes packed in the executeable jar, but must be on the file system to be used. Delete the exploded and out of date version (b/c you've made workload changes, right?) version of the local maven repo.

Windows:

rmdir /q /s %USERPROFILE%\.load-test-in-a-box\repository

Bash:

rm -rf ~/.load-test-in-a-box/repository

Step 5

Re-run Quick Build A

NOTES on WHY: Step 2 also runs "Quick Build A", so why do it again? Quick Build A packages the "maven repo zip" into the executable jar file.

Step 6 / Optional

Verify that the maven repo zip explodes to the file system upon launching the executable jar.

#### INFO:  Number if install issues: 0
2022-06-12 11:12:12.882  INFO 26500 --- [           main] c.g.e.snail4j.Snail4jInstaller           : About to unzip [repository.zip] from [/C:/Users/eoste/Documents/src/s4j_2020-040-30/load-test-in-a-box/backend/target/backend-0.0.2-SNAPSHOT.jar] to [C:\Users\eoste\.load-test-in-a-box\repository.zip]
2022-06-12 11:12:12.883  INFO 26500 --- [           main] c.github.eostermueller.snail4j.PathUtil  : Does criteria [repository.zip] match any of these entries in zip file [/C:/Users/eoste/Documents/src/s4j_2020-040-30/load-test-in-a-box/backend/target/backend-0.0.2-SNAPSHOT.jar]?
2022-06-12 11:12:13.869  INFO 26500 --- [           main] c.g.e.snail4j.Snail4jInstaller           : does [C:\Users\eoste\.load-test-in-a-box\repository.zip] exist? [true]
2022-06-12 11:12:13.869  INFO 26500 --- [           main] c.github.eostermueller.snail4j.PathUtil  : Unzipping file [C:\Users\eoste\.load-test-in-a-box\repository.zip] to [C:\Users\eoste\.snail4j]