// ================================================================================================ // Audio Backend - 测试模拟对象实现 // ================================================================================================ #include "mock_objects.h" #include #include #include namespace audio_backend { namespace test { //=================================================================================================== // ResourceLimiter 实现 //=================================================================================================== struct ResourceLimiter::Impl { size_t memory_limit = std::numeric_limits::max(); float cpu_limit = 100.0f; size_t io_limit = std::numeric_limits::max(); size_t network_limit = std::numeric_limits::max(); ResourceUsage current_usage; std::mt19937 rng{static_cast(std::chrono::steady_clock::now().time_since_epoch().count())}; }; ResourceLimiter::ResourceLimiter() : pimpl_(std::make_unique()) {} ResourceLimiter::~ResourceLimiter() = default; void ResourceLimiter::set_memory_limit(size_t bytes) { pimpl_->memory_limit = bytes; } void ResourceLimiter::set_cpu_limit(float percentage) { pimpl_->cpu_limit = std::clamp(percentage, 0.0f, 100.0f); } void ResourceLimiter::set_io_limit(size_t bytes_per_sec) { pimpl_->io_limit = bytes_per_sec; } void ResourceLimiter::set_network_limit(size_t bytes_per_sec) { pimpl_->network_limit = bytes_per_sec; } void ResourceLimiter::reset_limits() { pimpl_->memory_limit = std::numeric_limits::max(); pimpl_->cpu_limit = 100.0f; pimpl_->io_limit = std::numeric_limits::max(); pimpl_->network_limit = std::numeric_limits::max(); } ResourceUsage ResourceLimiter::get_current_usage() const { // 模拟随机资源使用 std::uniform_real_distribution cpu_dist(0.0f, pimpl_->cpu_limit * 1.2f); std::uniform_int_distribution memory_dist(0, pimpl_->memory_limit); std::uniform_int_distribution io_dist(0, pimpl_->io_limit); std::uniform_int_distribution network_dist(0, pimpl_->network_limit); ResourceUsage usage; usage.memory_usage_bytes = memory_dist(pimpl_->rng); usage.cpu_usage_percent = cpu_dist(pimpl_->rng); usage.io_bytes_per_sec = io_dist(pimpl_->rng); usage.network_bytes_per_sec = network_dist(pimpl_->rng); return usage; } bool ResourceLimiter::is_limit_reached(ResourceType type) const { auto usage = get_current_usage(); switch (type) { case ResourceType::Memory: return usage.memory_usage_bytes >= pimpl_->memory_limit; case ResourceType::CPU: return usage.cpu_usage_percent >= pimpl_->cpu_limit; case ResourceType::IO: return usage.io_bytes_per_sec >= pimpl_->io_limit; case ResourceType::Network: return usage.network_bytes_per_sec >= pimpl_->network_limit; default: return false; } } //=================================================================================================== // ErrorInjector 实现 //=================================================================================================== struct ErrorInjector::Impl { std::map> registered_errors; float error_probability = 0.0f; std::mt19937 rng{static_cast(std::chrono::steady_clock::now().time_since_epoch().count())}; }; ErrorInjector::ErrorInjector() : pimpl_(std::make_unique()) {} ErrorInjector::~ErrorInjector() = default; void ErrorInjector::register_error(const std::string& component, const std::string& operation, ErrorCallback callback) { pimpl_->registered_errors[component][operation] = std::move(callback); } bool ErrorInjector::inject_error(const std::string& component, const std::string& operation) { auto comp_it = pimpl_->registered_errors.find(component); if (comp_it != pimpl_->registered_errors.end()) { auto op_it = comp_it->second.find(operation); if (op_it != comp_it->second.end()) { op_it->second(); return true; } } return false; } bool ErrorInjector::inject_random_error() { std::uniform_real_distribution dist(0.0f, 1.0f); if (dist(pimpl_->rng) < pimpl_->error_probability) { // 随机选择一个错误注入 if (pimpl_->registered_errors.empty()) { return false; } std::vector> error_keys; for (const auto& comp : pimpl_->registered_errors) { for (const auto& op : comp.second) { error_keys.emplace_back(comp.first, op.first); } } if (error_keys.empty()) { return false; } std::uniform_int_distribution key_dist(0, error_keys.size() - 1); auto selected = error_keys[key_dist(pimpl_->rng)]; return inject_error(selected.first, selected.second); } return false; } void ErrorInjector::set_error_probability(float probability) { pimpl_->error_probability = std::clamp(probability, 0.0f, 1.0f); } void ErrorInjector::reset() { pimpl_->registered_errors.clear(); pimpl_->error_probability = 0.0f; } //=================================================================================================== // MockAudioGenerator 实现 //=================================================================================================== struct MockAudioGenerator::Impl { int sample_rate; int channels; SignalType type = SignalType::Sine; float frequency = 440.0f; float amplitude = 0.5f; float phase = 0.0f; float phase_increment = 0.0f; std::mt19937 rng{static_cast(std::chrono::steady_clock::now().time_since_epoch().count())}; Impl(int sr, int ch) : sample_rate(sr), channels(ch) { update_phase_increment(); } void update_phase_increment() { phase_increment = 2.0f * M_PI * frequency / static_cast(sample_rate); } float generate_sample() { float sample = 0.0f; switch (type) { case SignalType::Sine: sample = amplitude * std::sin(phase); break; case SignalType::Square: sample = amplitude * (std::sin(phase) >= 0.0f ? 1.0f : -1.0f); break; case SignalType::Triangle: sample = amplitude * (2.0f / M_PI) * std::asin(std::sin(phase)); break; case SignalType::Sawtooth: { float normalized_phase = std::fmod(phase, 2.0f * M_PI) / (2.0f * M_PI); sample = amplitude * (2.0f * normalized_phase - 1.0f); break; } case SignalType::Noise: { std::uniform_real_distribution dist(-amplitude, amplitude); sample = dist(rng); break; } case SignalType::Silence: default: sample = 0.0f; break; } // 更新相位 phase += phase_increment; if (phase > 2.0f * M_PI) { phase -= 2.0f * M_PI; } return sample; } }; MockAudioGenerator::MockAudioGenerator(int sample_rate, int channels) : pimpl_(std::make_unique(sample_rate, channels)) {} MockAudioGenerator::~MockAudioGenerator() = default; void MockAudioGenerator::set_signal_type(SignalType type) { pimpl_->type = type; } void MockAudioGenerator::set_frequency(float frequency_hz) { pimpl_->frequency = frequency_hz; pimpl_->update_phase_increment(); } void MockAudioGenerator::set_amplitude(float amplitude) { pimpl_->amplitude = amplitude; } void MockAudioGenerator::set_phase(float phase_radians) { pimpl_->phase = phase_radians; } void MockAudioGenerator::generate(float* buffer, size_t frames) { for (size_t i = 0; i < frames; ++i) { float sample = pimpl_->generate_sample(); for (int ch = 0; ch < pimpl_->channels; ++ch) { buffer[i * pimpl_->channels + ch] = sample; } } } void MockAudioGenerator::reset() { pimpl_->phase = 0.0f; } } // namespace test } // namespace audio_backend