Komutları Taklit Etme ve Dış Araçlar için Saplama Oluşturma
Gerçek sistemlere dokunmadan betikleri test etmek için PATH'i geçersiz kılın ve sahte ikili dosyalar tanımlayın.
Komutları Taklit Etme ve Dış Araçlar için Saplama Oluşturma, CoddyKit'te ücretsiz bir DevOps Bootcamp dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, DevOps Bootcamp öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. DevOps Bootcamp kursu toplamda 4 dersten oluşur.
Bash Testlerinde Komutlar Neden Taklit Edilir?
curl, aws, git veya herhangi bir harici aracı çağıran bir Bash betiğini test ettiğinizde bir sorunla karşılaşırsınız: Gerçek çağrılar ağa erişir, durumu değiştirir, maliyet oluşturur veya bu araçların kurulu olmadığı sürekli tümleştirme ortamında basitçe başarısız olur.
Taklit etme, gerçek komutu sizin denetlediğiniz sahte bir komutla değiştirmek anlamına gelir. Sahte komutunuz ( yalancı ) öngörülebilir çıktı ve çıkış kodları döndürür; böylece testiniz hızlı, yalıtılmış ve yeniden üretilebilir olur.
- Ağ veya bulut erişimi gerekmez
- Testler saniyeler yerine milisaniyeler içinde çalışır
- Gerçek sistemlerde tetiklenmesi zor olan hataları benzetebilirsiniz
- Sürekli tümleştirme işlem hatları temiz kalır ve bağımlılık gerektirmez
Bash bunu yapmak için şaşırtıcı derecede basit bir mekanizma sunar: sahte ikili dosyanızı $PATH üzerinde gerçek dosyadan daha önce aranan bir konuma yerleştirmeniz yeterlidir.
PATH Aramasının Çalışma Şekli
Kabuk curl gibi bir komutu çalıştırdığında, $PATH içindeki her dizini soldan sağa arar ve bulduğu ilk eşleşmeyi çalıştırır.
Bu, kendi curl betiğinizi içeren bir dizini başa eklerseniz kabuğun /usr/bin/curl konumuna hiçbir zaman ulaşmayacağı anlamına gelir.
Geçersiz kılma kalıbı:
- Geçici bir dizin oluşturun (sahte ikili dosyalarınızın bulunduğu dizin)
- Gerçek komutla aynı ada sahip sahte bir çalıştırılabilir dosya yazın
- Bu dizini
PATHdeğişkeninin başına ekleyin - Test edilen betiğinizi çalıştırın; gerçek ikili dosyayı değil, sahte dosyanızı çağırır
- Testten sonra geçici dizini temizleyin
Bu yöntem kök erişimi gerektirmeden, sistem dosyalarını değiştirmeden ve özel bir çatıya ihtiyaç duymadan çalışır.
Sahte Dosya Dizini Oluşturma
Standart yaklaşım, sahte dosyalarınız için yalıtılmış bir geçici dizin oluşturmak üzere mktemp -d kullanır. Her test veya test paketi kendi dizinine sahip olur; böylece testler arası kirlenme önlenir.
Testiniz tamamlandıktan sonra dizini rm -rf ile kaldırın. Bir trap kullanmak, test bir hata nedeniyle erken sonlansa bile temizliğin yapılmasını sağlar.
#!/usr/bin/env bash
# Setup a stub bin directory for testing
# Create the temp dir
STUB_BIN=$(mktemp -d)
# Always clean up on exit (success, error, or signal)
trap 'rm -rf "$STUB_BIN"' EXIT
# Prepend it to PATH so our stubs take priority
export PATH="$STUB_BIN:$PATH"
echo "Stub bin: $STUB_BIN"
echo "PATH starts with: ${PATH%%:*}"
# Your tests would go here...
echo "Tests complete."İlk Sahte Dosyanızı Yazma
Sahte dosya, değiştirmek istediğiniz komutla aynı ada sahip çalıştırılabilir bir dosyadan ibarettir. Test edilen betiğinizin beklediği çıktıyı yazdırır ve seçtiğiniz kodla çıkar.
Sahte dosyalar için temel kurallar:
- Dosya çalıştırılabilir olmalıdır (
chmod +x) - Shebang satırı (
#!/usr/bin/env bash) gereklidir - Gerçek betiğinizin ayrıştıracağı çıktıyı yazdırın
- Başarı için
exit 0, benzetilmiş başarısızlıklar için sıfır olmayan bir değer kullanın
#!/usr/bin/env bash
# Create a stub for 'curl' that returns a fake HTTP response
STUB_BIN=$(mktemp -d)
trap 'rm -rf "$STUB_BIN"' EXIT
export PATH="$STUB_BIN:$PATH"
# Write the stub
cat > "$STUB_BIN/curl" << 'EOF'
#!/usr/bin/env bash
# Fake curl: always returns a 200 OK with a JSON body
echo '{"status": "ok", "version": "1.2.3"}'
exit 0
EOF
chmod +x "$STUB_BIN/curl"
# Verify the stub is found before the real curl
which curl
curl https://example.com/api/versioncurl Çağıran Bir Betiği Test Etme
Şimdi hepsini bir araya getirelim. Bir sağlık uç noktasını kontrol etmek için curl çağıran ve hizmet sağlıklı değilse hatayla çıkan bir dağıtım betiğiniz olduğunu varsayalım. Gerçek bir sunucu olmadan hem başarılı yolu hem de başarısızlık yolunu test etmek istersiniz.
#!/usr/bin/env bash
# Script under test: check_health.sh
# It calls curl and checks the returned JSON
check_health() {
local url="$1"
local response
response=$(curl -sf "$url")
if [[ "$response" == *'"healthy":true'* ]]; then
echo "Service is UP"
return 0
else
echo "Service is DOWN" >&2
return 1
fi
}
# ---- Test harness ----
STUB_BIN=$(mktemp -d)
trap 'rm -rf "$STUB_BIN"' EXIT
export PATH="$STUB_BIN:$PATH"
# Happy path stub
cat > "$STUB_BIN/curl" << 'EOF'
#!/usr/bin/env bash
echo '{"healthy":true}'
EOF
chmod +x "$STUB_BIN/curl"
check_health "http://fake-host/health" && echo "PASS: healthy response"Komut Hatalarını Simüle Etme
Sahte uygulamaların en değerli kullanım alanlarından biri, gerçek araçlarla yeniden oluşturulması zor olan hataları simüle etmektir: ağ zaman aşımı, izin hataları, diskin dolması veya uzak bir API'nin 500 döndürmesi gibi.
Bir hatayı simüle etmek için sahte uygulamanızın sıfır olmayan bir kodla çıkmasını sağlamanız yeterlidir. Ayrıca gerçek komutun yapacağı gibi stderr'a yazabilir ve böylece betiğinizin hata işleme davranışını bütünüyle sınayabilirsiniz.
#!/usr/bin/env bash
# Test that check_health handles a curl failure gracefully
check_health() {
local url="$1"
local response
# -f makes curl exit non-zero on HTTP error; -s silences progress
if ! response=$(curl -sf "$url" 2>/dev/null); then
echo "ERROR: could not reach $url" >&2
return 1
fi
echo "OK: $response"
}
STUB_BIN=$(mktemp -d)
trap 'rm -rf "$STUB_BIN"' EXIT
export PATH="$STUB_BIN:$PATH"
# Failure stub — simulates a network error (curl exit code 6 = could not resolve host)
cat > "$STUB_BIN/curl" << 'EOF'
#!/usr/bin/env bash
echo 'curl: (6) Could not resolve host: fake-host' >&2
exit 6
EOF
chmod +x "$STUB_BIN/curl"
if ! check_health "http://fake-host/health"; then
echo "PASS: failure path handled correctly"
fiDoğrulama İçin Sahte Uygulama Çağrılarını Kaydetme
Bazen yalnızca betiğinizin ne çıktıladığını değil, harici bir aracı nasıl çağırdığını da doğrulamanız gerekir: aktardığı bağımsız değişkenler, kaç kez çağrıldığı veya çağrıların sırası gibi. Casus sahte uygulama, çağrılarını bir dosyaya kaydeder.
Sınamadan sonra test yardımcınız kayıt dosyasını okur ve içeriğini doğrular. Böylece özel bir çerçeveye ihtiyaç duymadan bağımsız değişken düzeyinde doğrulama yapabilirsiniz.
#!/usr/bin/env bash
# Spy stub: record every invocation of 'aws' to a log file
STUB_BIN=$(mktemp -d)
CALL_LOG=$(mktemp)
trap 'rm -rf "$STUB_BIN" "$CALL_LOG"' EXIT
export PATH="$STUB_BIN:$PATH"
export CALL_LOG # make it available inside the stub
cat > "$STUB_BIN/aws" << 'EOF'
#!/usr/bin/env bash
# Append all arguments to the call log
echo "aws $*" >> "$CALL_LOG"
# Return fake S3 output
echo "upload: ./report.pdf to s3://my-bucket/report.pdf"
exit 0
EOF
chmod +x "$STUB_BIN/aws"
# Simulate the script under test calling aws s3 cp
aws s3 cp report.pdf s3://my-bucket/report.pdf
aws s3 cp logs.tar.gz s3://my-bucket/logs.tar.gz
# Verify calls were made with expected arguments
echo "--- Recorded calls ---"
cat "$CALL_LOG"
grep -q 's3://my-bucket/report.pdf' "$CALL_LOG" && echo "PASS: S3 upload verified"Birden Çok Komutu Aynı Anda Sahte Uygulamayla Değiştirme
Gerçek bir betik çoğu zaman birkaç harici aracı çağırır. Bunların tümünü aynı STUB_BIN dizininde sahte uygulamalarla değiştirebilirsiniz. Her sahte dosya bağımsızdır ve farklı çıktılarla çıkış kodları döndürebilir.
Sahte uygulamaları küçük tutun: yalnızca sınanan betiğin gerçekten ayrıştırdığı şeyi döndürün. Her seçeneği simüle etmeye çalışmayın; yalnızca betiğinizin kullandığı alt kümeyi ele alın.
#!/usr/bin/env bash
# Stub both 'git' and 'docker' for a release script test
STUB_BIN=$(mktemp -d)
trap 'rm -rf "$STUB_BIN"' EXIT
export PATH="$STUB_BIN:$PATH"
# Stub git: pretend we are on tag v2.1.0
cat > "$STUB_BIN/git" << 'EOF'
#!/usr/bin/env bash
case "$*" in
*"describe --tags"*) echo "v2.1.0" ;;
*"rev-parse HEAD"*) echo "abc1234" ;;
*) echo "[git stub] unhandled: $*" >&2 ; exit 1 ;;
esac
EOF
chmod +x "$STUB_BIN/git"
# Stub docker: pretend build and push succeed
cat > "$STUB_BIN/docker" << 'EOF'
#!/usr/bin/env bash
echo "[docker stub] $*"
exit 0
EOF
chmod +x "$STUB_BIN/docker"
# Simulate the release logic
VERSION=$(git describe --tags)
SHA=$(git rev-parse HEAD)
echo "Building image for version=$VERSION sha=$SHA"
docker build -t "myapp:$VERSION" .
docker push "myapp:$VERSION"İşlevleri Sahte Uygulama Olarak Kullanma (Dosya Gerekmez)
Basit durumlarda hiç dosya yazmanız gerekmez. Komutla aynı ada sahip bir kabuk işlevi tanımlayabilirsiniz. İşlevler harici PATH aramasından önce çözümlendiği için otomatik olarak öncelik kazanır.
Bu, kaynak alınan betikleri birim olarak sınamanın en hızlı yoludur. Ancak işlev tabanlı sahte uygulamalar yalnızca aynı kabuk süreci içinde çalışır; açıkça bash -c ile oluşturulan alt kabuklarda veya arka planda çalıştırılan süreçlerde görünür olmaz. Bu durumlarda dosya tabanlı yaklaşımı kullanın.
#!/usr/bin/env bash
# Source the script under test (a small helper library)
source_under_test() {
# Inline the logic we want to test
get_instance_id() {
# Would normally call: curl http://169.254.169.254/latest/meta-data/instance-id
curl -sf http://169.254.169.254/latest/meta-data/instance-id
}
}
source_under_test
# Override curl with a shell function stub
curl() {
echo "i-0abc123def456"
return 0
}
# Export is NOT needed — function is visible in same shell
# Run the function under test
result=$(get_instance_id)
[[ "$result" == "i-0abc123def456" ]] && echo "PASS: instance ID returned" || echo "FAIL"İşlevleri Alt Kabuklara Dışa Aktarma
Sınanan betiğiniz bir alt kabuk başlattığında (örneğin bash script.sh veya bir iş hattı), üst süreçte tanımlanan kabuk işlevi sahte uygulamaları varsayılan olarak devralınmaz. İki seçeneğiniz vardır:
- İşlevi dışa aktarmak için
export -f function_namekullanın; işlev altbashsüreçlerinde kullanılabilir hâle gelir - Ya da süreç sınırları arasında her zaman çalışan bir
STUB_BINdizinindeki dosya tabanlı sahte uygulamalara geri dönün
export -f zarif bir çözümdür ancak yalnızca bash ile çalışır (sh veya diğer kabuklarla değil). Birden çok dilin kullanıldığı sürekli tümleştirme ortamlarında dosya tabanlı sahte uygulamaları tercih edin.
#!/usr/bin/env bash
# Demonstrate export -f for subshell-visible function stubs
# Define the stub in the current shell
curl() {
echo '{"status":"ok"}'
return 0
}
# Export the function so child bash processes inherit it
export -f curl
# Verify the stub works in a subshell
bash -c '
response=$(curl -sf http://api.example.com/status)
echo "Subshell got: $response"
'
# Without export -f, the subshell would call the real curl
# (or fail if curl is not installed)Sahte Uygulamaları Bir Sınama Çerçevesiyle Tümleştirme (BATS)
BATS (Bash Otomatik Sınama Sistemi) kullandığınızda sahte uygulama kurulumu setup() kancasına, temizleme işlemi ise teardown() kancasına aittir. BATS, sınamalar arasında ortamı sıfırlar; böylece her sınama yeni bir sahte uygulama dizini alır.
$BATS_TEST_TMPDIR gibi BATS değişkenleri her sınama için otomatik olarak geçici bir dizin sağlar; daha temiz kod için mktemp -d yerine bunu kullanın.
#!/usr/bin/env bats
# File: test_deploy.bats
# Run with: bats test_deploy.bats
setup() {
# BATS provides a unique tmpdir per test
export STUB_BIN="$BATS_TEST_TMPDIR/stub_bin"
mkdir -p "$STUB_BIN"
export PATH="$STUB_BIN:$PATH"
# Default stub: healthy service
cat > "$STUB_BIN/curl" << 'EOF'
#!/usr/bin/env bash
echo '{"healthy":true}'
EOF
chmod +x "$STUB_BIN/curl"
}
teardown() {
# BATS auto-removes BATS_TEST_TMPDIR, but explicit is safer
rm -rf "$STUB_BIN"
}
@test "deploy succeeds when service is healthy" {
run bash deploy.sh
[ "$status" -eq 0 ]
[[ "$output" == *"Deploy complete"* ]]
}
@test "deploy aborts when service is down" {
# Override the stub for this specific test
echo -e '#!/usr/bin/env bash\nexit 1' > "$STUB_BIN/curl"
chmod +x "$STUB_BIN/curl"
run bash deploy.sh
[ "$status" -ne 0 ]
}Bilgi Kontrolü: Bash'te Komutları Taklit Etme
Bash'te komut taklidi ve sahte uygulama kalıpları konusundaki anlayışınızı sınayın.
Bir geliştirici, gerçek AWS CLI'yi sahte uygulamayla değiştirmek için aws adlı bir kabuk işlevi tanımlayan bir sınama yazar. Sınama doğrudan uçbirimde sorunsuz çalışır; ancak sürekli tümleştirme iş hattı sınanan betiği bash deploy.sh olarak çalıştırdığında sahte uygulama yok sayılır ve gerçek aws komutu çağrılır.
Doğru düzeltme nedir?
Özet: Komutları Taklit Etme ve Harici Araçları Sahte Uygulamalarla Değiştirme
Bash betiklerini sınarken gerçek komutları denetimli sahte uygulamalarla değiştirmek için gereken araç takımının tamamını öğrendiniz.
Ele alınan temel teknikler:
PATH'i öne ekleme —mktemp -dile birSTUB_BINdizini oluşturun, buraya çalıştırılabilir sahte dosyalar yazın ve diziniPATH'in önüne ekleyin- Sahte uygulama çıkış kodları — başarı için
0, belirli hataları simüle etmek için sıfır olmayan değerler döndürün (ağ hataları, izin reddi vb.) - Casus sahte uygulamalar — betiğinizin harici araçları nasıl çağırdığını doğrulamak için bağımsız değişkenleri sahte uygulamanın içindeki bir günlük dosyasına ekleyin
- Birden çok sahte uygulama — tüm bağımlılık ekosistemini aynı anda taklit etmek için birkaç sahte dosyayı aynı
STUB_BINiçine yerleştirin - İşlev sahte uygulamaları — aynı süreçte taklit için komutla aynı ada sahip bir kabuk işlevi tanımlayın; alt bash süreçlerine ulaşmak için
export -fkullanın - BATS tümleştirmesi — temiz, sınama başına yalıtım için
setup()/teardown()kancalarını ve$BATS_TEST_TMPDIR'ı kullanın
Sınamanın sonucundan bağımsız olarak sahte uygulamaların temizlenmesini garanti etmek için her zaman trap '...' EXIT kullanın. Sahte uygulamaları küçük tutun; yalnızca betiğinizin gerçekten ayrıştırdığı şeyi döndürün. Dosya tabanlı sahte uygulamalar, sürekli tümleştirme iş hatları için en taşınabilir seçenektir.
Sıkça Sorulan Sorular
“Komutları Taklit Etme ve Dış Araçlar için Saplama Oluşturma” dersi ücretsiz mi?
Evet — “Komutları Taklit Etme ve Dış Araçlar için Saplama Oluşturma” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve DevOps Bootcamp kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. DevOps Bootcamp kursu toplamda 4 dersten oluşur.
“Komutları Taklit Etme ve Dış Araçlar için Saplama Oluşturma” dersinde ne öğreneceğim?
Gerçek sistemlere dokunmadan betikleri test etmek için PATH'i geçersiz kılın ve sahte ikili dosyalar tanımlayın. DevOps Bootcamp ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.
DevOps Bootcamp öğrenmeye başlamak için deneyim gerekli mi?
Önceden deneyim gerekmez. CoddyKit'te DevOps Bootcamp, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.
“Komutları Taklit Etme ve Dış Araçlar için Saplama Oluşturma” dersi ne kadar sürer?
Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.
Bu DevOps Bootcamp dersinde kod yazıp çalıştırabilir miyim?
Evet. Her DevOps Bootcamp dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.
Bu kursun tüm dersleri
- Bats-core ile Fonksiyonları Birim Testine Tabi Tutma
- Komutları Taklit Etme ve Dış Araçlar için Saplama Oluşturma
- Test Düzenekleri, Geçici Ortamlar ve Kapsam
- Kabuk Testlerini CI Pipeline'larında Çalıştırma