לדלג לתוכן

פתרון בדיקות מוצר וחבילות אבחון

פתרון התרגיל הראשון

התוכנית הבאה משתמשת בseed עצמאי ומוודאת התנהגות בנקודות גבול. היא מצטרפת לwire.h, ואפשר לבנות אותה עם MSVC או Clang בלי מנוע fuzzing.

#include "wire.h"
#include <array>
#include <stdexcept>

void require(bool value) { if (!value) throw std::runtime_error("parser regression"); }

int main() {
    std::array<std::uint8_t, 20> seed{
        0x41,0x4d,0x54,0x31, 1,0, 1,0, 4,0,0,0, 7,0,0,0, 100,0,0,0};
    require(parse(seed).has_value());
    for (std::size_t size = 0; size < seed.size(); ++size)
        require(!parse(std::span(seed).first(size)));
    for (std::size_t index : {0u, 4u, 8u}) {
        auto invalid = seed;
        invalid[index] ^= 0x80;
        require(!parse(invalid));
    }
    std::array<std::uint8_t, 16> empty{
        0x41,0x4d,0x54,0x31, 1,0, 2,0, 0,0,0,0, 8,0,0,0};
    require(parse(empty).has_value());
    std::vector<std::uint8_t> trailing(seed.begin(), seed.end());
    trailing.push_back(0);
    require(!parse(trailing));
}

הבדיקה של כל prefix מתאימה להודעה הזאת כי אין לה prefix קצר יותר שהוא הודעה חוקית שלמה. בפרוטוקול שמאפשר כמה הודעות ברצף נצטרך parser שמחזיר גם מספר בתים שנצרכו, ואז משמעות הבדיקה תהיה שונה. החוזה מגדיר את הoracle של הבדיקה.

פתרון התרגיל השני

לפני כתיבה אפשר לדחות בלי שינוי מתמשך. אחרי כתיבה חלקית נצטרך לדעת אם האחסון יכול לזהות ולחתוך רשומה לא שלמה, או אם צריך להכניס אותו למצב poisoned עד התאוששות. אחרי flush מוצלח של commit, אובדן reply אינו מבטל את הcommit.

הבדיקה תפעיל restart בין הכשל לניסיון החוזר, משום שמפה בזיכרון אינה הוכחת dedup מתמשך. נשווה את זהות הלקוח, request ID ותוכן הבקשה, ונדרוש שאותה כוונה לא תתבצע שוב אחרי commit ידוע. אם הגבול החיצוני אינו תומך בהכרעה אטומית, נחזיר unknown עם דרך בירור במקום להבטיח בדיוק פעם אחת בלי מנגנון שמקיים זאת.

פתרון התרגיל השלישי

החבילה צריכה לאפשר למצוא את הבינארי, לטעון symbols תואמים, להזין את הקלט ולהפעיל את אותו תרחיש. אם חסרה תלויות runtime, נוסיף manifest והוראות הקמה מדויקות. אם רק שם קובץ מוחלט של המפתח חסר, נתקן את ההרצה כך שתשתמש בנתיב יחסי לחבילה.

שחזור מוצלח על מחשב אחר הוא ראיה שהחבילה כוללת את התנאים החשובים. הוא אינו מוכיח שמצאנו את סיבת השורש; לשם כך עדיין צריך להסביר את הinvariant שנשבר ולצרף בדיקה שמכשילה את הגרסה הישנה ומעבירה את המתוקנת.