Sesi 03 dari 16

Model Keandalan Perangkat Lunak

Memprediksi masa depan keandalan software seperti cuaca — dengan model matematis yang dibangun dari data kegagalan nyata.

📐 SRGM & Matematis
🐍 Python scipy
📊 Curve Fitting
⏱️ 3 × 50 menit
🎯 Bagian 1 — Mengapa Kita Butuh Model Keandalan?

Model = Ramalan Berdasarkan Data

Tanpa model, kita tidak bisa menjawab pertanyaan kritis seperti: "Kapan software ini cukup andal untuk dirilis?" atau "Berapa banyak bug yang masih tersembunyi?"

💡 ANALOGI — Prakiraan Cuaca

Model keandalan seperti BMKG yang meramalkan cuaca.

BMKG tidak melihat masa depan secara langsung — mereka menggunakan data suhu, tekanan udara, kelembaban hari-hari sebelumnya, lalu memasukkannya ke model matematis untuk memperkirakan cuaca besok. Model keandalan bekerja persis sama: kita gunakan data kegagalan masa lalu untuk memprediksi kapan sistem akan gagal berikutnya, atau berapa banyak bug yang masih ada.

🔮

Prediksi Waktu Rilis

Kapan software siap dirilis? Model membantu menentukan apakah jumlah bug yang tersisa sudah di bawah ambang batas yang dapat diterima.

📦

Alokasi Sumber Daya

Berapa banyak tester yang masih dibutuhkan? Berapa lama fase pengujian harus berlangsung? Model memberikan estimasi berbasis data.

💰

Estimasi Biaya

Mengetahui berapa bug yang masih tersisa membantu menghitung biaya perbaikan yang diperlukan sebelum rilis.

📈

Monitoring Perkembangan

Apakah proses pengujian kita efektif? Model menunjukkan tren — apakah keandalan meningkat sesuai harapan atau tidak.

📂 Bagian 2 — Klasifikasi Model Keandalan

Dua Jenis Model Keandalan

🔭 Prediction Models

Memprediksi keandalan sebelum software selesai dibuat, berdasarkan karakteristik kode (kompleksitas, ukuran, dll). Seperti memperkirakan seberapa kuat sebuah jembatan berdasarkan blueprint-nya — sebelum dibangun.

📊 Estimation Models (SRGM)

Mengestimasi keandalan saat pengujian berlangsung, berdasarkan data kegagalan yang sudah terjadi. Seperti memperkirakan apakah mobil sudah layak jalan berdasarkan hasil uji coba di sirkuit test.

Dalam sesi ini kita fokus pada Software Reliability Growth Models (SRGM) — model estimasi yang paling banyak digunakan di industri.

📈 Konsep Dasar SRGM: "Reliability Grows Over Time"

SRGM didasarkan pada ide sederhana: setiap kali bug ditemukan dan diperbaiki, reliability software meningkat. Proses pengujian adalah proses "pertumbuhan keandalan".

💡 ANALOGI

SRGM seperti proses belajar mahasiswa sebelum ujian. Semakin banyak soal latihan dikerjakan (= pengujian), semakin banyak kelemahan ditemukan (= bug), dan setelah diperbaiki (= belajar dari kesalahan), kemampuan mahasiswa meningkat (= reliability tumbuh). Grafik nilainya pun naik secara bertahap, mirip dengan kurva SRGM.

Input Data yang Dibutuhkan:

  • Time-Between-Failures (TBF) — Waktu antara satu kegagalan dengan berikutnya
  • Failure Count Data — Jumlah kumulatif kegagalan per interval waktu

Output yang Diperoleh:

  • Prediksi jumlah bug yang tersisa
  • Estimasi waktu untuk mencapai target reliability
  • Failure rate di masa depan
🧮 Bagian 3 — Empat Model SRGM Utama

Model SRGM yang Wajib Anda Kuasai

MODEL 01
Jelinski-Moranda (J-M)
Dikembangkan 1972 · Model SRGM pertama yang dipublikasikan

Model paling sederhana dan tertua. Analoginya seperti setoples kelereng — setiap kali Anda menemukan dan mengambil satu kelereng (= bug diperbaiki), jumlah kelereng berkurang, dan probabilitas menemukan kelereng berikutnya juga berkurang.

Asumsi Utama
Formula
Failure Rate setelah (i-1) bug diperbaiki:
λᵢ = φ × (N₀ − (i−1))

Di mana: φ = failure rate per bug, N₀ = jumlah awal bug, i = ke-i kegagalan

✅ Kelebihan

  • Sangat sederhana dan mudah dipahami
  • Cocok sebagai pengantar SRGM
  • Parameter mudah diestimasi (hanya N₀ dan φ)

✗ Keterbatasan

  • Asumsi semua bug sama ukurannya tidak realistis
  • Tidak memodelkan imperfect debugging
  • Sering under/overestimate pada data nyata
MODEL 02
Goel-Okumoto (G-O) NHPP
Dikembangkan 1979 · Non-Homogeneous Poisson Process · Paling populer

Model ini menggunakan Non-Homogeneous Poisson Process (NHPP) — artinya jumlah kegagalan per satuan waktu berubah seiring berjalannya pengujian (tidak konstan). Analoginya seperti kurva belajar — paling banyak hal baru dipelajari di awal, lalu semakin lama semakin sedikit.

Asumsi Utama
Formula (Mean Value Function)
μ(t) = a × (1 − e−bt)

Di mana: a = jumlah total bug yang diharapkan ditemukan (N₀), b = failure detection rate, t = waktu pengujian
Failure Intensity: λ(t) = a·b·e−bt

✅ Kelebihan

  • Akurat untuk banyak dataset nyata
  • Hanya dua parameter (a dan b) — mudah difit
  • Memberikan prediksi jumlah total bug

✗ Keterbatasan

  • Fungsi intensitas selalu monoton turun (tidak bisa naik)
  • Tidak cocok untuk data dengan S-shaped growth
  • Asumsi perfect debugging
MODEL 03
Musa Basic Execution Time
Dikembangkan 1975 · Menggunakan execution time bukan calendar time

John Musa menyadari bahwa waktu kalender (jam/hari) bisa menipu — 8 jam pengujian oleh 1 tester tidak sama dengan 1 jam pengujian paralel oleh 8 tester. Solusinya: gunakan execution time (waktu CPU aktif menjalankan kode). Analoginya: mengukur bukan berapa jam kamu belajar, tapi berapa soal yang kamu kerjakan.

Konsep Execution Time
Execution Time = Waktu CPU × Faktor Komputasi

λ(τ) = λ₀ × e−(λ₀/ν₀)·τ

Di mana: τ = execution time, λ₀ = initial failure rate, ν₀ = total jumlah failure yang diharapkan

✅ Kelebihan

  • Lebih presisi karena menggunakan CPU time
  • Tidak terpengaruh jumlah tester atau lingkungan
  • Basis dari standar NASA dan banyak industri

✗ Keterbatasan

  • Sulit mengukur execution time yang akurat
  • Tidak praktis untuk sistem real-time
  • Butuh logging CPU yang detail
MODEL 04
Musa-Okumoto Logarithmic
Dikembangkan 1984 · Infinite bug model · Untuk sistem yang terus berkembang

Model ini berbeda: ia mengasumsikan jumlah bug tidak terbatas (infinite). Kenapa? Karena setiap kali software di-patch, ada kemungkinan bug baru masuk. Analoginya: seperti membersihkan rumah yang terus-menerus dikotori — selalu ada kotoran baru, tapi prosesnya tetap bisa dimodel secara logaritmik.

Formula
μ(t) = (1/θ) × ln(λ₀θt + 1)

Failure Intensity: λ(t) = λ₀ / (λ₀θt + 1)

Di mana: λ₀ = initial failure intensity, θ = failure intensity decay parameter

✅ Kelebihan

  • Cocok untuk software yang terus di-maintain
  • Menangani imperfect debugging
  • Sering cocok untuk software besar

✗ Keterbatasan

  • Asumsi infinite bug tidak selalu realistis
  • Lebih sulit diinterpretasikan
  • Konvergensi bisa lambat pada data kecil
⚖️ Bagian 4 — Perbandingan Keempat Model

Kapan Menggunakan Model yang Mana?

ModelAsumsi Jumlah BugJenis DataCocok UntukKompleksitas
Jelinski-MorandaFinite, homogenTBFSistem kecil, fase awal belajar SRGM⭐ Rendah
Goel-OkumotoFinite, inhomogenFailure countKebanyakan software komersial⭐⭐ Sedang
Musa BasicFiniteExecution timeSoftware embedded, sistem kritis⭐⭐ Sedang
Musa-Okumoto LogInfiniteExecution timeSoftware besar yang terus di-maintain⭐⭐⭐ Tinggi

Penting: Tidak ada model yang "terbaik" secara universal. Pilih model berdasarkan karakteristik data dan sistem Anda, lalu validasi dengan goodness-of-fit test (misalnya Kolmogorov-Smirnov atau Chi-Square).

🔢 Bagian 5 — Contoh Manual: Goel-Okumoto

Contoh Perhitungan Model G-O Step by Step

📊 STUDI KASUS — Aplikasi Manajemen Inventaris

Data kumulatif kegagalan selama pengujian: t=1 bulan → 5 failure, t=2 → 9, t=3 → 12, t=4 → 14, t=5 → 15. Gunakan model Goel-Okumoto μ(t) = a(1−e−bt).

1

Plot data dan amati polanya. Kumulatif failure: (1,5), (2,9), (3,12), (4,14), (5,15). Pola ini menunjukkan kurva yang mendatar — cocok untuk model eksponensial G-O.

2

Estimasi parameter a dan b secara intuitif. Pada t=5, kurva mulai mendatar mendekati 15. Jadi kita perkirakan a ≈ 16 (total bug yang diperkirakan). Dari data awal, pertumbuhan cepat → b ≈ 0.6.

3

Hitung μ(t) dengan a=16, b=0.6:
μ(1) = 16×(1−e−0.6) = 16×0.451 = 7.2 (aktual: 5)
μ(3) = 16×(1−e−1.8) = 16×0.835 = 13.4 (aktual: 12)
μ(5) = 16×(1−e−3.0) = 16×0.950 = 15.2 (aktual: 15)

4

Prediksi bug yang tersisa:
Jumlah bug tersisa ≈ a − μ(5) = 16 − 15.2 = ~1 bug lagi
Ini berarti software hampir siap dirilis!

5

Failure Intensity saat ini:
λ(5) = a·b·e−b×5 = 16 × 0.6 × e−3 = 9.6 × 0.0498 = 0.478 failure/bulan
Sangat kecil — artinya sistem sudah sangat andal!

✅ Kesimpulan: Berdasarkan model G-O, software ini memiliki ~1 bug tersisa dan failure intensity sudah sangat rendah (0.478/bulan). Layak untuk dipertimbangkan rilis dengan monitoring yang ketat.

🐍 Bagian 6 — Praktik Python: Fitting Model SRGM

Dari Model ke Kode Python Nyata

PRAKTIK: Fitting Model Goel-Okumoto dengan scipy.optimize Python 3.x
# ================================================================
# S11409 - Sesi 3: Fitting Software Reliability Growth Model (SRGM)
# Model: Goel-Okumoto (G-O) NHPP
# Dosen: Riadi Marta Dinata, S.Ti., M.Kom. | ISTN Jakarta
# ================================================================

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit
from scipy.stats import kstest
import warnings
warnings.filterwarnings('ignore')

# ── DATA KEGAGALAN KUMULATIF (bulan, cumulative failures) ──
t_data = np.array([1, 2, 3, 4, 5, 6, 7, 8])
m_data = np.array([5, 9, 12, 14, 15, 15.5, 15.8, 16])  # kumulatif

# ── DEFINISI MODEL ──
def goel_okumoto(t, a, b):
    """Goel-Okumoto Mean Value Function: μ(t) = a(1 - e^(-bt))"""
    return a * (1 - np.exp(-b * t))

def failure_intensity_go(t, a, b):
    """Failure Intensity: λ(t) = ab·e^(-bt)"""
    return a * b * np.exp(-b * t)

def jelinski_moranda_rate(i, phi, N0):
    """J-M Failure Rate: λ_i = φ(N0 - (i-1))"""
    return phi * (N0 - (i - 1))

# ── FITTING PARAMETER MODEL G-O ──
print("="*55)
print("  FITTING GOEL-OKUMOTO MODEL")
print("="*55)

popt, pcov = curve_fit(goel_okumoto, t_data, m_data,
                        p0=[20, 0.5],     # initial guess: a=20, b=0.5
                        bounds=([0, 0], [np.inf, np.inf]),
                        maxfev=10000)
a_fit, b_fit = popt
perr = np.sqrt(np.diag(pcov))

print(f"Parameter a (total bugs): {a_fit:.4f} ± {perr[0]:.4f}")
print(f"Parameter b (detect rate): {b_fit:.4f} ± {perr[1]:.4f}")

# ── PREDIKSI & EVALUASI ──
t_pred = np.linspace(0, 12, 200)  # prediksi hingga bulan 12
m_pred = goel_okumoto(t_pred, a_fit, b_fit)
lam_pred = failure_intensity_go(t_pred, a_fit, b_fit)

# Hitung residuals dan goodness-of-fit
m_fitted = goel_okumoto(t_data, a_fit, b_fit)
residuals = m_data - m_fitted
ss_res = np.sum(residuals**2)
ss_tot = np.sum((m_data - np.mean(m_data))**2)
r_squared = 1 - (ss_res / ss_tot)

print(f"\nGoodness of Fit R²        : {r_squared:.6f}")
print(f"RMSE                      : {np.sqrt(ss_res/len(m_data)):.4f}")

# ── PREDIKSI BUG TERSISA ──
bugs_found = m_data[-1]                       # sampai saat ini
bugs_remaining = a_fit - bugs_found
t_target = 9                                  # target bulan ke-9
m_at_target = goel_okumoto(t_target, a_fit, b_fit)
lam_at_target = failure_intensity_go(t_target, a_fit, b_fit)

print(f"\n--- PREDIKSI ---")
print(f"Total bug diperkirakan      : {a_fit:.1f}")
print(f"Bug ditemukan s/d bulan 8   : {bugs_found:.1f}")
print(f"Bug tersisa (perkiraan)     : {bugs_remaining:.2f}")
print(f"Failure intensity bulan 9   : {lam_at_target:.4f}/bulan")

# ── KAPAN LAYAK RILIS? ──
target_intensity = 0.1  # target failure rate yang bisa diterima
# Cari t ketika λ(t) ≤ target: t = -ln(target / (a*b)) / b
if a_fit * b_fit > target_intensity:
    t_release = -np.log(target_intensity / (a_fit * b_fit)) / b_fit
    print(f"Estimasi waktu siap rilis   : Bulan ke-{t_release:.1f}")
    print(f"  (saat failure intensity ≤ {target_intensity}/bulan)")

# ── VISUALISASI ──
fig, axes = plt.subplots(1, 3, figsize=(15, 5))
fig.suptitle('Software Reliability Growth Model - Goel-Okumoto',
             fontsize=14, fontweight='bold')

# Plot 1: Cumulative Failures (Data vs Model)
axes[0].scatter(t_data, m_data, color='#C8102E', s=80,
                zorder=5, label='Data Aktual')
axes[0].plot(t_pred, m_pred, color='#38BDF8', lw=2,
             label=f'G-O Fit (a={a_fit:.1f}, b={b_fit:.2f})')
axes[0].axhline(a_fit, color='#D4A017', linestyle='--',
                label=f'Total bugs ≈ {a_fit:.1f}')
axes[0].set_xlabel('Waktu Pengujian (bulan)')
axes[0].set_ylabel('Kumulatif Kegagalan')
axes[0].set_title('Cumulative Failure vs G-O Model')
axes[0].legend(fontsize=8); axes[0].grid(alpha=0.3)

# Plot 2: Failure Intensity (menurun = reliability meningkat)
axes[1].plot(t_pred, lam_pred, color='#22C55E', lw=2)
axes[1].axhline(target_intensity, color='#F97316',
                linestyle='--', label=f'Target λ = {target_intensity}')
axes[1].fill_between(t_pred, lam_pred, target_intensity,
                      where=(lam_pred <= target_intensity),
                      alpha=0.2, color='#22C55E', label='Zona Aman Rilis')
axes[1].set_xlabel('Waktu Pengujian (bulan)')
axes[1].set_ylabel('Failure Intensity λ(t)')
axes[1].set_title('Failure Intensity (Reliability Growth)')
axes[1].legend(fontsize=8); axes[1].grid(alpha=0.3)

# Plot 3: Residuals
axes[2].bar(t_data, residuals,
           color=['#22C55E' if r >= 0 else '#C8102E' for r in residuals],
           alpha=0.8)
axes[2].axhline(0, color='white', lw=1)
axes[2].set_xlabel('Waktu Pengujian (bulan)')
axes[2].set_ylabel('Residual (Aktual - Prediksi)')
axes[2].set_title(f'Residuals (R² = {r_squared:.4f})')
axes[2].grid(alpha=0.3)

plt.tight_layout()
plt.savefig('srgm_goel_okumoto.png', dpi=150, bbox_inches='tight')
print("\n✅ Grafik disimpan: srgm_goel_okumoto.png")

Instalasi dependensi: pip install numpy matplotlib scipy — Jalankan: python srgm_fitting.py

💡 Membaca Output Model

Parameter a (total bugs):

Jumlah bug total yang diperkirakan ada dalam software. Jika a=16.2 dan sudah 16 yang ditemukan, tersisa hanya 0.2 — sistem hampir bersih!

Parameter b (detection rate):

Seberapa cepat bug ditemukan. b besar = bug cepat ditemukan di awal. b kecil = proses penemuan bug lambat/merata.

R² mendekati 1:

R² > 0.99 artinya model sangat cocok dengan data. Jika R² rendah, coba model SRGM yang berbeda.

Zona Aman Rilis:

Ketika failure intensity sudah di bawah target (misal 0.1/bulan), software dianggap cukup andal untuk dirilis.

✏️ Bagian 7 — Latihan Mandiri
📝 KUIS SESI 3

Uji Pemahaman Anda

Soal 1 — Konseptual

Jelaskan dengan analogi sederhana mengapa model SRGM dibutuhkan dalam pengembangan software. Apa yang terjadi jika tim tidak menggunakan model dan hanya mengandalkan intuisi untuk menentukan waktu rilis?

Soal 2 — Hitungan Manual

Gunakan model Jelinski-Moranda: sebuah software diperkirakan memiliki N₀=20 bug, dengan φ=0.01 per jam. Hitunglah failure rate setelah: (a) 0 bug diperbaiki, (b) 5 bug diperbaiki, (c) 10 bug diperbaiki. Apa tren yang Anda lihat?

Soal 3 — Analisis G-O

Gunakan model G-O dengan a=25 dan b=0.4. Hitunglah: (a) μ(t) untuk t = 1, 2, 3, 5, 10 bulan, (b) Failure intensity λ(t) untuk t yang sama, (c) Kapan jumlah bug yang diharapkan mencapai 90% dari total (a)?

Soal 4 — Python Challenge

Modifikasi kode Python di atas untuk: (a) membandingkan model G-O dengan Jelinski-Moranda pada dataset yang sama, (b) menampilkan tabel perbandingan R² kedua model, (c) menentukan model mana yang lebih baik berdasarkan R² dan RMSE.

Soal 5 — Diskusi

Mengapa model Musa menggunakan "execution time" bukan "calendar time"? Berikan skenario nyata di mana penggunaan calendar time akan memberikan hasil yang menyesatkan jika digunakan dalam SRGM.

💡 Rangkuman Kunci Sesi 3

SRGM memodelkan pertumbuhan keandalan seiring bertambahnya bug yang ditemukan dan diperbaiki

Goel-Okumoto μ(t) = a(1−e⁻ᵇᵗ) adalah model paling populer dengan 2 parameter (a=total bugs, b=detection rate)

Failure intensity λ(t) turun artinya reliability meningkat — grafik ini yang ditunjukkan kepada manajemen

scipy.optimize.curve_fit adalah tool Python untuk meng-fit model ke data nyata secara otomatis

R² mendekati 1 menunjukkan model cocok dengan data — jika rendah, coba model SRGM berbeda

Tidak ada model universal terbaik — pilih berdasarkan karakteristik data dan validasi dengan uji statistik