|
11 | 11 | * [Teamscale Gradle Plugin](https://docs.teamscale.com/reference/integrations/gradle-plugin/) |
12 | 12 | * [Teamscale Maven Plugin](https://docs.teamscale.com/reference/integrations/maven-plugin/) |
13 | 13 |
|
| 14 | +## Architecture |
| 15 | + |
| 16 | +The profiler is a JVM agent that uses [JaCoCo](https://www.jacoco.org/) under the hood for bytecode instrumentation and coverage recording. |
| 17 | +The diagram below shows the data flow from JVM startup to coverage upload. |
| 18 | + |
| 19 | +``` |
| 20 | +┌──────────────────────────────────────────────────────────────────────────┐ |
| 21 | +│ JVM │ |
| 22 | +│ │ |
| 23 | +│ -javaagent:teamscale-jacoco-agent.jar=... │ |
| 24 | +│ │ │ |
| 25 | +│ ▼ │ |
| 26 | +│ ┌──────────┐ ┌─────────────────────┐ ┌──────────────────────┐ │ |
| 27 | +│ │ PreMain │────▶│ JaCoCoPreMain │────▶│ LenientCoverage- │ │ |
| 28 | +│ │ │ │ │ │ Transformer │ │ |
| 29 | +│ │ Parses │ │ Creates JaCoCo │ │ │ │ |
| 30 | +│ │ options, │ │ runtime, registers │ │ Registered with JVM │ │ |
| 31 | +│ │ logging │ │ class transformer │ │ via addTransformer() │ │ |
| 32 | +│ └──────────┘ └─────────────────────┘ └──────────┬───────────┘ │ |
| 33 | +│ │ │ │ |
| 34 | +│ │ ┌──────────────────────────────────────────────────┐ │ |
| 35 | +│ │ │ Class Loading │ │ |
| 36 | +│ │ │ │ │ |
| 37 | +│ │ │ For every class loaded by the JVM: │ │ |
| 38 | +│ │ │ 1. Transformer receives original bytecode │ │ |
| 39 | +│ │ │ 2. JaCoCo injects boolean[] probes at branches │ │ |
| 40 | +│ │ │ and lines │ │ |
| 41 | +│ │ │ 3. Modified bytecode returned to JVM │ │ |
| 42 | +│ │ │ │ │ |
| 43 | +│ │ │ Instrumentation happens ONLY at class load │ │ |
| 44 | +│ │ │ time. Already-loaded classes are never │ │ |
| 45 | +│ │ │ retransformed. │ │ |
| 46 | +│ │ └──────────────────────────────────────────────────┘ │ |
| 47 | +│ │ │ │ |
| 48 | +│ │ ┌──────────────────────────────────────────────────┐ │ |
| 49 | +│ │ │ Runtime │ │ |
| 50 | +│ │ │ │ │ |
| 51 | +│ │ │ Probes fire during normal code execution. │ │ |
| 52 | +│ │ │ Each probe sets a flag in a per-class │ │ |
| 53 | +│ │ │ boolean[], tracking which lines/branches ran. │ │ |
| 54 | +│ │ │ Data accumulates in JaCoCo runtime memory. │ │ |
| 55 | +│ │ └──────────────────────────────────────────────────┘ │ |
| 56 | +│ │ │ |
| 57 | +│ ▼ │ |
| 58 | +│ ┌─────────────────────────────────────────────────────────────────┐ │ |
| 59 | +│ │ Agent (Normal mode) OR TestwiseCoverageAgent │ │ |
| 60 | +│ │ │ │ |
| 61 | +│ │ HTTP server (Jetty + Jersey) for control: │ │ |
| 62 | +│ │ POST /dump ─── trigger coverage dump │ │ |
| 63 | +│ │ POST /test/start, /test/end ─── per-test coverage │ │ |
| 64 | +│ └─────────────────────────────────────────────────────────────────┘ │ |
| 65 | +│ │ |
| 66 | +└──────────────────────────────────────────────────────────────────────────┘ |
| 67 | + │ |
| 68 | + │ Periodically (default: every 10 min) or on HTTP request |
| 69 | + ▼ |
| 70 | +┌─────────────────────────────────────────────────────────────────────────┐ |
| 71 | +│ Coverage Dump Pipeline │ |
| 72 | +│ │ |
| 73 | +│ 1. JacocoRuntimeController.dumpAndReset() │ |
| 74 | +│ Retrieves execution data from JaCoCo runtime and resets probes. │ |
| 75 | +│ │ |
| 76 | +│ 2. JaCoCoXmlReportGenerator.convertSingleDumpToReport() │ |
| 77 | +│ Reads class files (from auto-created dump dir or user-specified │ |
| 78 | +│ class-dir), matches them with execution data by CRC64 class ID, │ |
| 79 | +│ and produces a JaCoCo XML coverage report. │ |
| 80 | +│ │ |
| 81 | +│ 3. IUploader.upload() │ |
| 82 | +│ Sends the XML report to the configured destination. │ |
| 83 | +│ │ |
| 84 | +└────────────────────────────┬────────────────────────────────────────────┘ |
| 85 | + │ |
| 86 | + ┌──────────────┼──────────────┐ |
| 87 | + ▼ ▼ ▼ |
| 88 | + ┌──────────┐ ┌───────────┐ ┌────────────┐ |
| 89 | + │Teamscale │ │Artifactory│ │Local disk │ |
| 90 | + │ Server │ │ / Azure │ │ │ |
| 91 | + └──────────┘ └───────────┘ └────────────┘ |
| 92 | +``` |
| 93 | + |
14 | 94 | ## Development |
15 | 95 |
|
16 | 96 | Before starting development, please enable the pre-commit hook by running: |
|
0 commit comments