boost.test mit blockierender Funktion



  • Wir benutzten für unsere Unit-Tests boost.test und haben neuerdings die Anforderung, eine blockierende Funktion zu detektieren.
    Also es gibt eine Funktion oder besser einen Funktor

    struct Blocky
    {
        void operator()()
        {
            // hier steht unser Code, der im Fehlerfall blockiert
            // genau genommen handelt es sich um das Einlesen von einem Device, welches blockiert, wenn keine Daten mehr kommen
        }
    };
    

    der Teil unserer Testumgebung ist. In einem Testcase wird dies dann benutzt

    BOOST_AUTO_TEST_CASE( unserTest )
    {
        // .. irgendwas
        Blocky b;
        BOOST_TEST_WEISS_NICH_WAS( b, 2 /*sec*/ ); // hier sollte dann b() aufgerufen werden, und wenn das nach 2s nicht fertig ist, dann FEHLER.
    }
    

    Ich habe schon einiges probiert, was aber nicht funktioniert hat.
    Kennt sich jemand damit aus, und kann mir sagen wie man das richtig macht?
    Bem.: wir nutzen z.Zt. boost Version 1.35 - würden aber auch updaten, wenn nötig.

    Gruß
    Werner



  • Dazu müsstest du wenn ich das richtig sehe die blockierende Funktion von außerhalb irgendwie abschießen können, sonst wartet der Testcase immer so lange wie die Funktion blockiert. Wenn das tatsächlich in irgendeiner Weise möglich ist (z.B. durch irgendeinen interrupt), würde ein Vorgehen naiv gesehen doch wie folgt aussehen:

    - starte einen Thread mit der Funktion b (und stelle sicher dass der genügend CPU-Zeit bekommt)
    - warte im main-Thread 2 Sekunden drauf, ob der Thread zurückkommt (boost::timer z.B.), falls nicht, kille ihn und liefere ERROR

    Alternativ kannst das auch mit asio oder ähnlichem machen, ist im grunde aber das gleiche.
    Wenn du die blockierende Funktion nicht unterbrechen kannst hast du quasi das selbe in grün wie ich mit dem blockierenden Input (anderer Thread).



  • Danke pumuckl für die Antwort.

    Solche Gedanken haben wir natürlich auch - ich suchte nur eine 'schöne' Lösung, die einem solche Kopfstände abnimmt.
    Ich habe jetzt auch herausbekommen, dass der boost::execution_monitor das 'in der Werbung versprochene' Timeout unter Windows nicht unterstützt. Kaum liest man auch die Dokumentation für die 1.41 schon weiß man warum das mit der 1.35 nicht geht 🙄

    Gruß
    Werner



  • Die einzige "verschönernde" Änderung die ich hier vorschlagen könnte, wäre, den Thread einfach weiterlaufen zu lassen.

    Wenn du es so programmierst, dass der Thread korrekt weiter laufen kann, nachdem die Test-Funktion schon verlassen wurde, dann besteht kein Grund ihn zu killen. (Ich mag Threads killen nicht sonderlich)

    Das ist natürlich auch nur dann eine Option, wenn sicher ist, dass die Funktion die in dem Thread ausgeführt wird, andere Tests, die danach kommen, nicht behindern kann. Also z.B. keine globalen Resourcen "verbraucht", die andere Threads auch brauchen (z.B. Locks, Files oder Devices).

    Ansonsten einfach ExitProcess() machen. Ist wohl die "sauberste" Variante.


Anmelden zum Antworten