Skip to content

Commit eabecdb

Browse files
authored
feat: optimize docker for test (#97)
1 parent 7fc1420 commit eabecdb

File tree

5 files changed

+523
-76
lines changed

5 files changed

+523
-76
lines changed

.dev/07-docker-test-optimization.md

Lines changed: 86 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -111,30 +111,63 @@ fn init_repo(&self, test_dir: &TestDir) -> io::Result<()> {
111111
- Enhanced test error handling for better flakiness detection
112112
- `test_get_vcs_data_with_commit` improved with detailed diagnostics
113113

114-
### **Phase 2: Parallelization (Advanced)**
114+
### **Phase 2: Parallelization (Advanced) - ❌ REVERTED**
115+
116+
- ✅ Implement container pool for parallel tests
117+
- ✅ Add thread-safe container management
118+
- ✅ Update test execution to use parallel containers
119+
-**Expected Speedup**: Additional 40-50%
120+
121+
**❌ PHASE 2 REVERSION NOTES**:
122+
123+
- Container pool functionality integrated directly into `DockerGit` struct
124+
- Thread-safe management using `Arc<Mutex<VecDeque<PooledContainer>>>`
125+
- Parallel execution enabled by default in all Docker Git operations
126+
- Container acquisition/release mechanisms with automatic cleanup
127+
- Pool limits: max 4 containers, 5-minute max age, 1-minute idle timeout
128+
- Zero flakiness detected in 10-iteration test loop
129+
- All functionality consolidated into single `DockerGit` implementation
130+
- **REVERTED**: Performance improvement was only 4.3% (140s → 134s)
131+
- **REVERTED**: Added 400+ lines of complex container pool management code
132+
- **REVERTED**: High risk of flaky tests due to parallel container execution
133+
- **REVERTED**: Maintenance burden outweighed minimal performance benefit
134+
135+
### **Phase 3: Batch Operations (Experimental) - ✅ COMPLETED**
136+
137+
⚠️ **Note**: This phase was initially considered experimental because the Docker image already includes git command and we just pass its subcommands. However, the batching approach works well by combining multiple git commands into single shell scripts.
138+
139+
- ✅ Modify `GitOperations` methods to batch operations
140+
- ✅ Update `init_repo()`, `create_commit()` methods with batch versions
141+
- ✅ Test batch operation error handling
142+
-**Expected Speedup**: Additional 20-30%
143+
144+
**✅ PHASE 3 COMPLETION NOTES**:
145+
146+
- Batch operations implemented in `DockerGit` struct and enabled by default
147+
- `init_repo_batch()` combines git init, config, file creation, add, and commit
148+
- `create_commit_batch()` combines git add and commit in single call
149+
- `create_tag_and_commit_batch()` combines add, commit, and tag operations
150+
- `run_batch_git_commands()` executes multiple git commands in single Docker call
151+
- **Simplified approach**: No environment variable needed - batch operations are the default
152+
- `GitOperations` trait methods (`init_repo()`, `create_commit()`) use batch operations automatically
153+
- Proper shell escaping for special characters in commit messages
154+
- Comprehensive test coverage for all batch operations
115155

116-
- [ ] Implement container pool for parallel tests
117-
- [ ] Add thread-safe container management
118-
- [ ] Update test execution to use parallel containers
119-
- [ ] **Expected Speedup**: Additional 40-50%
120-
121-
### **Phase 3: Batch Operations (Experimental - May Not Work)**
122-
123-
⚠️ **Note**: This phase may not work as expected because the Docker image already includes git command and we just pass its subcommands. The batching approach might conflict with how Docker handles git command execution.
156+
## 🎯 **Expected Performance Results**
124157

125-
- [ ] Modify `GitOperations` methods to batch operations
126-
- [ ] Update `init_repo()`, `create_commit()`, `create_tag()` methods
127-
- [ ] Test batch operation error handling
128-
- [ ] **Expected Speedup**: Additional 20-30% (if feasible)
158+
| Optimization Phase | Current Time | Optimized Time | Speedup | Status |
159+
| ------------------ | ------------ | -------------- | -------- | ------------ |
160+
| Container Reuse | 100% | 20-30% | 3-5x | ✅ COMPLETED |
161+
| + Parallelization | 20-30% | 10-15% | 2x | ❌ REVERTED |
162+
| + Batch Operations | 20-30% | 15-20% | 1.3-2x | ✅ COMPLETED |
163+
| **Total** | **100%** | **15-20%** | **5-6x** | **66% DONE** |
129164

130-
## 🎯 **Expected Performance Results**
165+
### **Actual Phase 2 Results (Reverted):**
131166

132-
| Optimization Phase | Current Time | Optimized Time | Speedup |
133-
| ------------------ | ------------ | -------------- | ---------------- |
134-
| Container Reuse | 100% | 20-30% | 3-5x |
135-
| + Parallelization | 20-30% | 10-15% | 2x |
136-
| + Batch Operations | 10-15% | 5-8% | 2x (if feasible) |
137-
| **Total** | **100%** | **5-8%** | **12-20x** |
167+
- **Before**: ~140s average test execution time
168+
- **After**: ~134s average test execution time
169+
- **Improvement**: Only 6 seconds (4.3% faster)
170+
- **Verdict**: Insufficient improvement to justify complexity
138171

139172
## 🔧 **Implementation Details**
140173

@@ -145,11 +178,25 @@ fn init_repo(&self, test_dir: &TestDir) -> io::Result<()> {
145178
3. `src/test_utils/mod.rs` - Add optimization flags
146179
4. `src/config.rs` - Add optimization environment variables
147180

148-
### **New Environment Variables:**
181+
### **Environment Variables:**
149182

150-
- `ZERV_TEST_DOCKER_OPTIMIZE=true` - Enable container reuse
151-
- `ZERV_TEST_DOCKER_PARALLEL=true` - Enable parallel execution
152-
- `ZERV_TEST_DOCKER_BATCH=true` - Enable batched operations
183+
- `ZERV_TEST_NATIVE_GIT=true` - Use native Git instead of Docker (for CI)
184+
- `ZERV_TEST_DOCKER=true` - Enable Docker tests (default)
185+
186+
**Note**: Container reuse and batch operations are now enabled by default in `DockerGit` - no additional environment variables needed. Parallel execution was reverted.
187+
188+
### **Usage Examples:**
189+
190+
```bash
191+
# Run with optimized Docker Git (container reuse + batch operations)
192+
make test
193+
194+
# Use native Git for faster CI performance
195+
ZERV_TEST_NATIVE_GIT=true make test
196+
197+
# Disable Docker tests entirely
198+
ZERV_TEST_DOCKER=false make test
199+
```
153200

154201
### **Backward Compatibility:**
155202

@@ -355,19 +402,26 @@ RUST_LOG=debug cargo test test_tagged_repo_clean test_distance_repo_clean test_d
355402

356403
## 🎯 **Next Steps**
357404

405+
### **Current Status:**
406+
407+
1. **Phase 1**: ✅ Container reuse optimization completed and maintained
408+
2. **Phase 2**: ❌ Parallelization reverted due to minimal performance gain
409+
3. **Phase 3**: ✅ Batch operations completed and available
410+
358411
### **Immediate Actions:**
359412

360-
1. **Start with Phase 1**: Implement container reuse optimization
361-
2. **Benchmark current performance**: Measure baseline test execution time
362-
3. **Create optimized DockerGit**: Implement container reuse logic
363-
4. **Test and validate**: Ensure no regressions
413+
1. **Maintain Phase 1**: Keep container reuse optimization working
414+
2. **Use Phase 3**: Batch operations are now enabled by default
415+
3. **Monitor performance**: Track test execution times with both optimizations
416+
4. **Consider alternatives**: Native Git in CI, test selection strategies
364417

365418
### **Short-term Goals:**
366419

367-
- Complete Phase 1 implementation
368-
- Achieve 70-80% performance improvement
369-
- Validate test stability and quality
370-
- Document performance improvements
420+
- Maintain Phase 1 container reuse benefits
421+
- Monitor Phase 3 batch operations performance
422+
- Monitor for any flakiness issues
423+
- Measure actual performance improvement from both optimizations
424+
- Explore alternative optimization strategies
371425

372426
### **Long-term Goals:**
373427

Makefile

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,31 @@ test:
3434
test_flaky:
3535
@echo "🚀 Starting flaky test detection with 5 iterations..."
3636
@echo "=================================================="
37-
@start_time=$$(date +%s); \
37+
@set -o pipefail; \
38+
start_time=$$(date +%s); \
3839
total_time=0; \
3940
success_count=0; \
41+
failed_iteration=0; \
4042
for i in 1 2 3 4 5; do \
4143
echo ""; \
4244
echo "=== Iteration $$i/5 ==="; \
4345
iter_start=$$(date +%s); \
4446
echo "⏰ Start time: $$(date)"; \
4547
echo "🔍 Running tests..."; \
46-
if ZERV_TEST_NATIVE_GIT=false ZERV_TEST_DOCKER=true $(MAKE) _test 2>&1 | tee /tmp/test_output_$$i.log; then \
47-
iter_end=$$(date +%s); \
48-
iter_duration=$$((iter_end - iter_start)); \
48+
ZERV_TEST_NATIVE_GIT=false ZERV_TEST_DOCKER=true $(MAKE) _test 2>&1 | tee /tmp/test_output_$$i.log; \
49+
test_exit_code=$$?; \
50+
iter_end=$$(date +%s); \
51+
iter_duration=$$((iter_end - iter_start)); \
52+
if [ $$test_exit_code -eq 0 ]; then \
4953
total_time=$$((total_time + iter_duration)); \
5054
success_count=$$((success_count + 1)); \
5155
echo "✅ Iteration $$i completed successfully in $${iter_duration}s"; \
5256
echo "⏰ End time: $$(date)"; \
5357
rm -f /tmp/test_output_$$i.log; \
5458
else \
55-
iter_end=$$(date +%s); \
56-
iter_duration=$$((iter_end - iter_start)); \
59+
failed_iteration=$$i; \
5760
echo ""; \
58-
echo "❌ FAILED at iteration $$i after $${iter_duration}s"; \
61+
echo "❌ FAILED at iteration $$i after $${iter_duration}s (exit code: $$test_exit_code)"; \
5962
echo "⏰ End time: $$(date)"; \
6063
echo ""; \
6164
echo "🚨 FLAKINESS DETECTED - Test failed at iteration $$i"; \
@@ -72,9 +75,12 @@ test_flaky:
7275
echo "No test output captured"; \
7376
fi; \
7477
echo "=================================================="; \
75-
exit 1; \
78+
break; \
7679
fi; \
7780
done; \
81+
if [ $$failed_iteration -gt 0 ]; then \
82+
exit 1; \
83+
fi; \
7884
end_time=$$(date +%s); \
7985
total_duration=$$((end_time - start_time)); \
8086
avg_time=$$((total_time / success_count)); \

0 commit comments

Comments
 (0)