Skip to content

Commit 02103d0

Browse files
committed
wip
Signed-off-by: Attila Mészáros <a_meszaros@apple.com>
1 parent 337c321 commit 02103d0

File tree

5 files changed

+105
-39
lines changed

5 files changed

+105
-39
lines changed

.github/scripts/performance-to-markdown.py

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,46 +2,87 @@
22
import json
33
import sys
44
import os
5+
import glob
56

6-
def convert_to_markdown(json_file):
7+
def load_all_summaries(json_files):
8+
"""Load summaries from all JSON files and group by test name"""
9+
summaries_by_name = {}
10+
11+
for json_file in json_files:
12+
try:
13+
with open(json_file, 'r') as f:
14+
data = json.load(f)
15+
16+
if 'summaries' in data and data['summaries']:
17+
for summary in data['summaries']:
18+
name = summary.get('name', 'Unknown Test')
19+
if name not in summaries_by_name:
20+
summaries_by_name[name] = []
21+
summaries_by_name[name].append(summary)
22+
except (FileNotFoundError, json.JSONDecodeError) as e:
23+
print(f"Warning: Error processing {json_file}: {e}", file=sys.stderr)
24+
continue
25+
26+
return summaries_by_name
27+
28+
def convert_to_markdown(json_files):
729
"""Convert performance test JSON results to markdown format"""
8-
try:
9-
with open(json_file, 'r') as f:
10-
data = json.load(f)
11-
except FileNotFoundError:
30+
summaries_by_name = load_all_summaries(json_files)
31+
32+
if not summaries_by_name:
1233
return "## Performance Test Results\n\nNo performance test results found."
13-
except json.JSONDecodeError:
14-
return "## Performance Test Results\n\nError parsing performance test results."
1534

1635
markdown = "## Performance Test Results\n\n"
1736

18-
if 'summaries' not in data or not data['summaries']:
19-
return markdown + "No test summaries available."
37+
# Create a table for each test name
38+
for name, summaries in sorted(summaries_by_name.items()):
39+
markdown += f"### {name}\n\n"
40+
markdown += "| Duration (ms) | Max Memory (GB) | Processors | Parameters |\n"
41+
markdown += "|---------------|-----------------|------------|------------|\n"
2042

21-
for summary in data['summaries']:
22-
name = summary.get('name', 'Unknown Test')
23-
duration = summary.get('duration', 0)
24-
processors = summary.get('numberOfProcessors', 0)
25-
max_memory = summary.get('maxMemory', 0)
43+
for summary in summaries:
44+
duration = summary.get('duration', 0)
45+
processors = summary.get('numberOfProcessors', 0)
46+
max_memory = summary.get('maxMemory', 0)
2647

27-
# Convert memory from bytes to GB
28-
max_memory_gb = max_memory / (1024 ** 3) if max_memory > 0 else 0
48+
# Convert memory from bytes to GB
49+
max_memory_gb = max_memory / (1024 ** 3) if max_memory > 0 else 0
50+
51+
# Extract dynamic properties (excluding standard fields)
52+
standard_fields = {'name', 'duration', 'numberOfProcessors', 'maxMemory'}
53+
params = []
54+
for key, value in summary.items():
55+
if key not in standard_fields:
56+
params.append(f"{key}={value}")
57+
58+
params_str = ", ".join(params) if params else "-"
59+
60+
markdown += f"| {duration} | {max_memory_gb:.2f} | {processors} | {params_str} |\n"
2961

30-
markdown += f"### {name}\n\n"
31-
markdown += "| Metric | Value |\n"
32-
markdown += "|--------|-------|\n"
33-
markdown += f"| Duration | {duration} ms |\n"
34-
markdown += f"| Processors | {processors} |\n"
35-
markdown += f"| Max Memory | {max_memory_gb:.2f} GB |\n"
3662
markdown += "\n"
3763

3864
return markdown
3965

4066
if __name__ == "__main__":
41-
if len(sys.argv) != 2:
42-
print("Usage: performance-to-markdown.py <json_file>")
67+
if len(sys.argv) < 2:
68+
print("Usage: performance-to-markdown.py <json_file> [json_file2 ...]")
69+
print(" or: performance-to-markdown.py <glob_pattern>")
4370
sys.exit(1)
4471

45-
json_file = sys.argv[1]
46-
markdown = convert_to_markdown(json_file)
72+
# Collect all JSON files from arguments (supporting both direct files and glob patterns)
73+
json_files = []
74+
for arg in sys.argv[1:]:
75+
if '*' in arg:
76+
json_files.extend(glob.glob(arg, recursive=True))
77+
else:
78+
json_files.append(arg)
79+
80+
# Filter to only existing files
81+
json_files = [f for f in json_files if os.path.isfile(f)]
82+
83+
if not json_files:
84+
print("## Performance Test Results\n\nNo performance test results found.")
85+
sys.exit(0)
86+
87+
markdown = convert_to_markdown(json_files)
4788
print(markdown)

.github/workflows/integration-tests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,14 @@ jobs:
4444
minikube version: 'v1.36.0'
4545
kubernetes version: '${{ inputs.kube-version }}'
4646
github token: ${{ github.token }}
47-
4847
- name: "${{inputs.it-category}} integration tests (kube: ${{ inputs.kube-version }} / java: ${{ inputs.java-version }} / client: ${{ inputs.http-client }})"
4948
run: |
5049
if [ -z "${{inputs.it-category}}" ]; then
5150
it_profile="integration-tests"
5251
else
5352
it_profile="integration-tests-${{inputs.it-category}}"
5453
fi
54+
echo "{ "kube-version":"${{inputs.kube-version}}", "java-version":"${{ inputs.java-version }}","http-client":"${{inputs.http-client}}"}" >> run-properties.json
5555
echo "Using profile: ${it_profile}"
5656
./mvnw ${MAVEN_ARGS} -T1C -B install -DskipTests -Pno-apt --file pom.xml
5757
./mvnw ${MAVEN_ARGS} -T1C -B package -P${it_profile} -Dfabric8-httpclient-impl.name=${{inputs.http-client}} --file pom.xml

.github/workflows/pr.yml

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ jobs:
5252
- name: Check for performance results
5353
id: check_results
5454
run: |
55-
if [ -d "performance-results" ] && [ "$(ls -A performance-results/*.json 2>/dev/null)" ]; then
55+
if [ -d "performance-results" ] && [ "$(ls -A performance-results/**/*.json 2>/dev/null)" ]; then
5656
echo "Has results"
5757
echo "has_results=true" >> $GITHUB_OUTPUT
5858
else
@@ -64,15 +64,7 @@ jobs:
6464
if: steps.check_results.outputs.has_results == 'true'
6565
id: convert
6666
run: |
67-
echo "# Performance Test Results" > comment.md
68-
echo "" >> comment.md
69-
for file in performance-results/*.json; do
70-
if [ -f "$file" ]; then
71-
echo "Processing $file"
72-
python3 .github/scripts/performance-to-markdown.py "$file" >> comment.md
73-
echo "" >> comment.md
74-
fi
75-
done
67+
python3 .github/scripts/performance-to-markdown.py performance-results/**/*.json > comment.md
7668
7769
- name: Post PR comment
7870
if: steps.check_results.outputs.has_results == 'true' && github.event_name == 'pull_request'

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/performance/PerformanceTestResult.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,27 @@
1515
*/
1616
package io.javaoperatorsdk.operator.baseapi.performance;
1717

18+
import com.fasterxml.jackson.annotation.JsonAnyGetter;
19+
import com.fasterxml.jackson.annotation.JsonAnySetter;
20+
21+
import java.util.HashMap;
1822
import java.util.List;
23+
import java.util.Map;
1924

2025
public class PerformanceTestResult {
2126

27+
private final Map<String, Object> additionalProperties = new HashMap<>();
28+
29+
@JsonAnySetter
30+
public void addProperty(String key, Object value) {
31+
additionalProperties.put(key, value);
32+
}
33+
34+
@JsonAnyGetter
35+
public Map<String, Object> getProperties() {
36+
return additionalProperties;
37+
}
38+
2239
private List<PerformanceTestSummary> summaries;
2340

2441
public List<PerformanceTestSummary> getSummaries() {

operator-framework/src/test/java/io/javaoperatorsdk/operator/baseapi/performance/SimplePerformanceTestIT.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.io.File;
1919
import java.io.IOException;
2020
import java.util.ArrayList;
21+
import java.util.HashMap;
2122
import java.util.List;
2223
import java.util.Map;
2324
import java.util.Set;
@@ -39,7 +40,7 @@
3940
import com.fasterxml.jackson.databind.ObjectMapper;
4041

4142
public class SimplePerformanceTestIT {
42-
43+
ObjectMapper objectMapper = new ObjectMapper();
4344
private static final Logger log = LoggerFactory.getLogger(SimplePerformanceTestIT.class);
4445
public static final String INITIAL_VALUE = "initialValue";
4546
public static final String RESOURCE_NAME_PREFIX = "resource";
@@ -89,19 +90,34 @@ void simpleNaivePerformanceTest() {
8990
private void saveResults(long duration) {
9091
try {
9192
var result = new PerformanceTestResult();
93+
getRunProperties().forEach((k,v)->result.addProperty(k,v));
9294
var summary = new PerformanceTestSummary();
9395
result.setSummaries(List.of(summary));
9496
summary.setName("Naive performance test");
9597
summary.setDuration(duration);
9698
summary.setNumberOfProcessors(Runtime.getRuntime().availableProcessors());
9799
summary.setMaxMemory(Runtime.getRuntime().maxMemory());
98-
var objectMapper = new ObjectMapper();
100+
99101
objectMapper.writeValue(new File("target/performance_test_result.json"), result);
100102
} catch (IOException e) {
101103
throw new RuntimeException(e);
102104
}
103105
}
104106

107+
private Map<String, Object> getRunProperties() {
108+
try {
109+
File runProperties = new File("../run-properties.json");
110+
if (runProperties.exists()) {
111+
return objectMapper.readValue(runProperties, HashMap.class);
112+
} else {
113+
log.warn("No run properties file found");
114+
return Map.of();
115+
}
116+
} catch (IOException e) {
117+
throw new RuntimeException(e);
118+
}
119+
}
120+
105121
private void createResources(int startIndex, int number, String value) {
106122
try {
107123
List<Callable<Void>> callables = new ArrayList<>(number);

0 commit comments

Comments
 (0)