-
Notifications
You must be signed in to change notification settings - Fork 0
243 lines (206 loc) · 9.76 KB
/
performance.yml
File metadata and controls
243 lines (206 loc) · 9.76 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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
name: Performance Tests
on:
schedule:
# Run weekly on Sundays at 2 AM UTC
- cron: '0 2 * * 0'
workflow_dispatch:
inputs:
dataset_size:
description: 'Number of test bookmarks'
required: false
default: '1000'
type: string
env:
CI: true
NODE_ENV: test
jobs:
performance-tests:
name: Performance Benchmarks
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20.x
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Setup performance test environment
run: |
echo "Setting up performance test environment..."
mkdir -p performance-results
# Create performance test data
node -e "
const fs = require('fs');
const datasetSize = parseInt('${{ github.event.inputs.dataset_size || '1000' }}');
console.log('Creating test dataset with', datasetSize, 'bookmarks...');
const bookmarks = [];
for (let i = 0; i < datasetSize; i++) {
bookmarks.push({
id: 'bookmark-' + i,
title: 'Test Bookmark ' + i,
url: 'https://example.com/page-' + i,
description: 'Test description for bookmark number ' + i,
tags: ['tag' + (i % 10), 'category' + (i % 5)],
created: new Date(Date.now() - i * 60000).toISOString(),
visited: i % 3 === 0,
folder: 'folder-' + Math.floor(i / 100)
});
}
fs.writeFileSync('performance-test-data.json', JSON.stringify(bookmarks, null, 2));
console.log('Test dataset created with', bookmarks.length, 'bookmarks');
"
- name: Run search performance tests
run: |
echo "Running search performance benchmarks..."
node -e "
const { performance } = require('perf_hooks');
// Mock search implementation for performance testing
function mockSearchIndex(bookmarks, query) {
const start = performance.now();
const results = bookmarks.filter(b =>
b.title.toLowerCase().includes(query.toLowerCase()) ||
b.description.toLowerCase().includes(query.toLowerCase()) ||
b.tags.some(tag => tag.toLowerCase().includes(query.toLowerCase()))
);
const end = performance.now();
return { results, duration: end - start };
}
const fs = require('fs');
const bookmarks = JSON.parse(fs.readFileSync('performance-test-data.json', 'utf8'));
const queries = ['test', 'bookmark', 'example', 'page', 'tag1', 'category2'];
console.log('Search Performance Results:');
console.log('==========================');
const results = [];
queries.forEach(query => {
const { results: searchResults, duration } = mockSearchIndex(bookmarks, query);
console.log('Query: \"' + query + '\"');
console.log(' Results: ' + searchResults.length);
console.log(' Duration: ' + duration.toFixed(2) + 'ms');
console.log('');
results.push({
query,
resultCount: searchResults.length,
duration: duration,
throughput: searchResults.length / (duration / 1000)
});
});
// Check for performance regressions
const avgDuration = results.reduce((sum, r) => sum + r.duration, 0) / results.length;
console.log('Average search duration: ' + avgDuration.toFixed(2) + 'ms');
const maxAcceptableDuration = 50; // 50ms max for search
if (avgDuration > maxAcceptableDuration) {
console.log('❌ Performance regression detected!');
console.log('Average search duration (' + avgDuration.toFixed(2) + 'ms) exceeds threshold (' + maxAcceptableDuration + 'ms)');
process.exit(1);
} else {
console.log('✅ Search performance within acceptable range');
}
// Save results for trending
fs.writeFileSync('performance-results/search-results.json', JSON.stringify(results, null, 2));
"
- name: Run memory usage tests
run: |
echo "Running memory usage benchmarks..."
node -e "
const fs = require('fs');
const { performance } = require('perf_hooks');
// Simulate bookmark storage and retrieval
function measureMemoryUsage(bookmarks) {
const initialMemory = process.memoryUsage();
// Simulate operations
const storage = new Map();
bookmarks.forEach(bookmark => {
storage.set(bookmark.id, bookmark);
});
// Force garbage collection if available
if (global.gc) {
global.gc();
}
const finalMemory = process.memoryUsage();
return {
heapUsed: finalMemory.heapUsed - initialMemory.heapUsed,
heapTotal: finalMemory.heapTotal - initialMemory.heapTotal,
external: finalMemory.external - initialMemory.external,
arrayBuffers: finalMemory.arrayBuffers - initialMemory.arrayBuffers
};
}
const bookmarks = JSON.parse(fs.readFileSync('performance-test-data.json', 'utf8'));
const memoryUsage = measureMemoryUsage(bookmarks);
console.log('Memory Usage Analysis:');
console.log('=====================');
console.log('Dataset size: ' + bookmarks.length + ' bookmarks');
console.log('Heap used: ' + (memoryUsage.heapUsed / 1024 / 1024).toFixed(2) + ' MB');
console.log('Heap total: ' + (memoryUsage.heapTotal / 1024 / 1024).toFixed(2) + ' MB');
console.log('External: ' + (memoryUsage.external / 1024 / 1024).toFixed(2) + ' MB');
console.log('Array buffers: ' + (memoryUsage.arrayBuffers / 1024 / 1024).toFixed(2) + ' MB');
// Memory usage per bookmark
const memoryPerBookmark = memoryUsage.heapUsed / bookmarks.length;
console.log('Memory per bookmark: ' + memoryPerBookmark.toFixed(0) + ' bytes');
// Check for memory issues
const maxMemoryPerBookmark = 1024; // 1KB per bookmark max
if (memoryPerBookmark > maxMemoryPerBookmark) {
console.log('❌ High memory usage detected!');
console.log('Memory per bookmark (' + memoryPerBookmark.toFixed(0) + ' bytes) exceeds threshold (' + maxMemoryPerBookmark + ' bytes)');
process.exit(1);
} else {
console.log('✅ Memory usage within acceptable range');
}
fs.writeFileSync('performance-results/memory-results.json', JSON.stringify({
datasetSize: bookmarks.length,
memoryUsage,
memoryPerBookmark,
timestamp: new Date().toISOString()
}, null, 2));
"
- name: Generate performance report
run: |
echo "Generating performance report..."
node -e "
const fs = require('fs');
const searchResults = JSON.parse(fs.readFileSync('performance-results/search-results.json', 'utf8'));
const memoryResults = JSON.parse(fs.readFileSync('performance-results/memory-results.json', 'utf8'));
const report = {
timestamp: new Date().toISOString(),
datasetSize: memoryResults.datasetSize,
search: {
averageDuration: searchResults.reduce((sum, r) => sum + r.duration, 0) / searchResults.length,
maxDuration: Math.max(...searchResults.map(r => r.duration)),
minDuration: Math.min(...searchResults.map(r => r.duration)),
totalQueries: searchResults.length
},
memory: {
heapUsedMB: memoryResults.memoryUsage.heapUsed / 1024 / 1024,
memoryPerBookmarkBytes: memoryResults.memoryPerBookmark
}
};
console.log('Performance Report Summary:');
console.log('==========================');
console.log(JSON.stringify(report, null, 2));
fs.writeFileSync('performance-results/performance-report.json', JSON.stringify(report, null, 2));
"
- name: Upload performance results
uses: actions/upload-artifact@v4
with:
name: performance-results-${{ github.run_id }}
path: performance-results/
retention-days: 90
- name: Performance summary
run: |
echo "## Performance Test Results" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Test Configuration" >> $GITHUB_STEP_SUMMARY
echo "- Dataset size: ${{ github.event.inputs.dataset_size || '1000' }} bookmarks" >> $GITHUB_STEP_SUMMARY
echo "- Test run: $(date)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Results" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`json" >> $GITHUB_STEP_SUMMARY
cat performance-results/performance-report.json >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Benchmarks" >> $GITHUB_STEP_SUMMARY
echo "- Search queries must complete within 50ms average" >> $GITHUB_STEP_SUMMARY
echo "- Memory usage must not exceed 1KB per bookmark" >> $GITHUB_STEP_SUMMARY