nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 fetchpatch,
6 gradle,
7 jdk17,
8 jre,
9 makeWrapper,
10 coreutils,
11 gitMinimal,
12}:
13
14stdenv.mkDerivation (finalAttrs: {
15 pname = "jmeter";
16 version = "5.6.3";
17
18 src = fetchFromGitHub {
19 owner = "apache";
20 repo = "jmeter";
21 rev = "rel/v${finalAttrs.version}";
22 hash = "sha256-mYjQs32SDoUB6SLXvEVOyxU68b8QRv39XxE3fvn4oNM=";
23 };
24
25 patches = [
26 # Fix for read-only installations (e.g., Nix store)
27 # Ensures directories are writable when generating reports from read-only sources
28 # Upstream: https://github.com/apache/jmeter/pull/6358
29 (fetchpatch {
30 url = "https://github.com/apache/jmeter/commit/f4f1ef144ab5678bddb010ed1f05c67a76f547a5.patch";
31 hash = "sha256-ICG2z+nyJT0WDiYmU/Dx3VtkG83ymU7HwYjEuJMjaiY=";
32 excludes = [ "xdocs/changes.xml" ];
33 })
34 ];
35
36 nativeBuildInputs = [
37 gradle
38 # JMeter's Gradle build-logic uses toolchains that explicitly request Java 17
39 jdk17
40 makeWrapper
41 gitMinimal
42 ];
43
44 mitmCache = gradle.fetchDeps {
45 inherit (finalAttrs) pname;
46 data = ./deps.json;
47 };
48
49 # Required for mitm-cache on Darwin
50 __darwinAllowLocalNetworking = true;
51
52 gradleFlags = [
53 # Point Gradle toolchain to the JDK we provide
54 "-Dorg.gradle.java.home=${jdk17}"
55 # Skip javadoc which tries to fetch external URLs
56 "-x"
57 "javadocAggregate"
58 # Skip checksum verification for dependencies
59 # we handle those ourself in `./deps.json`
60 "-PchecksumIgnore"
61 ];
62
63 # Build the distribution
64 gradleBuildTask = ":src:dist:assemble";
65
66 installPhase = ''
67 runHook preInstall
68
69 # Extract the built distribution
70 # Note: Built distributions have -SNAPSHOT suffix
71 mkdir -p $out
72 tar -xzf src/dist/build/distributions/apache-jmeter-${finalAttrs.version}-SNAPSHOT.tgz \
73 --strip-components=1 -C $out
74
75 # Remove Windows-specific files
76 rm -f $out/bin/*.bat $out/bin/*.cmd
77
78 # Fix create-rmi-keystore.sh to use the correct keytool path
79 substituteInPlace $out/bin/create-rmi-keystore.sh \
80 --replace-fail "keytool -genkey" "${jre}/lib/openjdk/jre/bin/keytool -genkey"
81
82 # Fix mirror-server.sh classpath: discover actual jar names at build time
83 # The script has hardcoded jar versions that don't match the built jars
84 substituteInPlace $out/bin/mirror-server.sh \
85 --replace-fail "oro-2.0.8.jar" "$(basename $out/lib/oro-*.jar)" \
86 --replace-fail "slf4j-api-1.7.25.jar" "$(basename $out/lib/slf4j-api-*.jar)" \
87 --replace-fail "jcl-over-slf4j-1.7.25.jar" "$(basename $out/lib/jcl-over-slf4j-*.jar)" \
88 --replace-fail "log4j-slf4j-impl-2.11.0.jar" "$(basename $out/lib/log4j-slf4j-impl-*.jar)" \
89 --replace-fail "log4j-api-2.11.1.jar" "$(basename $out/lib/log4j-api-*.jar)" \
90 --replace-fail "log4j-core-2.11.1.jar" "$(basename $out/lib/log4j-core-*.jar)" \
91 --replace-fail "log4j-1.2-api-2.11.1.jar" "$(basename $out/lib/log4j-1.2-api-*.jar)"
92
93 # Prefix some scripts with jmeter to avoid clobbering the namespace
94 for i in heapdump.sh mirror-server mirror-server.sh shutdown.sh stoptest.sh create-rmi-keystore.sh; do
95 mv $out/bin/$i $out/bin/jmeter-$i
96 wrapProgram $out/bin/jmeter-$i \
97 --prefix PATH : "${jre}/bin"
98 done
99
100 wrapProgram $out/bin/jmeter --set JAVA_HOME "${jre}"
101 wrapProgram $out/bin/jmeter.sh --set JAVA_HOME "${jre}"
102
103 runHook postInstall
104 '';
105
106 nativeCheckInputs = [ coreutils ];
107
108 installCheckPhase = ''
109 runHook preInstallCheck
110
111 set -x
112
113 # Test basic functionality
114 $out/bin/jmeter --version 2>&1 | grep -q "${finalAttrs.version}"
115
116 # Test helper scripts
117 $out/bin/jmeter-heapdump.sh > /dev/null
118 $out/bin/jmeter-shutdown.sh > /dev/null
119 $out/bin/jmeter-stoptest.sh > /dev/null
120 timeout --kill=1s 1s $out/bin/jmeter-mirror-server.sh || test "$?" = "124"
121
122 # Test HTML report generation (regression test for Nix store read-only issue)
123 echo "Testing HTML report generation..."
124
125 # Create minimal test results file (using actual JMeter CSV format)
126 TMPDIR=$(mktemp -d)
127 cat > $TMPDIR/test-results.jtl << 'EOF'
128 timeStamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect
129 1699123200000,100,HTTP Request,200,OK,Thread Group 1-1,text,true,,805,113,1,1,https://example.com/,95,0,25
130 1699123201000,150,HTTP Request,200,OK,Thread Group 1-1,text,true,,805,113,1,1,https://example.com/,140,0,30
131 1699123202000,200,HTTP Request,500,Internal Server Error,Thread Group 1-1,text,false,Server Error,512,113,1,1,https://example.com/,180,0,40
132 EOF
133
134 # Generate HTML report
135 echo "Generating HTML report..."
136 $out/bin/jmeter -g $TMPDIR/test-results.jtl -o $TMPDIR/test-report 2>/dev/null
137
138 # Verify the report was generated successfully
139 echo "Verifying report generation..."
140 test -f $TMPDIR/test-report/index.html
141 test -f $TMPDIR/test-report/statistics.json
142 test -d $TMPDIR/test-report/sbadmin2-1.0.7
143
144 # Verify the HTML contains expected content
145 grep -q "Apache JMeter Dashboard" $TMPDIR/test-report/index.html
146
147 # Verify statistics contain the test data
148 grep -q "HTTP Request" $TMPDIR/test-report/statistics.json
149
150 echo "HTML report generation test passed!"
151
152 runHook postInstallCheck
153 '';
154
155 meta = {
156 description = "100% pure Java desktop application designed to load test functional behavior and measure performance";
157 longDescription = ''
158 The Apache JMeter desktop application is open source software, a 100%
159 pure Java application designed to load test functional behavior and
160 measure performance. It was originally designed for testing Web
161 Applications but has since expanded to other test functions.
162 '';
163 homepage = "https://jmeter.apache.org/";
164 changelog = "https://github.com/apache/jmeter/releases/tag/rel%2Fv${finalAttrs.version}";
165 license = lib.licenses.asl20;
166 maintainers = [ ];
167 sourceProvenance = with lib.sourceTypes; [
168 fromSource
169 binaryBytecode # mitm cache
170 ];
171 platforms = lib.platforms.unix;
172 mainProgram = "jmeter";
173 };
174})