Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 65 additions & 8 deletions scripts/report_build_size.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,62 @@ class Colors:
BOLD = '\033[1m'

def format_size(bytes_size):
"""Format bytes to human-readable size"""
"""
Bayt cinsinden verilen büyüklüğü insan tarafından okunabilir birimle (B, KB, MB, GB) biçimlendirir.

Parameters:
bytes_size (int | float): Biçimlendirilecek değer, bayt cinsinden.

Returns:
str: İki ondalık basamak gösterimiyle biçimlendirilmiş büyüklük ve birim (ör. "1.23 KB").
"""
for unit in ['B', 'KB', 'MB']:
if bytes_size < 1024.0:
return f"{bytes_size:.2f} {unit}"
bytes_size /= 1024.0
return f"{bytes_size:.2f} GB"

def calculate_percentage(used, total):
"""Calculate percentage with safety check"""
"""
Belirtilen toplam üzerinden kullanılan miktarın yüzdesini hesaplar.

Parameters:
used (int | float): Kullanılan miktar.
total (int | float): Yüzdelik hesaplamada referans alınan toplam değer.

Returns:
float: Kullanılan miktarın toplam içindeki oranı yüzde cinsinden; `total` sıfır ise `0.0`.
"""
if total == 0:
return 0.0
return (used / total) * 100

def get_file_size(filepath):
"""Get file size safely"""
"""
Belirtilen dosyanın boyutunu bayt cinsinden döndürür.

Returns:
int: Dosya boyutu bayt cinsinden; dosya bulunamaz veya erişim hatası varsa `0`.
"""
try:
return os.path.getsize(filepath)
except OSError:
return 0

def find_build_artifacts(project_root):
"""Find all build artifacts in .pio directory"""
"""
PlatformIO proje kök dizinindeki .pio/build dizinini tarayarak her ortam için derleme artefaktlarının dosya yollarını toplar.

Parameters:
project_root (pathlib.Path): PlatformIO proje kök dizinine işaret eden Path nesnesi.

Returns:
dict: Ortam adıyla anahtarlanmış, her biri şu anahtarları içeren sözlükler:
- 'firmware_bin': firmware.bin dosya yolu (pathlib.Path)
- 'firmware_elf': firmware.elf dosya yolu (pathlib.Path)
- 'partitions_bin': partitions.bin dosya yolu (pathlib.Path)
None: Eğer .pio/build dizini bulunamazsa None döner.
"""
artifacts = {}
pio_dir = project_root / ".pio" / "build"

Expand All @@ -63,7 +97,15 @@ def find_build_artifacts(project_root):
return artifacts

def analyze_elf_sections(elf_path):
"""Analyze ELF file sections using size command"""
"""
ELF dosyasındaki bölümlerin (sections) bayt cinsinden boyutlarını elde eder.

Parameters:
elf_path (str | pathlib.Path): Analiz edilecek ELF dosyasına işaret eden yol.

Returns:
dict: Anahtarları bölüm adları (ör. '.text', '.data', '.bss', '.rodata') ve değerleri her bölümün byte cinsinden boyutu olan sözlük. Eğer analiz başarısız olursa veya bölüm bulunmazsa boş sözlük döner.
"""
try:
import subprocess
result = subprocess.run(
Expand Down Expand Up @@ -99,7 +141,15 @@ def analyze_elf_sections(elf_path):
return {}

def generate_report(project_root):
"""Generate comprehensive build size report"""
"""
Belirtilen PlatformIO proje kök dizinine göre tüm yapı ortamları için ayrıntılı bir boyut raporu yazdırır.

Parameters:
project_root (str | pathlib.Path): PlatformIO proje kök dizininin yolu; fonksiyon .pio/build altında ortam dizinlerini arar.

Returns:
int: Çıkış kodu — `0` başarıyla rapor oluşturuldu, `1` .pio/build dizini veya yapı eserleri bulunamadığında.
"""
print(f"\n{Colors.HEADER}{Colors.BOLD}=" * 70)
print(f"ESP32 Audio Streamer - Build Artifact Size Report")
print(f"=" * 70 + Colors.ENDC)
Expand Down Expand Up @@ -170,7 +220,14 @@ def generate_report(project_root):
return 0

def main():
"""Main entry point"""
"""
PlatformIO proje kök dizinini tespit eder ve proje için build boyutu raporunu üretir.

Çalışma dizininden başlayarak yukarı doğru her üst dizinde `platformio.ini` arar; bir proje kökü bulunamazsa hata mesajı yazdırır ve 1 döner. Proje kökü bulunduğunda `generate_report` çağrılır ve onun döndürdüğü çıkış kodu geri verilir.

Returns:
int: `generate_report` tarafından döndürülen çıkış kodu; PlatformIO projesi bulunamazsa `1`.
"""
# Find project root (directory containing platformio.ini)
current = Path.cwd()
project_root = None
Expand All @@ -187,4 +244,4 @@ def main():
return generate_report(project_root)

if __name__ == "__main__":
sys.exit(main())
sys.exit(main())
18 changes: 12 additions & 6 deletions src/config_validator.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#include <string>

/**
* Configuration Validator
* Validates critical configuration values at runtime startup
* Prevents system from starting with invalid or missing configurations
* Tüm kritik yapılandırma parametrelerinin geçerliliğini kontrol eder ve başlatma öncesi ayarların uygun olduğunu garanti eder.
*
* @returns `true` ise tüm doğrulamalar başarılı, `false` aksi halde.
*/
class ConfigValidator {
public:
Expand Down Expand Up @@ -111,8 +111,14 @@ class ConfigValidator {
}

/**
* Validate server configuration
* Checks: HOST and PORT not empty, valid port number
* Sunucu yapılandırmasının geçerliliğini denetler.
*
* Denetimler şunları kapsar: SERVER_HOST boş olmamalı, SERVER_PORT 1–65535 aralığında olmalı;
* ayrıca yeniden bağlanma zamanlayıcıları (SERVER_RECONNECT_MIN, SERVER_RECONNECT_MAX) ve
* TCP_WRITE_TIMEOUT için mantıklı/önerilen değer aralıkları kontrol edilir; tutarsız veya kritik
* hatalar bulunduğunda uygun hata/uyarı mesajları üretilir.
*
* @returns `true` if required server configuration values are valid, `false` otherwise.
*/
static bool validateServerConfig() {
bool valid = true;
Expand Down Expand Up @@ -345,4 +351,4 @@ class ConfigValidator {
}
};

#endif // CONFIG_VALIDATOR_H
#endif // CONFIG_VALIDATOR_H
12 changes: 11 additions & 1 deletion src/network.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,16 @@ void NetworkManager::monitorWiFiQuality()
}
}

/**
* @brief Sunucuya TCP bağlantısı kurmayı dener.
*
* Sunucuya bağlanmadan önce Wi‑Fi bağlantısını ve yeniden deneme zamanlayıcısını (exponential backoff) kontrol eder.
* Başarılı olduğunda TCP durumunu CONNECTED olarak günceller, yeniden deneme geri dönüşünü sıfırlar, bağlantı sayacı ve son başarılı yazma zamanını günceller
* ve alttaki soket için TCP_NODELAY, keepalive ve gönderme zaman aşımı gibi uygun soket seçeneklerini yapılandırır.
* Başarısız olduğunda TCP hata işleyicisini çağırır, backoff ile sonraki yeniden deneme süresini planlar ve yeniden deneme zamanlayıcısını başlatır.
*
* @return `true` bağlantı başarıyla kurulduysa, `false` aksi halde.
*/
bool NetworkManager::connectToServer()
{
if (!isWiFiConnected())
Expand Down Expand Up @@ -532,4 +542,4 @@ void NetworkManager::updateAdaptiveBuffer()
size_t NetworkManager::getAdaptiveBufferSize()
{
return AdaptiveBuffer::getBufferSize();
}
}
81 changes: 73 additions & 8 deletions tests/unit/test_event_bus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,27 @@ EventBus* eventBus = nullptr;
int callback_count = 0;
SystemEvent last_event = SystemEvent::SYSTEM_STARTUP;

/**
* @brief Test yardımcı geri çağırma; çağrılma sayısını artırır ve varsa iletilen olay yükünü kaydeder.
*
* Gelen `data` eğer null değilse, bunun `const SystemEvent*` olduğu varsayılır ve `last_event`
* global değişkeni bu değere güncellenir. Her çağrıldığında `callback_count` global sayacı bir arttırır.
*
* @param data Olay yükünü içeren işaretçi; `nullptr` olabilir. İşaretçi null değilse `const SystemEvent*` olarak yorumlanır.
*/
void test_callback(const void* data) {
callback_count++;
if (data) {
last_event = *static_cast<const SystemEvent*>(data);
}
}

/**
* @brief Her bir testten önce ortak test ortamını sıfırlar ve EventBus örneğini hazırlar.
*
* Bu fonksiyon test öncesi çağrılır; çağrı sayacı ve son olay değerini başlatır, yeni bir
* EventBus örneği oluşturur ve örneğin oluşturulduğunu ve başarılı şekilde başlatıldığını doğrular.
*/
void setUp(void) {
// Initialize before each test
callback_count = 0;
Expand All @@ -30,6 +44,12 @@ void setUp(void) {
TEST_ASSERT_TRUE(eventBus->initialize());
}

/**
* @brief Her testten sonra global EventBus örneğini güvenli şekilde temizler.
*
* Eğer global `eventBus` mevcutsa, çalışmayı sonlandırır, belleğini serbest bırakır
* ve global işaretçiyi `nullptr` olarak sıfırlar.
*/
void tearDown(void) {
// Cleanup after each test
if (eventBus) {
Expand All @@ -39,7 +59,11 @@ void tearDown(void) {
}
}

// Test: EventBus Initialization
/**
* @brief EventBus'in başlatıldığını doğrular.
*
* Unity testinde EventBus örneğinin `isInitialized()` çağrısının `true` döndüğünü doğrular.
*/
void test_eventbus_initialization() {
TEST_ASSERT_TRUE(eventBus->isInitialized());
}
Expand Down Expand Up @@ -75,7 +99,12 @@ void test_event_publication() {
TEST_ASSERT_EQUAL(1, callback_count);
}

// Test: Multiple Subscribers
/**
* @brief Aynı olaya birden fazla abonenin kaydedilebildiğini doğrulayan bir birim testi.
*
* Bu test, aynı SystemEvent türü için birden fazla abonelik oluşturduktan sonra
* EventBus'un çökmeden veya hata vermeden devam ettiğini doğrular.
*/
void test_multiple_subscribers() {
int subscriber1_count = 0;
int subscriber2_count = 0;
Expand All @@ -99,7 +128,12 @@ void test_multiple_subscribers() {
TEST_ASSERT_TRUE(true); // Placeholder - passes if no crash
}

// Test: Priority Handling
/**
* @brief Olay abonelerinin öncelik düzeyine göre çalıştırılma sırasını doğrular.
*
* Üç farklı öncelikte (CRITICAL, HIGH, NORMAL) aynı olaya abone olur, olayı yayımlar ve kuyruğu işler;
* ardından abonelerin yürütülme sırasının CRITICAL → HIGH → NORMAL olduğunu doğrulayan test aserasyonlarını yürütür.
*/
void test_priority_handling() {
int execution_order[3] = {0, 0, 0};
int execution_index = 0;
Expand Down Expand Up @@ -142,7 +176,16 @@ void test_priority_handling() {
TEST_ASSERT_EQUAL(1, execution_order[2]);
}

// Test: Immediate vs Queued Events
/**
* @brief Kuyruklu ve anlık olay yayınlama davranışını doğrular.
*
* Bu birim testi, EventBus'un kuyruklanan (queued) olayları processEvents() çağrısına
* kadar beklettiğini ve anlık (immediate) olarak yayımlanan olayları hemen işlediğini doğrular:
* - AUDIO_BUFFER_READY için bir abone kaydeder.
* - Kuyruklu yayınlandığında geri çağrının processEvents() çağrısına kadar tetiklenmediğini,
* processEvents() sonrası tetiklendiğini kontrol eder.
* - Anlık (immediate) yayınlandığında geri çağrının hemen tetiklendiğini kontrol eder.
*/
void test_immediate_vs_queued() {
eventBus->subscribe(
SystemEvent::AUDIO_BUFFER_READY,
Expand Down Expand Up @@ -183,7 +226,12 @@ void test_event_data_payload() {
eventBus->publish(SystemEvent::CPU_OVERLOAD, &test_event, true);
}

// Test: Unsubscribe
/**
* @brief Aboneliğin kaldırılmasının etkisini doğrular.
*
* NETWORK_DISCONNECTED olayına "test" etiketiyle abone olunup sonra aynı etiketle
* aboneliğin iptal edilmesinin, yayımlanan olayların kayıtlı geri çağırmayı tetiklemediğini doğrular.
*/
void test_unsubscribe() {
eventBus->subscribe(
SystemEvent::NETWORK_DISCONNECTED,
Expand All @@ -201,7 +249,12 @@ void test_unsubscribe() {
TEST_ASSERT_EQUAL(0, callback_count);
}

// Test: Event Statistics
/**
* @brief SYSTEM_STARTUP olay yayınlandığında abone geri çağrılarının sayısını doğrular.
*
* Sisteme `SYSTEM_STARTUP` için bir abonelik ekler, aynı olayı beş kez yayımlar,
* bekleyen olayları işler ve test callback'inin tam olarak 5 kez çağrıldığını doğrular.
*/
void test_event_statistics() {
eventBus->subscribe(
SystemEvent::SYSTEM_STARTUP,
Expand All @@ -221,7 +274,12 @@ void test_event_statistics() {
TEST_ASSERT_EQUAL(5, callback_count);
}

// Test: Event Queue Overflow Handling
/**
* @brief Olay kuyruğu taşması durumunun EventBus tarafından düzgün şekilde ele alındığını doğrular.
*
* Bu birim testi, aynı olaya 100 kez yayın yapıp olayları işledikten sonra en az bir geri çağırmanın çalıştırıldığını kontrol eder;
* amaç, kuyruk taşması senaryosunda EventBus'ın hatasız şekilde bazı olayları işlemesini sağladığını doğrulamaktır.
*/
void test_queue_overflow() {
eventBus->subscribe(
SystemEvent::AUDIO_BUFFER_READY,
Expand All @@ -242,6 +300,13 @@ void test_queue_overflow() {
TEST_ASSERT_TRUE(callback_count > 0);
}

/**
* @brief EventBus birim testlerini kaydeder ve çalıştırır.
*
* Programın test giriş noktası; tüm tanımlı EventBus testlerini Unity çerçevesi altında çalıştırır.
*
* @return int Unity test koşucusunun bitiş/kod sonucu.
*/
int main(int argc, char **argv) {
UNITY_BEGIN();

Expand All @@ -257,4 +322,4 @@ int main(int argc, char **argv) {
RUN_TEST(test_queue_overflow);

return UNITY_END();
}
}
Loading