<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Fuzzing on Tarragon</title><link>https://tarrragon.github.io/blog/tags/fuzzing/</link><description>Recent content in Fuzzing on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 22 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/fuzzing/index.xml" rel="self" type="application/rss+xml"/><item><title>7.6 CI、fuzz、load test 與 chaos testing</title><link>https://tarrragon.github.io/blog/go-advanced/07-distributed-operations/reliability-pipeline/</link><pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/go-advanced/07-distributed-operations/reliability-pipeline/</guid><description>&lt;p>可靠性驗證流程的核心責任是讓不同層級的測試回答不同風險。Unit test 驗證規則，integration test 驗證協定協作，race test 檢查資料競爭，&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/fuzz-test/" data-link-title="Fuzz Test" data-link-desc="說明用隨機與變異輸入驗證解析器與邊界處理健壯性">fuzz test&lt;/a> 尋找輸入邊界，&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/load-test/" data-link-title="Load Test" data-link-desc="說明在預期流量下驗證容量、延遲與降級策略的測試">load test&lt;/a> 驗證容量，&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/chaos-test/" data-link-title="Chaos Test" data-link-desc="說明透過受控故障注入驗證系統在異常條件下的恢復能力">chaos test&lt;/a> 驗證失敗復原。&lt;/p>
&lt;h2 id="本章目標">本章目標&lt;/h2>
&lt;p>學完本章後，你將能夠：&lt;/p>
&lt;ol>
&lt;li>分辨不同測試層級各自要防的風險&lt;/li>
&lt;li>把 race、fuzz、load 與 chaos 放到合適的流程裡&lt;/li>
&lt;li>設計能回饋容量規劃的驗證流程&lt;/li>
&lt;li>不把端到端測試當成萬能答案&lt;/li>
&lt;li>讓測試結果回到 deployment 與 runtime 邊界&lt;/li>
&lt;/ol>
&lt;h2 id="前置章節">前置章節&lt;/h2>
&lt;ul>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/go/05-error-testing/testing-basics/" data-link-title="5.2 testing 基礎" data-link-desc="用 testing package 驗證函式行為">Go 入門：testing 基礎&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/go-advanced/05-testing-reliability/websocket-integration/" data-link-title="5.2 WebSocket integration test" data-link-desc="驗證 client/server 實際互動">Go 進階：WebSocket integration test&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/go-advanced/05-testing-reliability/race-check/" data-link-title="5.3 race condition 檢查" data-link-desc="用 go test -race 找資料競爭">Go 進階：race condition 檢查&lt;/a>&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/go-advanced/05-testing-reliability/table-tests/" data-link-title="5.4 table-driven test 的設計邊界" data-link-desc="避免測試資料混雜太多概念">Go 進階：table-driven test 的設計邊界&lt;/a>&lt;/li>
&lt;/ul>
&lt;h2 id="後續撰寫方向">後續撰寫方向&lt;/h2>
&lt;ol>
&lt;li>CI 中哪些測試應每次執行，哪些可以排程或合併前執行。&lt;/li>
&lt;li>Fuzzing 適合驗證 parser、normalizer 與 protocol decoder 的哪些邊界。&lt;/li>
&lt;li>Load test 如何設定 client 數、message rate、payload size 與觀測指標。&lt;/li>
&lt;li>Chaos testing 如何模擬 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/broker/" data-link-title="Broker" data-link-desc="說明 broker 在訊息傳遞系統中負責保存、路由與交付訊息">broker&lt;/a> 斷線、資料庫延遲、server shutdown 與網路抖動。&lt;/li>
&lt;li>測試結果如何回饋到 capacity planning 與 feature gate。&lt;/li>
&lt;/ol>
&lt;h2 id="觀察不同測試層級回答不同問題">【觀察】不同測試層級回答不同問題&lt;/h2>
&lt;p>可靠性驗證最怕的錯誤，是把所有測試都塞成一種樣子。不同層級應該分工：&lt;/p>
&lt;ul>
&lt;li>unit test：規則有沒有寫對&lt;/li>
&lt;li>integration test：協定與元件有沒有接對&lt;/li>
&lt;li>race test：並發邊界有沒有資料競爭&lt;/li>
&lt;li>fuzz test：輸入邊界有沒有漏掉&lt;/li>
&lt;li>load test：容量與延遲是否能接受&lt;/li>
&lt;li>chaos test：失敗發生時系統能不能復原&lt;/li>
&lt;/ul>
&lt;h2 id="判讀race-test-是輔助檢查">【判讀】race test 是輔助檢查&lt;/h2>
&lt;p>&lt;code>go test -race&lt;/code> 能抓出實際跑到的資料競爭，但它不是正確性保證。真正的重點仍然是：&lt;/p>
&lt;ul>
&lt;li>state owner 是誰&lt;/li>
&lt;li>哪些資料需要 lock&lt;/li>
&lt;li>哪些資料應該只讓單一 goroutine 擁有&lt;/li>
&lt;li>哪些資料應該複製而不是共享&lt;/li>
&lt;/ul>
&lt;h2 id="策略load-test-的輸出要能回到容量判斷">【策略】load test 的輸出要能回到容量判斷&lt;/h2>
&lt;p>load test 不應只是跑出一個數字，還要能回答：&lt;/p>
&lt;ul>
&lt;li>哪個 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/queue/" data-link-title="Queue" data-link-desc="說明 queue 如何保存等待處理的工作並形成容量邊界">queue&lt;/a> 開始變長&lt;/li>
&lt;li>哪個 DB &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/connection-pool/" data-link-title="Connection Pool" data-link-desc="說明連線池如何限制下游資源並影響服務容量">connection pool&lt;/a> 開始飽和&lt;/li>
&lt;li>哪種 message rate 會讓 latency 明顯上升&lt;/li>
&lt;li>哪個 memory curve 表示需要調整 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/buffer/" data-link-title="Buffer" data-link-desc="說明系統如何用暫存空間吸收短暫速度差與尖峰流量">buffer&lt;/a> 或 GC 參數&lt;/li>
&lt;/ul>
&lt;p>如果沒有這些觀察點，壓測結果就很難轉成實際修正。&lt;/p>
&lt;h2 id="執行chaos-test-應該模擬真實失敗">【執行】chaos test 應該模擬真實失敗&lt;/h2>
&lt;p>chaos test 的重點是模擬真實世界常見的失敗：&lt;/p>
&lt;ul>
&lt;li>broker 暫時不可用&lt;/li>
&lt;li>&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/database/" data-link-title="Database" data-link-desc="說明 database 在後端系統中如何承擔正式狀態、查詢與一致性責任">database&lt;/a> 延遲上升&lt;/li>
&lt;li>shutdown 中斷流量&lt;/li>
&lt;li>網路抖動或 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/timeout/" data-link-title="Timeout" data-link-desc="說明等待外部操作的時間上限如何保護資源與使用者體驗">timeout&lt;/a>&lt;/li>
&lt;/ul>
&lt;p>這些情境應該回到 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/graceful-shutdown/" data-link-title="Graceful Shutdown" data-link-desc="說明服務停止前如何排空流量、完成工作與保存狀態">graceful shutdown&lt;/a>、retry、&lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/idempotency/" data-link-title="Idempotency" data-link-desc="說明同一操作執行多次時如何保持結果一致">idempotency&lt;/a> 與 &lt;a href="https://tarrragon.github.io/blog/backend/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="說明下游處理速度不足時系統如何讓上游依下游能力送出工作">backpressure&lt;/a> 設計。&lt;/p></description><content:encoded><![CDATA[<p>可靠性驗證流程的核心責任是讓不同層級的測試回答不同風險。Unit test 驗證規則，integration test 驗證協定協作，race test 檢查資料競爭，<a href="/blog/backend/knowledge-cards/fuzz-test/" data-link-title="Fuzz Test" data-link-desc="說明用隨機與變異輸入驗證解析器與邊界處理健壯性">fuzz test</a> 尋找輸入邊界，<a href="/blog/backend/knowledge-cards/load-test/" data-link-title="Load Test" data-link-desc="說明在預期流量下驗證容量、延遲與降級策略的測試">load test</a> 驗證容量，<a href="/blog/backend/knowledge-cards/chaos-test/" data-link-title="Chaos Test" data-link-desc="說明透過受控故障注入驗證系統在異常條件下的恢復能力">chaos test</a> 驗證失敗復原。</p>
<h2 id="本章目標">本章目標</h2>
<p>學完本章後，你將能夠：</p>
<ol>
<li>分辨不同測試層級各自要防的風險</li>
<li>把 race、fuzz、load 與 chaos 放到合適的流程裡</li>
<li>設計能回饋容量規劃的驗證流程</li>
<li>不把端到端測試當成萬能答案</li>
<li>讓測試結果回到 deployment 與 runtime 邊界</li>
</ol>
<h2 id="前置章節">前置章節</h2>
<ul>
<li><a href="/blog/go/05-error-testing/testing-basics/" data-link-title="5.2 testing 基礎" data-link-desc="用 testing package 驗證函式行為">Go 入門：testing 基礎</a></li>
<li><a href="/blog/go-advanced/05-testing-reliability/websocket-integration/" data-link-title="5.2 WebSocket integration test" data-link-desc="驗證 client/server 實際互動">Go 進階：WebSocket integration test</a></li>
<li><a href="/blog/go-advanced/05-testing-reliability/race-check/" data-link-title="5.3 race condition 檢查" data-link-desc="用 go test -race 找資料競爭">Go 進階：race condition 檢查</a></li>
<li><a href="/blog/go-advanced/05-testing-reliability/table-tests/" data-link-title="5.4 table-driven test 的設計邊界" data-link-desc="避免測試資料混雜太多概念">Go 進階：table-driven test 的設計邊界</a></li>
</ul>
<h2 id="後續撰寫方向">後續撰寫方向</h2>
<ol>
<li>CI 中哪些測試應每次執行，哪些可以排程或合併前執行。</li>
<li>Fuzzing 適合驗證 parser、normalizer 與 protocol decoder 的哪些邊界。</li>
<li>Load test 如何設定 client 數、message rate、payload size 與觀測指標。</li>
<li>Chaos testing 如何模擬 <a href="/blog/backend/knowledge-cards/broker/" data-link-title="Broker" data-link-desc="說明 broker 在訊息傳遞系統中負責保存、路由與交付訊息">broker</a> 斷線、資料庫延遲、server shutdown 與網路抖動。</li>
<li>測試結果如何回饋到 capacity planning 與 feature gate。</li>
</ol>
<h2 id="觀察不同測試層級回答不同問題">【觀察】不同測試層級回答不同問題</h2>
<p>可靠性驗證最怕的錯誤，是把所有測試都塞成一種樣子。不同層級應該分工：</p>
<ul>
<li>unit test：規則有沒有寫對</li>
<li>integration test：協定與元件有沒有接對</li>
<li>race test：並發邊界有沒有資料競爭</li>
<li>fuzz test：輸入邊界有沒有漏掉</li>
<li>load test：容量與延遲是否能接受</li>
<li>chaos test：失敗發生時系統能不能復原</li>
</ul>
<h2 id="判讀race-test-是輔助檢查">【判讀】race test 是輔助檢查</h2>
<p><code>go test -race</code> 能抓出實際跑到的資料競爭，但它不是正確性保證。真正的重點仍然是：</p>
<ul>
<li>state owner 是誰</li>
<li>哪些資料需要 lock</li>
<li>哪些資料應該只讓單一 goroutine 擁有</li>
<li>哪些資料應該複製而不是共享</li>
</ul>
<h2 id="策略load-test-的輸出要能回到容量判斷">【策略】load test 的輸出要能回到容量判斷</h2>
<p>load test 不應只是跑出一個數字，還要能回答：</p>
<ul>
<li>哪個 <a href="/blog/backend/knowledge-cards/queue/" data-link-title="Queue" data-link-desc="說明 queue 如何保存等待處理的工作並形成容量邊界">queue</a> 開始變長</li>
<li>哪個 DB <a href="/blog/backend/knowledge-cards/connection-pool/" data-link-title="Connection Pool" data-link-desc="說明連線池如何限制下游資源並影響服務容量">connection pool</a> 開始飽和</li>
<li>哪種 message rate 會讓 latency 明顯上升</li>
<li>哪個 memory curve 表示需要調整 <a href="/blog/backend/knowledge-cards/buffer/" data-link-title="Buffer" data-link-desc="說明系統如何用暫存空間吸收短暫速度差與尖峰流量">buffer</a> 或 GC 參數</li>
</ul>
<p>如果沒有這些觀察點，壓測結果就很難轉成實際修正。</p>
<h2 id="執行chaos-test-應該模擬真實失敗">【執行】chaos test 應該模擬真實失敗</h2>
<p>chaos test 的重點是模擬真實世界常見的失敗：</p>
<ul>
<li>broker 暫時不可用</li>
<li><a href="/blog/backend/knowledge-cards/database/" data-link-title="Database" data-link-desc="說明 database 在後端系統中如何承擔正式狀態、查詢與一致性責任">database</a> 延遲上升</li>
<li>shutdown 中斷流量</li>
<li>網路抖動或 <a href="/blog/backend/knowledge-cards/timeout/" data-link-title="Timeout" data-link-desc="說明等待外部操作的時間上限如何保護資源與使用者體驗">timeout</a></li>
</ul>
<p>這些情境應該回到 <a href="/blog/backend/knowledge-cards/graceful-shutdown/" data-link-title="Graceful Shutdown" data-link-desc="說明服務停止前如何排空流量、完成工作與保存狀態">graceful shutdown</a>、retry、<a href="/blog/backend/knowledge-cards/idempotency/" data-link-title="Idempotency" data-link-desc="說明同一操作執行多次時如何保持結果一致">idempotency</a> 與 <a href="/blog/backend/knowledge-cards/backpressure/" data-link-title="Backpressure" data-link-desc="說明下游處理速度不足時系統如何讓上游依下游能力送出工作">backpressure</a> 設計。</p>
<h2 id="延伸測試結果應回饋到-feature-gate">【延伸】測試結果應回饋到 feature gate</h2>
<p>如果某個功能在 load test 或 chaos test 下風險太高，最直接的做法不一定是先修完整系統，也可能是先用 feature gate 逐步推出、觀察與回收。</p>
<h2 id="本章不處理">本章不處理</h2>
<p>本章不會綁定特定 CI 或壓測平台。教材重點會放在測試層級分工，避免把所有風險都塞進端到端測試。</p>
<h2 id="和-go-教材的關係">和 Go 教材的關係</h2>
<p>這一章承接的是 Go 的並發測試與可靠性驗證；如果你要先回看語言教材，可以讀：</p>
<ul>
<li><a href="/blog/go/05-error-testing/testing-basics/" data-link-title="5.2 testing 基礎" data-link-desc="用 testing package 驗證函式行為">Go：測試基礎</a></li>
<li><a href="/blog/go-advanced/05-testing-reliability/websocket-integration/" data-link-title="5.2 WebSocket integration test" data-link-desc="驗證 client/server 實際互動">Go 進階：WebSocket integration test</a></li>
<li><a href="/blog/go-advanced/05-testing-reliability/race-check/" data-link-title="5.3 race condition 檢查" data-link-desc="用 go test -race 找資料競爭">Go 進階：race condition 檢查</a></li>
<li><a href="/blog/go-advanced/05-testing-reliability/table-tests/" data-link-title="5.4 table-driven test 的設計邊界" data-link-desc="避免測試資料混雜太多概念">Go 進階：table-driven test 的設計邊界</a></li>
</ul>
]]></content:encoded></item></channel></rss>