-
Notifications
You must be signed in to change notification settings - Fork 387
Expand file tree
/
Copy pathbean-instantiations-startup.yml
More file actions
225 lines (186 loc) · 9.77 KB
/
Copy pathbean-instantiations-startup.yml
File metadata and controls
225 lines (186 loc) · 9.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
name: Check Bean Instantiations on Startup
on:
push:
branches: [ develop ]
paths:
- src/main/java/**
pull_request:
# TODO revert this before merging
# paths:
# - src/main/java/**
jobs:
build:
name: Check Bean Instantiations on Startup
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: '21'
- name: Build application
run: ./gradlew clean bootJar -x test -x webapp
- name: Start Spring Boot app
run: |
PROFILES=dev,localci,lti,aeolus,theia,iris,localvc,artemis,scheduling,buildagent,core,ldap
JAR=$(ls build/libs/Artemis*.jar | head -n1)
nohup java -jar $JAR \
--spring.profiles.active=$PROFILES \
--artemis.user-management.passkey.enabled=true \
--artemis.user-management.use-external=false \
--artemis.iris.url=http://iris.fake \
--artemis.iris.secret-token=token \
--spring.liquibase.enabled=false \
--spring.datasource.url="jdbc:h2:mem:mydb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE" \
--spring.datasource.username=sa \
--spring.datasource.password= \
--eureka.client.enabled=false \
--aeolus.url=http://aeolus.fake \
> app.log 2>&1 &
echo $! > app.pid
- name: Wait for the application to start
run: |
# Configuration variables
RUNNING_MESSAGE="'Artemis' is running!"
STARTUP_TIMEOUT_ATTEMPTS=30
STARTUP_RETRY_INTERVAL=2
STARTUP_TOTAL_TIMEOUT=$((STARTUP_TIMEOUT_ATTEMPTS * STARTUP_RETRY_INTERVAL))
LOG_FILE="app.log"
echo "Waiting up to ${STARTUP_TOTAL_TIMEOUT}s for $RUNNING_MESSAGE to appear in $LOG_FILE..."
isAppRunning=false
for i in $(seq 1 $STARTUP_TIMEOUT_ATTEMPTS); do
if grep -q "$RUNNING_MESSAGE" "$LOG_FILE"; then
isAppRunning=true
echo "✅ Found $RUNNING_MESSAGE in $LOG_FILE after $i attempts"
break
fi
echo " attempt $i/$STARTUP_TIMEOUT_ATTEMPTS: not found yet"
sleep $STARTUP_RETRY_INTERVAL
done
if [ "$isAppRunning" = false ]; then
echo "❌ Timeout: $RUNNING_MESSAGE not found in $LOG_FILE"
cat $LOG_FILE
exit 1
fi
- name: Extract and validate startup bean instantiation metrics
run: |
STARTUP_LOG_PATTERN="Bean instantiation graph exported to startupBeans\.dot \(([0-9]+) edges, longest dependency chain length: ([0-9]+)\)"
MIN_INSTANTIATED_BEANS=20
MAX_INSTANTIATED_BEANS=94
MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH=9
LOG_FILE="app.log"
# Extract search text from pattern (everything before opening parenthesis)
STARTUP_SEARCH=$(echo "$STARTUP_LOG_PATTERN" | sed 's/ \\(.*$//')
LINE=$(grep -E "$STARTUP_SEARCH" $LOG_FILE) \
|| { echo "❌ No startup metrics line found"; cat $LOG_FILE; exit 1; }
if [[ "$LINE" =~ $STARTUP_LOG_PATTERN ]]; then
INSTANTIATED_BEANS=${BASH_REMATCH[1]}
LONGEST_CHAIN_LENGTH=${BASH_REMATCH[2]}
else
echo "❌ Failed to parse startup metrics from: $LINE"
exit 1
fi
echo "• Number of instantiated beans = $INSTANTIATED_BEANS"
echo "• Longest dependency chain length = $LONGEST_CHAIN_LENGTH"
echo "Validating against thresholds: MIN_INSTANTIATED_BEANS=$MIN_INSTANTIATED_BEANS (expected ≥ $MIN_INSTANTIATED_BEANS), MAX_INSTANTIATED_BEANS=$MAX_INSTANTIATED_BEANS (expected ≤ $MAX_INSTANTIATED_BEANS), MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH=$MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH (expected ≤ $MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH)"
if (( INSTANTIATED_BEANS < MIN_INSTANTIATED_BEANS )); then
echo "❌ $INSTANTIATED_BEANS < $MIN_INSTANTIATED_BEANS beans. Something seems to be wrong, as usually more beans are instantiated."
exit 1
fi
if (( INSTANTIATED_BEANS > MAX_INSTANTIATED_BEANS )); then
echo "❌ $INSTANTIATED_BEANS > $MAX_INSTANTIATED_BEANS threshold"
exit 1
fi
if (( LONGEST_CHAIN_LENGTH > MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH )); then
echo "❌ Longest dependency chain length $LONGEST_CHAIN_LENGTH > $MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH threshold"
exit 1
fi
echo "✅ Final values → Beans: $INSTANTIATED_BEANS; Longest dependency chain length: $LONGEST_CHAIN_LENGTH"
echo "🎉 Startup bean instantiation metrics within expected ranges"
# Export variables for next step
echo "LONGEST_CHAIN_LENGTH=$LONGEST_CHAIN_LENGTH" >> $GITHUB_ENV
- name: Check for startup dependency chains exceeding threshold
run: |
STARTUP_DEEP_CHAIN_PATTERN="Startup long bean instantiation chain"
MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH=9
LOG_FILE="app.log"
echo "Checking for startup dependency chains exceeding threshold..."
if (( LONGEST_CHAIN_LENGTH > MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH )); then
echo "❌ Startup dependency chain length $LONGEST_CHAIN_LENGTH > $MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH threshold"
echo "Chains exceeding threshold:"
grep -E "$STARTUP_DEEP_CHAIN_PATTERN" $LOG_FILE || echo " (No detailed chains found in log)"
echo "🔧 These chains violate the threshold MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH. Please refactor them to break these chains."
exit 1
else
echo "✅ No startup dependency chains exceed the threshold of $MAX_STARTUP_DEPENDENCY_CHAIN_LENGTH"
fi
- name: Extract and validate deferred eager bean chain length
run: |
DEFERRED_BEAN_PATTERN="Maximum dependency chain length during deferred eager init: ([0-9]+)"
DEFERRED_TIMEOUT_ATTEMPTS=10
DEFERRED_RETRY_INTERVAL=12
DEFERRED_TOTAL_TIMEOUT=$((DEFERRED_TIMEOUT_ATTEMPTS * DEFERRED_RETRY_INTERVAL))
MIN_DEFERRED_CHAIN_LENGTH=1
MAX_DEFERRED_CHAIN_LENGTH=15
LOG_FILE="app.log"
LOG_TAIL_LINES=50
# Extract search text from pattern (everything before :)
DEFERRED_BEAN_SEARCH=$(echo "$DEFERRED_BEAN_PATTERN" | sed 's/:.*$//')
echo "Waiting for deferred eager bean initialization to complete..."
DEFERRED_LINE=""
for i in $(seq 1 $DEFERRED_TIMEOUT_ATTEMPTS); do
DEFERRED_LINE=$(grep -E "$DEFERRED_BEAN_SEARCH" $LOG_FILE 2>/dev/null || true)
if [ -n "$DEFERRED_LINE" ]; then
echo "✅ Found deferred eager bean initialization log after $i attempts"
break
fi
echo " attempt $i/$DEFERRED_TIMEOUT_ATTEMPTS: deferred eager bean initialization not completed yet"
sleep $DEFERRED_RETRY_INTERVAL
done
if [ -z "$DEFERRED_LINE" ]; then
echo "❌ No deferred eager bean chain length line found after ${DEFERRED_TOTAL_TIMEOUT}s"
echo "Last $LOG_TAIL_LINES lines of $LOG_FILE:"
cat $LOG_FILE
exit 1
fi
if [[ "$DEFERRED_LINE" =~ $DEFERRED_BEAN_PATTERN ]]; then
DEFERRED_CHAIN_LENGTH=${BASH_REMATCH[1]}
else
echo "❌ Failed to parse deferred eager bean chain length from: $DEFERRED_LINE"
exit 1
fi
echo "• Maximum dependency chain length during deferred eager bean initialization = $DEFERRED_CHAIN_LENGTH"
echo "Validating against thresholds: MIN_DEFERRED_CHAIN_LENGTH=$MIN_DEFERRED_CHAIN_LENGTH (expected ≥ $MIN_DEFERRED_CHAIN_LENGTH), MAX_DEFERRED_CHAIN_LENGTH=$MAX_DEFERRED_CHAIN_LENGTH (expected ≤ $MAX_DEFERRED_CHAIN_LENGTH)"
if (( DEFERRED_CHAIN_LENGTH < MIN_DEFERRED_CHAIN_LENGTH )); then
echo "❌ Deferred chain length $DEFERRED_CHAIN_LENGTH < $MIN_DEFERRED_CHAIN_LENGTH. Something seems to be wrong, as usually some deferred beans are instantiated."
exit 1
fi
if (( DEFERRED_CHAIN_LENGTH > MAX_DEFERRED_CHAIN_LENGTH )); then
echo "❌ Deferred chain length $DEFERRED_CHAIN_LENGTH > $MAX_DEFERRED_CHAIN_LENGTH threshold"
exit 1
fi
echo "✅ Deferred eager bean chain length: $DEFERRED_CHAIN_LENGTH"
echo "🎉 Deferred eager bean dependency chain length within expected ranges"
# Export variable for next step
echo "DEFERRED_CHAIN_LENGTH=$DEFERRED_CHAIN_LENGTH" >> $GITHUB_ENV
- name: Check for deferred dependency chains exceeding threshold
run: |
# Configuration variables
DEFERRED_DEEP_CHAIN_PATTERN="Deferred long bean instantiation chain"
MAX_DEFERRED_DEPENDENCY_CHAIN_LENGTH=15
LOG_FILE="app.log"
echo "Checking for deferred dependency chains exceeding threshold..."
if (( DEFERRED_CHAIN_LENGTH > MAX_DEFERRED_DEPENDENCY_CHAIN_LENGTH )); then
echo "❌ Deferred dependency chain length $DEFERRED_CHAIN_LENGTH > $MAX_DEFERRED_DEPENDENCY_CHAIN_LENGTH threshold"
echo "Chains exceeding threshold:"
grep -E "$DEFERRED_DEEP_CHAIN_PATTERN" $LOG_FILE || echo " (No detailed chains found in log)"
echo "🔧 These chains violate the threshold MAX_DEFERRED_DEPENDENCY_CHAIN_LENGTH. Please refactor them to break these chains."
exit 1
else
echo "✅ No deferred dependency chains exceed the threshold of $MAX_DEFERRED_DEPENDENCY_CHAIN_LENGTH"
fi
- name: Stop application
if: always()
run: kill $(<app.pid) || true