mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-09-27 03:25:56 +08:00
doc: add test plugin doc
This commit is contained in:
287
plugin/test/README.md
Normal file
287
plugin/test/README.md
Normal file
@@ -0,0 +1,287 @@
|
||||
# Test Plugin
|
||||
|
||||
The Test Plugin is a comprehensive testing framework for Monibuca v5 that provides automated testing capabilities for various streaming protocols and media processing scenarios. It enables developers to validate streaming functionality, performance, and reliability through configurable test cases.
|
||||
|
||||
## Overview
|
||||
|
||||
The Test Plugin serves as a quality assurance tool for Monibuca's streaming capabilities, offering:
|
||||
|
||||
- **Automated Test Cases**: Pre-configured test scenarios for common streaming workflows
|
||||
- **Multi-Protocol Support**: Testing across RTMP, RTSP, SRT, WebRTC, HLS, MP4, FLV, and PS protocols
|
||||
- **Stress Testing**: Performance testing with configurable concurrent push/pull operations
|
||||
- **Real-time Monitoring**: Live status updates via Server-Sent Events (SSE)
|
||||
- **Flexible Task System**: Extensible task framework for custom test scenarios
|
||||
|
||||
## Architecture
|
||||
|
||||
### Core Components
|
||||
|
||||
1. **TestPlugin**: Main plugin controller managing test cases and stress testing
|
||||
2. **TestCase**: Individual test scenario with configurable tasks and parameters
|
||||
3. **TestTaskFactory**: Factory pattern for creating different types of test tasks
|
||||
4. **Task Types**: Specialized tasks for different operations (push, pull, snapshot, write, read)
|
||||
|
||||
### Task System Design
|
||||
|
||||
The plugin uses a sophisticated task orchestration system:
|
||||
|
||||
```go
|
||||
type TestTaskConfig struct {
|
||||
Action string `json:"action"` // Task type: push, pull, snapshot, write, read
|
||||
Delay time.Duration `json:"delay"` // Delay before task execution
|
||||
Format string `json:"format"` // Protocol/format: rtmp, rtsp, srt, etc.
|
||||
ServerAddr string `json:"serverAddr"` // Target server address
|
||||
Input string `json:"input"` // Input source (file, URL, etc.)
|
||||
StreamPath string `json:"streamPath"` // Stream identifier
|
||||
}
|
||||
```
|
||||
|
||||
### Task Types
|
||||
|
||||
#### 1. Push Task (`AcceptPushTask`)
|
||||
- **Purpose**: Simulates media streaming to the server
|
||||
- **Implementation**: Uses FFmpeg to push media from files or live sources
|
||||
- **Supported Formats**: RTMP, RTSP, SRT, WebRTC, PS
|
||||
- **Design Insight**: Leverages FFmpeg's robust streaming capabilities while maintaining control through process management
|
||||
|
||||
#### 2. Snapshot Task (`SnapshotTask`)
|
||||
- **Purpose**: Captures frames from streams to verify content quality
|
||||
- **Implementation**: Two modes:
|
||||
- Direct FFmpeg capture from stream URLs
|
||||
- Internal stream subscription with AnnexB format processing
|
||||
- **Design Insight**: Dual approach allows testing both external accessibility and internal stream processing
|
||||
|
||||
#### 3. Write Task (`WriteRemoteTask`)
|
||||
- **Purpose**: Records streams to various formats
|
||||
- **Implementation**: Integrates with Monibuca's recording plugins
|
||||
- **Supported Formats**: MP4, FLV, HLS, PS
|
||||
- **Design Insight**: Reuses existing recording infrastructure for consistency
|
||||
|
||||
#### 4. Read Task (`ReadRemoteTask`)
|
||||
- **Purpose**: Pulls streams from various sources
|
||||
- **Implementation**: Uses Monibuca's puller plugins
|
||||
- **Supported Formats**: MP4, FLV, HLS, RTMP, RTSP, SRT, WebRTC, AnnexB
|
||||
- **Design Insight**: Unified interface for different puller implementations
|
||||
|
||||
## Key Design Patterns
|
||||
|
||||
### 1. Factory Pattern
|
||||
The `TestTaskFactory` uses a registry pattern to dynamically create tasks:
|
||||
|
||||
```go
|
||||
func (f *TestTaskFactory) Register(action string, taskCreator func(*TestCase, TestTaskConfig) task.ITask) {
|
||||
f.tasks[action] = taskCreator
|
||||
}
|
||||
```
|
||||
|
||||
This allows easy extension with new task types without modifying core code.
|
||||
|
||||
### 2. Task Orchestration with Reflection
|
||||
The test case execution uses Go's reflection API for dynamic task scheduling:
|
||||
|
||||
```go
|
||||
subTaskSelect := []reflect.SelectCase{
|
||||
{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(time.After(ts.Timeout))},
|
||||
{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ts.Done())},
|
||||
}
|
||||
```
|
||||
|
||||
This enables complex timing control and parallel task execution.
|
||||
|
||||
### 3. Real-time Status Updates
|
||||
The plugin implements Server-Sent Events (SSE) for live monitoring:
|
||||
|
||||
```go
|
||||
func (p *TestPlugin) GetTestCaseSSE(w http.ResponseWriter, r *http.Request) {
|
||||
util.NewSSE(w, r.Context(), func(sse *util.SSE) {
|
||||
// Real-time status broadcasting
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Stress Testing Architecture
|
||||
The stress testing system maintains collections of active push/pull operations:
|
||||
|
||||
```go
|
||||
type TestPlugin struct {
|
||||
pushers util.Collection[string, *m7s.PushJob]
|
||||
pullers util.Collection[string, *m7s.PullJob]
|
||||
}
|
||||
```
|
||||
|
||||
This allows dynamic scaling and management of concurrent operations.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Test Case Configuration
|
||||
|
||||
Test cases are defined in YAML format with the following structure:
|
||||
|
||||
```yaml
|
||||
cases:
|
||||
test_name:
|
||||
description: "Test description"
|
||||
videoCodec: "h264"
|
||||
audioCodec: "aac"
|
||||
videoOnly: false
|
||||
audioOnly: false
|
||||
timeout: "30s"
|
||||
tasks:
|
||||
- action: push
|
||||
format: rtmp
|
||||
delay: 0s
|
||||
- action: snapshot
|
||||
format: rtmp
|
||||
delay: 5s
|
||||
```
|
||||
|
||||
### Pre-configured Test Cases
|
||||
|
||||
The plugin includes comprehensive test scenarios:
|
||||
|
||||
- **Protocol Cross-Testing**: RTMP↔RTSP, RTMP↔SRT, RTSP↔SRT
|
||||
- **File Format Testing**: MP4, FLV, HLS reading and recording
|
||||
- **Advanced Features**: PS encapsulation, AnnexB processing, WebRTC testing
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### REST API
|
||||
- `GET /test/api/cases` - List test cases
|
||||
- `POST /test/api/cases/execute` - Execute test cases
|
||||
- `GET /test/api/stress/count` - Get stress test counts
|
||||
- `POST /test/api/stress/push/{protocol}/{count}` - Start push stress test
|
||||
- `POST /test/api/stress/pull/{protocol}/{count}` - Start pull stress test
|
||||
|
||||
### Server-Sent Events
|
||||
- `GET /sse/cases` - Real-time test case status updates
|
||||
|
||||
### gRPC API
|
||||
Full gRPC service definition available in `pb/test.proto` with corresponding HTTP gateway endpoints.
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Basic Test Execution
|
||||
```bash
|
||||
# Execute a specific test case
|
||||
curl -X POST http://localhost:8080/test/api/cases/execute \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"names": ["rtmp2rtmp"]}'
|
||||
```
|
||||
|
||||
### Stress Testing
|
||||
```bash
|
||||
# Start 10 concurrent RTMP pushes
|
||||
curl -X POST http://localhost:8080/test/api/stress/push/rtmp/10 \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"streamPath": "stress_test",
|
||||
"remoteURL": "rtmp://localhost/live/%d"
|
||||
}'
|
||||
```
|
||||
|
||||
### Real-time Monitoring
|
||||
```javascript
|
||||
// Monitor test case status
|
||||
const eventSource = new EventSource('/sse/cases');
|
||||
eventSource.onmessage = function(event) {
|
||||
const testCases = JSON.parse(event.data);
|
||||
// Update UI with test status
|
||||
};
|
||||
```
|
||||
|
||||
## Advanced Features
|
||||
|
||||
### 1. Dynamic Stream Path Generation
|
||||
The plugin automatically generates unique stream paths for parallel test execution:
|
||||
|
||||
```go
|
||||
if taskConfig.StreamPath == "" {
|
||||
taskConfig.StreamPath = fmt.Sprintf("test/%d", ts.ID)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Intelligent Input Handling
|
||||
Supports both file-based and URL-based inputs with automatic path resolution:
|
||||
|
||||
```go
|
||||
if taskConfig.Input != "" && !strings.Contains(taskConfig.Input, ".") {
|
||||
taskConfig.Input = fmt.Sprintf("%s/%d", taskConfig.Input, ts.ID)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Comprehensive Logging
|
||||
Each test case maintains detailed logs with timestamps:
|
||||
|
||||
```go
|
||||
func (ts *TestCase) Write(buf []byte) (int, error) {
|
||||
ts.Logs += time.Now().Format("2006-01-02 15:04:05") + " " + string(buf) + "\n"
|
||||
return len(buf), nil
|
||||
}
|
||||
```
|
||||
|
||||
## Integration with Monibuca Ecosystem
|
||||
|
||||
The Test Plugin seamlessly integrates with Monibuca's plugin architecture:
|
||||
|
||||
- **Plugin Registration**: Uses `m7s.InstallPlugin` for automatic discovery
|
||||
- **Configuration Management**: Leverages Monibuca's configuration system
|
||||
- **Task Framework**: Built on Monibuca's task management system
|
||||
- **Stream Management**: Integrates with publisher/subscriber model
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
### Memory Management
|
||||
- Uses `util.Memory` for efficient buffer management
|
||||
- Implements proper cleanup for temporary files and processes
|
||||
- Leverages Go's garbage collector for automatic memory management
|
||||
|
||||
### Concurrency
|
||||
- Thread-safe operations using Monibuca's `Call` method
|
||||
- Efficient collection management for stress testing
|
||||
- Non-blocking SSE implementation
|
||||
|
||||
### Resource Cleanup
|
||||
- Automatic process termination on task completion
|
||||
- Temporary file cleanup after recording tests
|
||||
- Proper connection management for network operations
|
||||
|
||||
## Extensibility
|
||||
|
||||
The plugin is designed for easy extension:
|
||||
|
||||
1. **New Task Types**: Register new task creators with the factory
|
||||
2. **Custom Protocols**: Add support for new streaming protocols
|
||||
3. **Advanced Metrics**: Extend monitoring and reporting capabilities
|
||||
4. **Integration Tests**: Create complex multi-step test scenarios
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Test Isolation**: Each test case runs with unique stream paths
|
||||
2. **Timeout Management**: Configure appropriate timeouts for different scenarios
|
||||
3. **Resource Monitoring**: Monitor system resources during stress testing
|
||||
4. **Log Analysis**: Use detailed logs for debugging and performance analysis
|
||||
5. **Incremental Testing**: Start with simple cases before complex scenarios
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **FFmpeg Not Found**: Ensure FFmpeg is installed and in PATH
|
||||
2. **Port Conflicts**: Check for port availability in stress testing
|
||||
3. **File Permissions**: Ensure write permissions for recording tests
|
||||
4. **Network Connectivity**: Verify network access for remote stream testing
|
||||
|
||||
### Debug Mode
|
||||
Enable detailed logging by setting appropriate log levels in Monibuca configuration.
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- **Visual Test Reports**: HTML-based test result visualization
|
||||
- **Performance Metrics**: Detailed performance analysis and reporting
|
||||
- **CI/CD Integration**: Automated testing in continuous integration pipelines
|
||||
- **Custom Assertions**: User-defined validation rules for test cases
|
||||
- **Distributed Testing**: Multi-node testing capabilities
|
||||
|
||||
---
|
||||
|
||||
The Test Plugin represents a sophisticated approach to streaming media testing, combining flexibility, performance, and ease of use to ensure the reliability of Monibuca's streaming capabilities.
|
307
plugin/test/README_CN.md
Normal file
307
plugin/test/README_CN.md
Normal file
@@ -0,0 +1,307 @@
|
||||
# 测试插件
|
||||
|
||||
测试插件是 Monibuca v5 的综合测试框架,为各种流媒体协议和媒体处理场景提供自动化测试能力。它使开发者能够通过可配置的测试用例来验证流媒体功能、性能和可靠性。
|
||||
|
||||
## 概述
|
||||
|
||||
测试插件作为 Monibuca 流媒体能力的质量保证工具,提供:
|
||||
|
||||
- **自动化测试用例**:为常见流媒体工作流预配置测试场景
|
||||
- **多协议支持**:支持 RTMP、RTSP、SRT、WebRTC、HLS、MP4、FLV 和 PS 协议的测试
|
||||
- **压力测试**:通过可配置的并发推拉流操作进行性能测试
|
||||
- **实时监控**:通过服务器发送事件(SSE)提供实时状态更新
|
||||
- **灵活的任务系统**:可扩展的任务框架,支持自定义测试场景
|
||||
|
||||
## 架构设计
|
||||
|
||||
### 核心组件
|
||||
|
||||
1. **TestPlugin**:主插件控制器,管理测试用例和压力测试
|
||||
2. **TestCase**:具有可配置任务和参数的单个测试场景
|
||||
3. **TestTaskFactory**:用于创建不同类型测试任务的工厂模式
|
||||
4. **任务类型**:针对不同操作的专业化任务(推流、拉流、截图、录制、读取)
|
||||
|
||||
### 任务系统设计
|
||||
|
||||
插件使用复杂的任务编排系统:
|
||||
|
||||
```go
|
||||
type TestTaskConfig struct {
|
||||
Action string `json:"action"` // 任务类型:push, pull, snapshot, write, read
|
||||
Delay time.Duration `json:"delay"` // 任务执行前的延迟
|
||||
Format string `json:"format"` // 协议/格式:rtmp, rtsp, srt 等
|
||||
ServerAddr string `json:"serverAddr"` // 目标服务器地址
|
||||
Input string `json:"input"` // 输入源(文件、URL 等)
|
||||
StreamPath string `json:"streamPath"` // 流标识符
|
||||
}
|
||||
```
|
||||
|
||||
### 任务类型详解
|
||||
|
||||
#### 1. 推流任务(`AcceptPushTask`)
|
||||
- **目的**:模拟向服务器推送媒体流
|
||||
- **实现**:使用 FFmpeg 从文件或实时源推送媒体
|
||||
- **支持格式**:RTMP、RTSP、SRT、WebRTC、PS
|
||||
- **设计巧思**:利用 FFmpeg 强大的流媒体能力,同时通过进程管理保持控制
|
||||
|
||||
#### 2. 截图任务(`SnapshotTask`)
|
||||
- **目的**:从流中捕获帧以验证内容质量
|
||||
- **实现**:两种模式:
|
||||
- 直接从流 URL 进行 FFmpeg 捕获
|
||||
- 内部流订阅与 AnnexB 格式处理
|
||||
- **设计巧思**:双重方法允许测试外部可访问性和内部流处理
|
||||
|
||||
#### 3. 录制任务(`WriteRemoteTask`)
|
||||
- **目的**:将流录制为各种格式
|
||||
- **实现**:与 Monibuca 的录制插件集成
|
||||
- **支持格式**:MP4、FLV、HLS、PS
|
||||
- **设计巧思**:重用现有录制基础设施以确保一致性
|
||||
|
||||
#### 4. 读取任务(`ReadRemoteTask`)
|
||||
- **目的**:从各种源拉取流
|
||||
- **实现**:使用 Monibuca 的拉流插件
|
||||
- **支持格式**:MP4、FLV、HLS、RTMP、RTSP、SRT、WebRTC、AnnexB
|
||||
- **设计巧思**:为不同拉流器实现提供统一接口
|
||||
|
||||
## 关键设计模式
|
||||
|
||||
### 1. 工厂模式
|
||||
`TestTaskFactory` 使用注册表模式动态创建任务:
|
||||
|
||||
```go
|
||||
func (f *TestTaskFactory) Register(action string, taskCreator func(*TestCase, TestTaskConfig) task.ITask) {
|
||||
f.tasks[action] = taskCreator
|
||||
}
|
||||
```
|
||||
|
||||
这允许轻松扩展新任务类型而无需修改核心代码。
|
||||
|
||||
### 2. 基于反射的任务编排
|
||||
测试用例执行使用 Go 的反射 API 进行动态任务调度:
|
||||
|
||||
```go
|
||||
subTaskSelect := []reflect.SelectCase{
|
||||
{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(time.After(ts.Timeout))},
|
||||
{Dir: reflect.SelectRecv, Chan: reflect.ValueOf(ts.Done())},
|
||||
}
|
||||
```
|
||||
|
||||
这实现了复杂的时间控制和并行任务执行。
|
||||
|
||||
### 3. 实时状态更新
|
||||
插件实现服务器发送事件(SSE)进行实时监控:
|
||||
|
||||
```go
|
||||
func (p *TestPlugin) GetTestCaseSSE(w http.ResponseWriter, r *http.Request) {
|
||||
util.NewSSE(w, r.Context(), func(sse *util.SSE) {
|
||||
// 实时状态广播
|
||||
})
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 压力测试架构
|
||||
压力测试系统维护活跃推拉流操作的集合:
|
||||
|
||||
```go
|
||||
type TestPlugin struct {
|
||||
pushers util.Collection[string, *m7s.PushJob]
|
||||
pullers util.Collection[string, *m7s.PullJob]
|
||||
}
|
||||
```
|
||||
|
||||
这允许动态扩展和管理并发操作。
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 测试用例配置
|
||||
|
||||
测试用例以 YAML 格式定义,结构如下:
|
||||
|
||||
```yaml
|
||||
cases:
|
||||
test_name:
|
||||
description: "测试描述"
|
||||
videoCodec: "h264"
|
||||
audioCodec: "aac"
|
||||
videoOnly: false
|
||||
audioOnly: false
|
||||
timeout: "30s"
|
||||
tasks:
|
||||
- action: push
|
||||
format: rtmp
|
||||
delay: 0s
|
||||
- action: snapshot
|
||||
format: rtmp
|
||||
delay: 5s
|
||||
```
|
||||
|
||||
### 预配置测试用例
|
||||
|
||||
插件包含全面的测试场景:
|
||||
|
||||
- **协议交叉测试**:RTMP↔RTSP、RTMP↔SRT、RTSP↔SRT
|
||||
- **文件格式测试**:MP4、FLV、HLS 读取和录制
|
||||
- **高级功能**:PS 封装、AnnexB 处理、WebRTC 测试
|
||||
|
||||
## API 接口
|
||||
|
||||
### REST API
|
||||
- `GET /test/api/cases` - 列出测试用例
|
||||
- `POST /test/api/cases/execute` - 执行测试用例
|
||||
- `GET /test/api/stress/count` - 获取压力测试计数
|
||||
- `POST /test/api/stress/push/{protocol}/{count}` - 开始推流压力测试
|
||||
- `POST /test/api/stress/pull/{protocol}/{count}` - 开始拉流压力测试
|
||||
|
||||
### 服务器发送事件
|
||||
- `GET /sse/cases` - 实时测试用例状态更新
|
||||
|
||||
### gRPC API
|
||||
完整的 gRPC 服务定义在 `pb/test.proto` 中,包含相应的 HTTP 网关端点。
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 基本测试执行
|
||||
```bash
|
||||
# 执行特定测试用例
|
||||
curl -X POST http://localhost:8080/test/api/cases/execute \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"names": ["rtmp2rtmp"]}'
|
||||
```
|
||||
|
||||
### 压力测试
|
||||
```bash
|
||||
# 启动 10 个并发 RTMP 推流
|
||||
curl -X POST http://localhost:8080/test/api/stress/push/rtmp/10 \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"streamPath": "stress_test",
|
||||
"remoteURL": "rtmp://localhost/live/%d"
|
||||
}'
|
||||
```
|
||||
|
||||
### 实时监控
|
||||
```javascript
|
||||
// 监控测试用例状态
|
||||
const eventSource = new EventSource('/sse/cases');
|
||||
eventSource.onmessage = function(event) {
|
||||
const testCases = JSON.parse(event.data);
|
||||
// 使用测试状态更新 UI
|
||||
};
|
||||
```
|
||||
|
||||
## 高级功能
|
||||
|
||||
### 1. 动态流路径生成
|
||||
插件自动为并行测试执行生成唯一流路径:
|
||||
|
||||
```go
|
||||
if taskConfig.StreamPath == "" {
|
||||
taskConfig.StreamPath = fmt.Sprintf("test/%d", ts.ID)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 智能输入处理
|
||||
支持基于文件和基于 URL 的输入,具有自动路径解析:
|
||||
|
||||
```go
|
||||
if taskConfig.Input != "" && !strings.Contains(taskConfig.Input, ".") {
|
||||
taskConfig.Input = fmt.Sprintf("%s/%d", taskConfig.Input, ts.ID)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 综合日志记录
|
||||
每个测试用例维护带时间戳的详细日志:
|
||||
|
||||
```go
|
||||
func (ts *TestCase) Write(buf []byte) (int, error) {
|
||||
ts.Logs += time.Now().Format("2006-01-02 15:04:05") + " " + string(buf) + "\n"
|
||||
return len(buf), nil
|
||||
}
|
||||
```
|
||||
|
||||
## 与 Monibuca 生态系统的集成
|
||||
|
||||
测试插件与 Monibuca 的插件架构无缝集成:
|
||||
|
||||
- **插件注册**:使用 `m7s.InstallPlugin` 进行自动发现
|
||||
- **配置管理**:利用 Monibuca 的配置系统
|
||||
- **任务框架**:基于 Monibuca 的任务管理系统构建
|
||||
- **流管理**:与发布者/订阅者模型集成
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 内存管理
|
||||
- 使用 `util.Memory` 进行高效的缓冲区管理
|
||||
- 为临时文件和进程实现适当的清理
|
||||
- 利用 Go 的垃圾收集器进行自动内存管理
|
||||
|
||||
### 并发性
|
||||
- 使用 Monibuca 的 `Call` 方法进行线程安全操作
|
||||
- 为压力测试进行高效的集合管理
|
||||
- 非阻塞 SSE 实现
|
||||
|
||||
### 资源清理
|
||||
- 任务完成时自动终止进程
|
||||
- 录制测试后清理临时文件
|
||||
- 网络操作的适当连接管理
|
||||
|
||||
## 可扩展性
|
||||
|
||||
插件设计便于扩展:
|
||||
|
||||
1. **新任务类型**:向工厂注册新的任务创建器
|
||||
2. **自定义协议**:添加对新流媒体协议的支持
|
||||
3. **高级指标**:扩展监控和报告功能
|
||||
4. **集成测试**:创建复杂的多步骤测试场景
|
||||
|
||||
## 最佳实践
|
||||
|
||||
1. **测试隔离**:每个测试用例使用唯一的流路径运行
|
||||
2. **超时管理**:为不同场景配置适当的超时
|
||||
3. **资源监控**:在压力测试期间监控系统资源
|
||||
4. **日志分析**:使用详细日志进行调试和性能分析
|
||||
5. **增量测试**:在复杂场景之前从简单用例开始
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **找不到 FFmpeg**:确保 FFmpeg 已安装并在 PATH 中
|
||||
2. **端口冲突**:在压力测试中检查端口可用性
|
||||
3. **文件权限**:确保录制测试的写入权限
|
||||
4. **网络连接**:验证远程流测试的网络访问
|
||||
|
||||
### 调试模式
|
||||
通过在 Monibuca 配置中设置适当的日志级别来启用详细日志记录。
|
||||
|
||||
## 设计巧思总结
|
||||
|
||||
### 1. 任务工厂模式
|
||||
通过注册表模式实现任务的动态创建,使得添加新任务类型变得非常简单,无需修改核心代码。
|
||||
|
||||
### 2. 反射驱动的任务调度
|
||||
使用 Go 的反射 API 实现复杂的任务编排,支持动态延迟和并行执行,提供了极大的灵活性。
|
||||
|
||||
### 3. 双重截图机制
|
||||
截图任务支持两种模式:外部 FFmpeg 捕获和内部流订阅,既测试了外部可访问性,又验证了内部流处理能力。
|
||||
|
||||
### 4. 智能资源管理
|
||||
通过 `util.Collection` 管理并发操作,支持动态扩展和收缩,实现了高效的压力测试。
|
||||
|
||||
### 5. 实时状态同步
|
||||
使用 SSE 技术实现实时状态更新,为测试监控提供了良好的用户体验。
|
||||
|
||||
### 6. 流路径隔离
|
||||
自动生成唯一的流路径,确保并行测试之间不会相互干扰,提高了测试的可靠性。
|
||||
|
||||
## 未来增强
|
||||
|
||||
- **可视化测试报告**:基于 HTML 的测试结果可视化
|
||||
- **性能指标**:详细的性能分析和报告
|
||||
- **CI/CD 集成**:在持续集成管道中的自动化测试
|
||||
- **自定义断言**:用户定义的测试用例验证规则
|
||||
- **分布式测试**:多节点测试能力
|
||||
|
||||
---
|
||||
|
||||
测试插件代表了流媒体测试的复杂方法,结合了灵活性、性能和易用性,以确保 Monibuca 流媒体能力的可靠性。通过其精心设计的架构和丰富的功能集,它为开发者提供了一个强大的工具来验证和优化流媒体系统。
|
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -203,6 +204,19 @@ func (p *TestPlugin) push(count int, streamPath, url string, pusher m7s.PusherFa
|
||||
|
||||
func (p *TestPlugin) StartPush(ctx context.Context, req *testpb.PushRequest) (res *pb.SuccessResponse, err error) {
|
||||
var pusher m7s.PusherFactory
|
||||
if req.Protocol == "" {
|
||||
if strings.HasPrefix(req.RemoteURL, "http") {
|
||||
req.Protocol = "webrtc"
|
||||
} else if strings.HasPrefix(req.RemoteURL, "srt") {
|
||||
req.Protocol = "srt"
|
||||
} else if strings.HasPrefix(req.RemoteURL, "rtsp") {
|
||||
req.Protocol = "rtsp"
|
||||
} else if strings.HasPrefix(req.RemoteURL, "rtmp") {
|
||||
req.Protocol = "rtmp"
|
||||
} else {
|
||||
return nil, fmt.Errorf("unsupport protocol %s", req.RemoteURL)
|
||||
}
|
||||
}
|
||||
switch req.Protocol {
|
||||
case "rtmp":
|
||||
pusher = rtmp.NewPusher
|
||||
@@ -210,7 +224,7 @@ func (p *TestPlugin) StartPush(ctx context.Context, req *testpb.PushRequest) (re
|
||||
pusher = rtsp.NewPusher
|
||||
case "srt":
|
||||
pusher = srt.NewPusher
|
||||
case "whip":
|
||||
case "webrtc":
|
||||
pusher = webrtc.NewPusher
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupport protocol %s", req.Protocol)
|
||||
@@ -220,6 +234,27 @@ func (p *TestPlugin) StartPush(ctx context.Context, req *testpb.PushRequest) (re
|
||||
|
||||
func (p *TestPlugin) StartPull(ctx context.Context, req *testpb.PullRequest) (res *pb.SuccessResponse, err error) {
|
||||
var puller m7s.PullerFactory
|
||||
if req.Protocol == "" {
|
||||
u, err := url.Parse(req.RemoteURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse remote url failed: %w", err)
|
||||
}
|
||||
if strings.HasSuffix(u.Path, ".m3u8") {
|
||||
req.Protocol = "hls"
|
||||
} else if strings.HasSuffix(u.Path, ".flv") {
|
||||
req.Protocol = "flv"
|
||||
} else if strings.HasSuffix(u.Path, ".mp4") {
|
||||
req.Protocol = "mp4"
|
||||
} else if strings.HasPrefix(req.RemoteURL, "srt") {
|
||||
req.Protocol = "srt"
|
||||
} else if strings.HasPrefix(req.RemoteURL, "rtsp") {
|
||||
req.Protocol = "rtsp"
|
||||
} else if strings.HasPrefix(req.RemoteURL, "rtmp") {
|
||||
req.Protocol = "rtmp"
|
||||
} else {
|
||||
req.Protocol = "webrtc"
|
||||
}
|
||||
}
|
||||
switch req.Protocol {
|
||||
case "rtmp":
|
||||
puller = rtmp.NewPuller
|
||||
@@ -231,7 +266,7 @@ func (p *TestPlugin) StartPull(ctx context.Context, req *testpb.PullRequest) (re
|
||||
puller = flv.NewPuller
|
||||
case "mp4":
|
||||
puller = mp4.NewPuller
|
||||
case "whep":
|
||||
case "webrtc":
|
||||
puller = webrtc.NewPuller
|
||||
case "hls":
|
||||
puller = hls.NewPuller
|
||||
|
Reference in New Issue
Block a user