00 Donanım doğrulama neden gerekli
Gömülü Linux sistemlerde donanım doğrulama (hardware validation) üç temel amaca hizmet eder: üretim kabul testi (production acceptance test), kernel regresyon tespiti ve burn-in ile güvenilirlik doğrulaması.
Doğrulama gerektiren senaryolar
Test araçları ekosistemi
| Araç | Amaç | Güçlü yönü |
|---|---|---|
| LTP | Kernel syscall ve subsystem regresyon testi | 3000+ test case, kapsamlı syscall kapsamı |
| stress-ng | Donanım ve kernel stres oluşturma | 350+ stressor, ince ayarlı yük profilleri |
| cyclictest | RT gecikme ölçümü | Histogram, outlier tespiti, PREEMPT_RT doğrulama |
| memtester | RAM doğrulama (hata tespiti) | Bit-flip, ECC hatası tespiti |
| fio | Depolama I/O performans testi | Flash, eMMC, NVMe profilleme |
| iperf3 | Ağ performans testi | TCP/UDP throughput, jitter ölçümü |
Test piramidi
[ RT gecikme doğrulama — cyclictest ] <-- az sayıda, çok kritik
[ Burn-in / soaktest — stress-ng 24 saat ]
[ Regresyon — LTP syscalls, fs, mm, net testleri ]
[ Kabul testi — smoke test, temel fonksiyon doğrulama ] <-- her üretim kartı
Bu bölümde
- Üretim kabul testi: her kartta çalıştırılan hızlı smoke test
- Burn-in: tam yük altında saatler/günler — infant mortality tespiti
- Kernel regresyon: BSP veya sürücü değişikliği sonrası zorunlu
- LTP + stress-ng + cyclictest: gömülü Linux test ekosisteminin üç temel aracı
01 LTP genel bakış
Linux Test Project (LTP), IBM ve SGI tarafından 2000 yılında başlatılan, şu anda topluluk tarafından sürdürülen açık kaynak kernel test paketidir. 3000'den fazla test case ile Linux kernel syscall ve subsystem uyumluluğunu doğrular.
LTP test kategorileri
| Kategori | Dizin | Test sayısı (yaklaşık) | Ne test eder |
|---|---|---|---|
| syscalls | testcases/kernel/syscalls/ | ~1200 | POSIX syscall davranışı, hata kodları, edge case |
| mm | testcases/kernel/mem/ | ~80 | mmap, brk, mprotect, mremap, OOM killer |
| fs | testcases/kernel/fs/ | ~120 | ext4, xfs, tmpfs, dosya izinleri, inode limitler |
| net | testcases/network/ | ~90 | TCP/UDP soket, routing, netfilter |
| realtime | testcases/realtime/ | ~30 | SCHED_FIFO/RR, mutex, PI, latency |
| ipc | testcases/kernel/syscalls/ipc/ | ~60 | semaphore, message queue, shared memory |
| controllers | testcases/kernel/controllers/ | ~20 | cgroup v1/v2, cpu/memory/io controller |
LTP kaynak yapısı
| Yol | İçerik |
|---|---|
runtest/ | Test listesi dosyaları — her satır: test_adı komut |
testcases/ | Tüm test kaynak kodları ve binary'ler |
tools/ | runltp, ltp-pan (paralel runner), runtests.sh |
lib/ | Ortak test yardımcı fonksiyonları (tst_res, tst_timer...) |
doc/ | Test yazma rehberi, API belgeleri |
LTP test sonuç kodları
Bu bölümde
- LTP: 3000+ test case, syscall/mm/fs/net/rt kategorileri
- TPASS/TFAIL/TBROK/TCONF/TWARN: sonuç kodları — CI'da TFAIL ve TBROK kritik
- runtest/ dizini: hangi testlerin çalıştırılacağını belirleyen liste dosyaları
- gömülü board'da TCONF: kernel feature yoksa test otomatik atlanır
02 LTP kurulumu ve çalıştırma
LTP'yi hedef gömülü board için cross-compile etmek ve temel runltp komutlarıyla test çalıştırmak.
LTP cross-compile (gömülü board için)
# LTP kaynak kodunu al
git clone https://github.com/linux-test-project/ltp.git
cd ltp
# Bağımlılıklar (host derleme araçları)
sudo apt-get install -y \
autoconf automake pkg-config libtirpc-dev \
gcc make flex bison
# Cross-compile için (ARM Cortex-A, aarch64)
# CROSS_COMPILE: araç zinciri prefix'i
# prefix: hedef dosya sistemi kök dizini
make autotools
./configure \
--host=aarch64-linux-gnu \
--prefix=/opt/ltp \
CC=aarch64-linux-gnu-gcc \
CXX=aarch64-linux-gnu-g++
make -j$(nproc)
make DESTDIR=/tmp/ltp-sysroot install
# Hedef board'a kopyala
rsync -av /tmp/ltp-sysroot/opt/ltp root@192.168.1.100:/opt/
LTP yerel (native) kurulum — host test için
# x86_64 host üzerinde doğrudan derleme ve kurulum
./configure --prefix=/opt/ltp
make -j$(nproc)
sudo make install
# LTP kurulum dizini yapısı
ls /opt/ltp/
# bin/ — runltp, ltp-pan yürütücüleri
# testcases/ — test binary'leri
# runtest/ — test listesi dosyaları
# results/ — varsayılan sonuç dizini
# output/ — ham çıktı dosyaları
Temel runltp kullanımı
cd /opt/ltp
# Tam syscall test setini çalıştır
./runltp -f syscalls -l /tmp/ltp-syscalls.log
# Bellek (mm) testlerini çalıştır
./runltp -f mm -l /tmp/ltp-mm.log
# Birden fazla test seti
./runltp -f 'syscalls,mm,fs' -l /tmp/ltp-combined.log
# Timeout ile (her test için maksimum saniye)
./runltp -f syscalls -t 1h -l /tmp/ltp.log
# Paralel test çalıştırma (-j: paralellik sayısı)
./runltp -f syscalls -P 4 -l /tmp/ltp.log
# Belirli test atlama listesi (-S)
./runltp -f syscalls -S /opt/ltp/skiplist.txt
runltp parametreleri
| Parametre | Açıklama | Örnek |
|---|---|---|
-f FILE | runtest/ altındaki test listesi dosyası | -f syscalls |
-l LOGFILE | Sonuçların yazıldığı log dosyası | -l /tmp/ltp.log |
-o OUTDIR | Ham çıktı dizini | -o /tmp/ltp-out/ |
-t DURATION | Maksimum çalışma süresi | -t 2h, -t 30m |
-p | HTML format çıktı | -p -l report.html |
-q | Quiet mod — sadece PASS/FAIL | -q |
-v | Verbose mod — tüm mesajlar | -v |
-S FILE | Atlanacak testlerin listesi | -S skip.txt |
Bu bölümde
- Cross-compile: ./configure --host=aarch64-linux-gnu + make + rsync
- runltp -f syscalls -l logfile: en yaygın kullanım
- -t ile süre sınırı; -P ile paralel çalıştırma
- -S ile bilinen uyumsuz testleri atla — TCONF'tan farklı, CI'dan kasıtlı hariç tutma
03 Kritik LTP test setleri
Gömülü Linux sistemleri için en kritik LTP test setleri: mm (bellek yönetimi), fs (dosya sistemi) ve syscalls (sistem çağrısı uyumu). Her biri farklı kernel alt sistemini kapsar.
mm — bellek yönetimi testleri
# Tüm mm testleri
./runltp -f mm -l /tmp/mm.log
# Önemli mm testleri ayrı ayrı
./testcases/bin/mmap01 # mmap/munmap temel davranışı
./testcases/bin/oom01 # OOM killer tetikleme ve kurtarma
./testcases/bin/hugetlb01 # hugepage tahsis ve serbest bırakma
./testcases/bin/thp01 # Transparent Huge Pages
./testcases/bin/mtest01 # mmap ile bellek doğrulama
| Test adı | Ne test eder | Kritik senaryo |
|---|---|---|
| mmap01–15 | mmap/munmap/mprotect sistemik davranış | Sürücü mmap uygulaması, CMA tahsisi |
| oom01–05 | OOM killer — bellek tükenmesi kurtarma | Uzun süreli çalışmada bellek sızıntısı tespiti |
| mmapstress01 | Yoğun eşzamanlı mmap/munmap | Race condition ve kernel kilitleme hataları |
| vma01 | VMA birleştirme (merge) mantığı | mm subsystem kernel sürüm değişikliği sonrası |
fs — dosya sistemi testleri
# Genel fs testleri
./runltp -f fs -l /tmp/fs.log
# Inode/dentry stres testi (dosya sistemi doluluk testi)
./testcases/bin/fsstress \
-d /tmp/fsstress-dir \
-n 1000 \
-p 4
# eMMC/flash üzerinde doğrudan test — önce mount edin
mount /dev/mmcblk0p2 /mnt/test
./runltp -f fs -l /tmp/fs-emmc.log \
LTP_TMPDIR=/mnt/test/tmp
syscalls — sistem çağrısı uyumu
# Syscall testleri çok uzun sürer — alt kümelerle çalışın
# Temel I/O syscall'ları
./runltp -f syscalls \
-s 'read write open close stat' \
-l /tmp/io-syscalls.log
# Süreç yönetimi syscall'ları
./runltp -f syscalls \
-s 'fork clone execve wait' \
-l /tmp/proc-syscalls.log
# Sinyal testleri
./runltp -f syscalls \
-s 'signal kill sigaction' \
-l /tmp/signal-syscalls.log
network — ağ testleri
# Ağ testleri için loopback veya gerçek NIC gerekir
ip link set lo up # loopback etkin olmalı
# Temel ağ testi
./runltp -f net.features -l /tmp/net.log
# TCP soket testleri
./runltp -f net_stress.tcp -l /tmp/tcp.log
realtime — gerçek zamanlı testler
# RT testleri için SCHED_FIFO yetkisi gerekir (root)
./runltp -f realtime -l /tmp/rt.log
# Priority inversion ve mutex testi
./testcases/realtime/bin/pi_test
# RT task yaratma ve zamanlama
./testcases/realtime/bin/sched_latency
Bu bölümde
- mm: mmap/OOM/hugepage — bellek subsystem sağlığı
- fs: fsstress ile dosya sistemi tutarlılığı — eMMC/flash testleri için LTP_TMPDIR değiştir
- syscalls: POSIX uyumluluğu — alt kümelere böl, tümü çok uzun sürer
- realtime: PI mutex, SCHED_FIFO zamanlama — RT sistem doğrulama
04 stress-ng stressor kavramı
stress-ng, 350'den fazla stressor ile CPU, RAM, I/O, ağ ve kernel alt sistemlerini stres altına alan kapsamlı bir araçtır. Her stressor bağımsız bir yük bileşenidir.
stress-ng kurulumu
# Ubuntu/Debian paket yöneticisi
sudo apt-get install stress-ng
# Kaynak koddan derleme (gömülü board cross-compile için)
git clone https://github.com/ColinIanKing/stress-ng.git
cd stress-ng
make CC=aarch64-linux-gnu-gcc \
CFLAGS="-O2 -static" \
-j$(nproc)
# Statik binary: başka kütüphane gerektirmez — gömülü için ideal
file stress-ng
# stress-ng: ELF 64-bit LSB executable, ARM aarch64, statically linked
Temel stressor kullanımı
# CPU stressor: tüm çekirdekleri %100 yükler (genel)
stress-ng --cpu 4 --timeout 60s
# CPU stressor: belirli işlem türü
stress-ng --cpu 4 --cpu-method fft --timeout 60s
stress-ng --cpu 0 --cpu-method all --timeout 60s
# --cpu 0: CPU sayısı kadar işçi (otomatik)
# Bellek stressor: vm (sanal bellek)
stress-ng --vm 2 --vm-bytes 256M --timeout 60s
stress-ng --vm 2 --vm-bytes 75% --timeout 60s
# I/O stressor
stress-ng --io 4 --timeout 60s # fsync yoğun
stress-ng --hdd 2 --hdd-bytes 1G --timeout 60s # sabit disk yaz/oku
# Ağ stressor
stress-ng --sock 4 --timeout 60s # TCP soket oluşturma/kapatma
stress-ng --udp 4 --timeout 60s # UDP paket gönderme
# Zamanlayıcı ve süreç stressoru
stress-ng --fork 8 --timeout 60s # sürekli fork/exec
stress-ng --sched 4 --timeout 60s # zamanlayıcı yükü
Önemli stressor'lar
| Stressor | Amaç | Kritik parametre |
|---|---|---|
--cpu | CPU aritmetik ve kriptografik yük | --cpu-method: fft, matrixprod, sha256... |
--vm | malloc/memset/free döngüsü — bellek basıncı | --vm-bytes: yük miktarı |
--mmap | mmap/munmap döngüsü — VM subsystem | --mmap-bytes: eşleme boyutu |
--hdd | Sıralı ve rasgele disk yazma/okuma | --hdd-bytes, --hdd-write-size |
--io | fsync yoğun I/O — writeback basıncı | işçi sayısı |
--timer | Yüksek frekanslı kernel timer kesmeleri | --timer-freq: Hz cinsinden |
--pipe | Pipe yazma/okuma — IPC basıncı | --pipe-size |
--gpio | GPIO set/clear döngüsü (donanım gerekir) | --gpio-line |
stress-ng metrikleri
# İstatistik çıktısı — bops (bogo operations per second)
stress-ng --cpu 4 --timeout 30s --metrics
# Örnek çıktı:
# stress-ng: info: [1234] stressor bogo ops real time usr time sys time bogo ops/s
# stress-ng: info: [1234] cpu 48321 30.00 119.8 0.04 1610.69
# Verbose hata ayıklama
stress-ng --cpu 2 --timeout 10s --verbose
# JSON formatında çıktı (CI için)
stress-ng --cpu 4 --timeout 30s \
--metrics-brief \
--yaml /tmp/stress-results.yaml
Bu bölümde
- 350+ stressor: --cpu, --vm, --hdd, --io, --sock, --timer vb.
- --timeout: süre sınırı; --metrics: bogo ops/s performans ölçümü
- Statik derleme: gömülü board'a bağımlılıksız kopyalama imkânı
- --yaml: makine okunabilir çıktı — CI ve regresyon karşılaştırması için
05 Gömülü board burn-in senaryosu
Gömülü bir board için kapsamlı burn-in testi: CPU, RAM, flash depolama ve GPIO'yu aynı anda stres altında tutarak saatler boyunca çalıştırma ve sonuçları izleme.
Burn-in test senaryosu tasarımı
Başlangıç kontrolleri (temp, voltage) → Paralel stressor başlat
→ CPU full load + RAM tüm bellek + Flash yazma + GPIO toggle
→ Periyodik sağlık kontrolü (dmesg hata, temp limit)
→ Süre dol → İstatistik topla → Geçer/Kalır kararı
Kapsamlı burn-in scripti
#!/bin/bash
# burn-in.sh — Gömülü board burn-in testi
# Kullanim: ./burn-in.sh [sure_saat] [flash_mount]
# Ornek: ./burn-in.sh 8 /mnt/data
set -euo pipefail
DURATION_H=${1:-4} # varsayılan 4 saat
FLASH_MNT=${2:-/mnt/data} # flash test dizini
DURATION_S=$((DURATION_H * 3600))
LOG=/tmp/burnin-$(date +%Y%m%d-%H%M%S).log
FAIL=0
echo "=== BURN-IN BASLADI: ${DURATION_H} saat ===" | tee -a "$LOG"
echo "Tarih: $(date)" | tee -a "$LOG"
echo "Kernel: $(uname -r)" | tee -a "$LOG"
# --- CPU sayısını al ---
NCPUS=$(nproc)
# --- RAM miktarını al (MB) ---
RAM_MB=$(awk '/MemTotal/ {printf "%d", $2/1024}' /proc/meminfo)
# RAM'in %75'ini kullan
VM_MB=$(( RAM_MB * 75 / 100 ))
echo "CPU sayisi: $NCPUS | RAM: ${RAM_MB}MB | VM stres: ${VM_MB}MB" | tee -a "$LOG"
# --- Başlangıç sıcaklık kontrolü ---
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
TEMP=$(cat /sys/class/thermal/thermal_zone0/temp)
TEMP_C=$((TEMP / 1000))
echo "Baslangic sicaklik: ${TEMP_C}C" | tee -a "$LOG"
if [ "$TEMP_C" -gt 70 ]; then
echo "HATA: Baslangic sicakligi cok yuksek: ${TEMP_C}C" | tee -a "$LOG"
exit 1
fi
fi
# --- Flash I/O stres arka planda ---
if mountpoint -q "$FLASH_MNT"; then
stress-ng --hdd 1 \
--hdd-bytes 512M \
--temp-path "$FLASH_MNT" \
--timeout "${DURATION_S}s" \
--metrics >> "$LOG" 2>&1 &
FLASH_PID=$!
echo "Flash stres PID: $FLASH_PID" | tee -a "$LOG"
fi
# --- CPU + RAM kombine stres ---
stress-ng \
--cpu "$NCPUS" \
--cpu-method all \
--vm 2 \
--vm-bytes "${VM_MB}M" \
--vm-method all \
--io 2 \
--timeout "${DURATION_S}s" \
--metrics-brief \
--yaml /tmp/stress-metrics.yaml \
>> "$LOG" 2>&1 &
STRESS_PID=$!
echo "Stres PID: $STRESS_PID" | tee -a "$LOG"
# --- GPIO toggle testi (donanım varsa) ---
if [ -c /dev/gpiochip0 ]; then
# gpioset ile 1 Hz toggle (gpiotools gerekir)
( while kill -0 $STRESS_PID 2>/dev/null; do
gpioset gpiochip0 0=1
sleep 0.5
gpioset gpiochip0 0=0
sleep 0.5
done ) &
GPIO_PID=$!
fi
# --- Periyodik sağlık kontrolü (60 saniyede bir) ---
CHECK_INTERVAL=60
while kill -0 $STRESS_PID 2>/dev/null; do
sleep $CHECK_INTERVAL
# Sıcaklık kontrolü
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
TEMP=$(cat /sys/class/thermal/thermal_zone0/temp)
TEMP_C=$((TEMP / 1000))
echo "$(date +%H:%M:%S) sicaklik: ${TEMP_C}C" | tee -a "$LOG"
if [ "$TEMP_C" -gt 85 ]; then
echo "KRITIK: Termal limiti asildi! ${TEMP_C}C" | tee -a "$LOG"
kill $STRESS_PID 2>/dev/null || true
FAIL=1
break
fi
fi
# dmesg hata kontrolü
if dmesg --since "1 minute ago" | grep -qiE '(error|bug:|oops|panic|corruption)'; then
echo "HATA: Kernel hata mesaji tespit edildi!" | tee -a "$LOG"
dmesg --since "1 minute ago" | grep -iE '(error|bug:|oops|panic)' | tee -a "$LOG"
FAIL=1
fi
done
wait $STRESS_PID 2>/dev/null || true
[ -n "${FLASH_PID:-}" ] && wait $FLASH_PID 2>/dev/null || true
[ -n "${GPIO_PID:-}" ] && kill $GPIO_PID 2>/dev/null || true
# --- Sonuç ---
if [ "$FAIL" -eq 0 ]; then
echo "=== BURN-IN GECTI ===" | tee -a "$LOG"
exit 0
else
echo "=== BURN-IN BASARISIZ ===" | tee -a "$LOG"
exit 1
fi
Burn-in süresi rehberi
| Süre | Amaç | Ne yakalar |
|---|---|---|
| 30 dakika | Hızlı smoke test — fabrika hat testi | Belirgin donanım hataları, bağlantı sorunları |
| 4–8 saat | Standart burn-in | Isı dengesi, infant mortality |
| 24–72 saat | Uzun süreli güvenilirlik | Bellek ECC, termal kırılma, yazılım sızıntıları |
| 168 saat (1 hafta) | HALT/HASS — yüksek güvenilirlik gerektiren ürünler | Yaşam sonu hataları, uzun dönem drift |
Bu bölümde
- CPU + RAM + Flash + GPIO aynı anda — gerçekçi üretim yük senaryosu
- Periyodik sağlık kontrolü: sıcaklık sınırı + dmesg hata tespiti
- stress-ng --yaml: metrikleri makine okunabilir formatta kaydet
- Standart burn-in 4–8 saat; kritik ürünler için 24+ saat
06 cyclictest ile RT gecikme testi
cyclictest, PREEMPT_RT kernel'lerde ve endüstriyel gömülü sistemlerde maximum scheduling latency'yi ölçen referans araçtır. rt-tests paketinin parçasıdır.
cyclictest kurulumu
# Ubuntu/Debian
sudo apt-get install rt-tests
# Kaynak koddan cross-compile
git clone https://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git
cd rt-tests
make CROSS_COMPILE=aarch64-linux-gnu- cyclictest
# Sürüm kontrolü
cyclictest --version
# cyclictest v2.6
Temel cyclictest çalıştırma
# Temel test: SCHED_FIFO prio 80, 4 CPU thread, 1 dakika
cyclictest \
--mlockall \
--smp \
--priority 80 \
--interval 1000 \ # 1000 µs periyot
--distance 0 \
--loops 60000 \
--histogram 200 \
--histfile /tmp/cyclictest-hist.dat
# Açıklama:
# --mlockall: tüm belleği RAM'de kilitle (page fault yok)
# --smp: tüm CPU'larda thread aç
# --interval: ölçüm periyodu (µs)
# --distance: thread'ler arası periyot farkı (0=eşit)
# --loops: toplam ölçüm sayısı (0=sonsuz)
# --histogram: histogram çözünürlüğü (µs)
Yük altında test (stres kombinasyonu)
# 1. Arka planda ağır yük oluştur
stress-ng --cpu 0 \
--vm 2 \
--io 4 \
--timeout 120s &
STRESS_PID=$!
# 2. Yük altında RT gecikme ölç
cyclictest \
--mlockall \
--smp \
--priority 99 \
--interval 1000 \
--loops 100000 \
--histogram 400 \
--histfile /tmp/latency-under-load.dat
# 3. Stres'i durdur
kill $STRESS_PID
Histogram analizi ve görselleştirme
# cyclictest çıktısı:
# T: 0 (12345) P:80 I:1000 C: 60000 Min: 3 Act: 5 Avg: 4 Max: 18
# T: 1 (12346) P:80 I:1000 C: 60000 Min: 3 Act: 6 Avg: 5 Max: 21
# T: thread P: öncelik I: interval(µs) C: döngü sayısı
# Min/Avg/Max: minimum/ortalama/maksimum gecikme (µs)
# Gnuplot ile histogram görselleştirme
cat > /tmp/plot.gp <<'EOF'
set terminal png size 1200,600
set output '/tmp/latency-hist.png'
set title "RT Latency Histogram"
set xlabel "Latency (us)"
set ylabel "Count"
set logscale y
plot '/tmp/cyclictest-hist.dat' using 1:2 with linespoints title 'CPU0', \
'' using 1:3 with linespoints title 'CPU1'
EOF
gnuplot /tmp/plot.gp
Gecikme eşik değerleri
| Sistem türü | Tipik Max Gecikme | Kabul edilebilir sınır |
|---|---|---|
| PREEMPT_RT kernel, güçlü CPU | 10–50 µs | < 100 µs |
| Standart kernel (no RT patch) | 100–2000 µs | Uygulama bağımlı |
| Gömülü ARM Cortex-A (RT patch) | 20–100 µs | < 200 µs tipik |
| Endüstriyel kontrol (EtherCAT) | 5–30 µs | < 50 µs zorunlu |
| Gömülü MCU (bare-metal karşılaştırma) | < 5 µs | < 10 µs |
Outlier tespiti
# Anlık outlier raporu — eşiği aşan gecikmeleri say
cyclictest \
--mlockall \
--smp \
--priority 99 \
--interval 1000 \
--loops 1000000 \
--breaktrace 100 \ # 100 µs aşılırsa trace al ve dur
--tracer ftrace # ftrace ile iz kaydet
# Histogram dosyasından outlier sayısını hesapla
awk 'NR>1 && $1 >= 100 {sum += $2} END {print "100us+ outlier:", sum}' \
/tmp/cyclictest-hist.dat
Bu bölümde
- cyclictest --smp --mlockall --priority 99: standart RT gecikme ölçümü
- Yük altında ölçüm: stress-ng + cyclictest eşzamanlı çalışmalı
- --histogram ile gecikme dağılımı; --breaktrace ile outlier yakalama
- PREEMPT_RT ARM: <200 µs max kabul; EtherCAT <50 µs zorunlu
07 Sonuç analizi ve CI entegrasyonu
LTP ve stress-ng sonuçlarını makine okunabilir formatta kaydetmek, log ayrıştırma scripti yazmak ve CI pipeline'a entegre etmek.
LTP sonuç log formatı
# LTP log dosyasının formatı:
# mmap01 1 TPASS: mmap ile anonim sayfa tahsis edildi
# open01 0 TPASS: open() calistirildi
# oom01 1 TFAIL: OOM killer beklenmedik sureci sonlandirdi
# ioctl01 0 TCONF: bu cihazda ioctl destegi yok
# Sonuç özeti — TFAIL ve TBROK sayısı
grep -cE 'TPASS' /tmp/ltp.log
grep -cE 'TFAIL' /tmp/ltp.log
grep -cE 'TBROK' /tmp/ltp.log
grep -cE 'TCONF' /tmp/ltp.log
# Başarısız testlerin listesi
grep 'TFAIL\|TBROK' /tmp/ltp.log
LTP sonuç ayrıştırma scripti
#!/bin/bash
# parse-ltp.sh — LTP sonuçlarını ayrıştır ve geçer/kalır karar ver
# Kullanim: ./parse-ltp.sh /tmp/ltp.log [max_fail]
# Cikis kodu: 0=gecti, 1=basarisiz
LOGFILE=${1:?'log dosyasi belirtin'}
MAX_FAIL=${2:-0} # izin verilen maksimum TFAIL sayısı
PASS=$(grep -c 'TPASS' "$LOGFILE" || true)
FAIL=$(grep -c 'TFAIL' "$LOGFILE" || true)
BROK=$(grep -c 'TBROK' "$LOGFILE" || true)
CONF=$(grep -c 'TCONF' "$LOGFILE" || true)
TOTAL=$((PASS + FAIL + BROK))
echo "LTP Sonuc Ozeti"
echo "==============="
echo "TPASS: $PASS"
echo "TFAIL: $FAIL"
echo "TBROK: $BROK"
echo "TCONF: $CONF (atlandı)"
echo "Toplam: $TOTAL"
if [ "$FAIL" -gt 0 ] || [ "$BROK" -gt 0 ]; then
echo ""
echo "=== Basarisiz Testler ==="
grep 'TFAIL\|TBROK' "$LOGFILE"
fi
# Karar
if [ "$FAIL" -le "$MAX_FAIL" ] && [ "$BROK" -eq 0 ]; then
echo "SONUC: GECTI (TFAIL: $FAIL <= $MAX_FAIL)"
exit 0
else
echo "SONUC: BASARISIZ (TFAIL: $FAIL, TBROK: $BROK)"
exit 1
fi
GitHub Actions CI entegrasyonu
name: LTP Kernel Regression Test
on:
push:
paths:
- 'drivers/**'
- 'kernel/**'
- 'mm/**'
- 'fs/**'
jobs:
ltp-qemu:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Araçları kur
run: |
sudo apt-get update -q
sudo apt-get install -y qemu-system-x86 qemu-utils \
gcc make autoconf automake pkg-config libtirpc-dev
- name: LTP derle
run: |
git clone --depth=1 https://github.com/linux-test-project/ltp.git
cd ltp && make autotools
./configure --prefix=/opt/ltp
make -j$(nproc)
sudo make install
- name: Syscall testlerini çalıştır
run: |
sudo /opt/ltp/runltp -f syscalls \
-l /tmp/ltp-syscalls.log \
-t 30m \
-q
- name: Sonuçları ayrıştır
run: bash parse-ltp.sh /tmp/ltp-syscalls.log 0
- name: Artifact kaydet
if: always()
uses: actions/upload-artifact@v4
with:
name: ltp-results
path: /tmp/ltp-syscalls.log
Geçer/Kalır kriterleri tablosu
| Test | Geçer kriteri | Koşul |
|---|---|---|
| LTP syscalls | TFAIL = 0, TBROK = 0 | TCONF kabul edilebilir (skip) |
| LTP mm | TFAIL = 0 | OOM testleri yeterli RAM gerektir |
| stress-ng burn-in | Süre tamamlandı, exit 0 | Termal limiti aşılmadı, dmesg temiz |
| cyclictest RT | Max gecikme < eşik | Eşik: uygulama SRS'inden alınır |
Bu bölümde
- LTP log: grep TPASS/TFAIL/TBROK ile sonuç sayıları
- parse-ltp.sh: CI'da kullanılabilir ayrıştırma + exit code
- GitHub Actions: syscall regresyon testi QEMU üzerinde otomatik
- Geçer kriteri: TFAIL=0, TBROK=0 — TCONF (skip) kabul edilebilir
08 Üretim test otomasyonu
Fabrika test otomasyonu için LAVA (Lab Automation and Validation Architecture), pytest-board ve özel shell script yaklaşımları — her üretim kartı için tekrarlanabilir, paralel test çalıştırma.
Üretim test mimarisi
Test sunucusu (CI/CD) → LAVA dispatcher → USB/UART/Ethernet → DUT (board)
| | |
Test jobı üret Power on/off LTP + stress-ng
Sonuç topla Seri port izle Sonuç geri gönder
Pass/Fail karar Network boot dmesg, log
Basit fabrika test scripti
#!/bin/bash
# factory-test.sh — Üretim kabul testi (30 dakika)
# Her kart için çalıştırılır; seri numarasını log'a yazar
# Cikis: 0=geçti, 1=başarısız
set -euo pipefail
SERIAL=${1:?'Kart seri numarası gerekli'}
LOG="/var/log/factory-test-${SERIAL}-$(date +%Y%m%d-%H%M%S).log"
LTP_DIR=/opt/ltp
PASS=0
log() { echo "[$(date +%H:%M:%S)] $*" | tee -a "$LOG"; }
log "=== FABRIKA KABUL TESTI ==="
log "Seri No: $SERIAL"
log "Kernel: $(uname -r)"
log "CPU: $(grep 'model name' /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)"
# --- 1. CPU bilgi kontrolü ---
log "[1/5] CPU kontrol..."
CPUS=$(nproc)
[ "$CPUS" -ge 1 ] && log " PASS: $CPUS CPU aktif" || { log " FAIL: CPU sayisi hatalı"; PASS=1; }
# --- 2. RAM miktarı kontrolü ---
log "[2/5] RAM kontrol..."
RAM_MB=$(awk '/MemTotal/ {printf "%d", $2/1024}' /proc/meminfo)
MIN_RAM=512
if [ "$RAM_MB" -ge "$MIN_RAM" ]; then
log " PASS: RAM ${RAM_MB}MB (>= ${MIN_RAM}MB)"
else
log " FAIL: RAM ${RAM_MB}MB < ${MIN_RAM}MB"
PASS=1
fi
# --- 3. Hızlı bellek testi (memtester ile) ---
log "[3/5] Bellek testi (1 dakika)..."
if memtester 256M 1 >> "$LOG" 2>&1; then
log " PASS: memtester 256MB gecti"
else
log " FAIL: memtester hata"
PASS=1
fi
# --- 4. Flash yazma/okuma testi ---
log "[4/5] Flash I/O testi..."
TEST_FILE=/tmp/factory-io-test-$SERIAL
dd if=/dev/urandom of="$TEST_FILE" bs=1M count=64 2>> "$LOG"
dd if="$TEST_FILE" of=/dev/null bs=1M 2>> "$LOG"
rm -f "$TEST_FILE"
log " PASS: Flash 64MB yazma/okuma tamamlandı"
# --- 5. LTP hızlı smoke testi ---
log "[5/5] LTP syscall smoke testi..."
"$LTP_DIR/runltp" -f syscalls \
-s 'open01 read01 write01 close01 stat01 fork01 exec01' \
-l /tmp/ltp-smoke-"$SERIAL".log \
-q
TFAIL=$(grep -c 'TFAIL' /tmp/ltp-smoke-"$SERIAL".log || true)
if [ "$TFAIL" -eq 0 ]; then
log " PASS: LTP smoke testi gecti"
else
log " FAIL: LTP $TFAIL test basarisiz"
PASS=1
fi
# --- Sonuç ---
log "=== SONUC ==="
if [ "$PASS" -eq 0 ]; then
log "KABUL: $SERIAL GECTI"
echo "PASS:$SERIAL" >> /var/log/factory-results.csv
exit 0
else
log "RED: $SERIAL BASARISIZ"
echo "FAIL:$SERIAL:$(grep FAIL "$LOG" | head -5 | tr '\n' '|')" \
>> /var/log/factory-results.csv
exit 1
fi
pytest-board ile Python tabanlı test
"""
Gömülü board kabul testi — pytest + pexpect ile UART üzerinden
Kullanim: pytest test_board_acceptance.py --board-serial /dev/ttyUSB0
"""
import pytest
import pexpect
import re
TIMEOUT = 30 # saniye
@pytest.fixture(scope="session")
def board(request):
port = request.config.getoption("--board-serial", default="/dev/ttyUSB0")
conn = pexpect.spawn(f"picocom -b 115200 {port}")
conn.expect(r"\$|#", timeout=60) # shell prompt bekle
yield conn
conn.close()
def test_kernel_version(board):
board.sendline("uname -r")
board.expect(r"(\d+\.\d+\.\d+)", timeout=TIMEOUT)
version = board.match.group(1)
major = int(version.split(".")[0])
assert major >= 5, f"Kernel cok eski: {version}"
def test_cpu_count(board):
board.sendline("nproc")
board.expect(r"(\d+)", timeout=TIMEOUT)
ncpus = int(board.match.group(1))
assert ncpus >= 2, f"Beklenen 2+ CPU, bulunan: {ncpus}"
def test_ram_minimum(board):
board.sendline("awk '/MemTotal/ {print $2}' /proc/meminfo")
board.expect(r"(\d+)", timeout=TIMEOUT)
ram_kb = int(board.match.group(1))
assert ram_kb >= 512 * 1024, f"RAM yetersiz: {ram_kb // 1024} MB"
def test_ltp_smoke(board):
board.sendline(
"/opt/ltp/runltp -f syscalls -s 'open01 read01 write01' -q 2>&1 | tail -3"
)
idx = board.expect(["passed", "failed", pexpect.TIMEOUT], timeout=120)
assert idx == 0, "LTP smoke testi basarisiz"
LAVA job tanımı (örnek)
job_name: LTP Regression - BeagleBone Black
device_type: bbb
priority: medium
timeout:
job: 120
action: 60
actions:
- deploy:
to: tftp
kernel:
url: http://fileserver/images/bbb/zImage
type: zimage
dtb:
url: http://fileserver/images/bbb/am335x-boneblack.dtb
nfsrootfs:
url: http://fileserver/rootfs/ltp-rootfs.tar.gz
- boot:
method: u-boot
commands: nfs
prompts: ['root@bbb:~#']
- test:
timeout: 90
definitions:
- repository: https://git.linaro.org/qa/test-definitions.git
from: git
path: automated/linux/ltp/ltp.yaml
name: ltp-mm
parameters:
TEST_SUITE: mm
LTP_INSTALL_PATH: /opt/ltp
Bu bölümde
- factory-test.sh: CPU/RAM/Flash/LTP smoke — 30 dakika, her kart için
- pytest + pexpect: UART üzerinden Python tabanlı board test framework
- LAVA: Linaro'nun üretim sınıfı test otomasyonu — TFTP boot + NFS rootfs + test execution
- Sonuçlar CSV'ye yaz: fabrika veritabanına entegrasyon için yapılandırılmış çıktı