vak: (Default)
[personal profile] vak
Я придумал решение для запуска REPL приложения, упомянутое в предыдущем посте. Напомню формулировку: есть интерактивная процедура на Си++ со следующим интерфейсом.
void application(std::istream &input, std::ostream &output);
Процедура работает в стиле REPL: берет ввод из входного потока, обрабатывает, выдаёт результат в выходной поток и ждёт следующего ввода. Мы хотим запустить эту процедуру из нашей программы на Си++, посылать ей команды и получать результат. Это, в частности, полезно для автоматического тестирования. Примерно так:
send("foo\n");
std::string reply = receive();
REQUIRE(reply == "bar\n");
Решение выглядит в виде класса Interact и работает следующим образом:
#include "interact.h"

Interact session(application);
REQUIRE(session.receive() == "Hello!\n");

session.send("foo\n");
REQUIRE(session.receive() == "bar\n");
Исходники можно взять на Гитхабе: https://github.com/sergev/interactРеализация должна быть понятна из комментариев.

Date: 2020-08-14 07:58 (UTC)
ircicq: (Default)
From: [personal profile] ircicq
Увидел, что Вы не используете "override specifier" ( https://en.cppreference.com/w/cpp/language/override)
В старом C++ его не было, а в других языках он обязателен.

Очень советую, помогает избежать ошибок из-за опечатки в имени метода или изменении типа аргумента.



Date: 2020-08-14 08:05 (UTC)
archaicos: Шарж (Default)
From: [personal profile] archaicos
Ещё const полезен.

Date: 2020-08-14 15:31 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Класс!

Date: 2020-08-14 18:49 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Ещё можно так: сделать обёртку, чтобы при неудаче программа завершалась нормально, а при удаче, наоборот - крэшилась, и напустить на это дело fuzzing. :)

Date: 2020-08-14 20:13 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Слишком простой алгоритм; за миллион с лишним прогонов нашлось меньше сотни разных путей выполнения, фаззингу не за что зацепиться. Хотя кратчайший ввод для достижения результата всего 20 байт: "\ntv0\n200\nt:0\n149\n20\n".

Date: 2020-08-15 01:44 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Это было без фаззинга, моей программой. Всегда можно вручную заменить последовательность одинаковых команд на увеличенный интервал, лишь бы ASCII-диапазона хватило. В данном случае повезло, что нужно было ровно 70 секунд и на свободное падение, и на торможение.

Это решение годится для большинства уровней (кроме 1 и 2, если не ошибаюсь).


Date: 2020-08-14 16:52 (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Ну это странный дизайн. А если я еще раз receive() вызову? Или это FSM, и каждый send изменяет статус, а потом receive возвращает аутпут в этом статусе? Не очевидно. По идее, это должна быть функция: вход -> выход, без всякого там state.

Date: 2020-08-14 17:23 (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Ну в варианте send/receive это уже не выглядело как repl.

Так у нас же функция, так? Ну и смотреть на это как на функцию.

Date: 2020-08-14 19:26 (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Я в чисто научном смысле. Как происходит обмен, не столь важно. Важно, что есть вход, и есть выход, и нет никакого внутреннего состояния.

Date: 2020-08-14 20:17 (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

О, т.е. есть State. Ну окей. Можно рисовать как (S,I) => (S,O)

Date: 2020-08-14 21:12 (UTC)
juan_gandhi: (Default)
From: [personal profile] juan_gandhi

Э не. Это тест будет генерировать в зависимости - если такой тест. Или такой юзер. Но для тестирования собственно функциональности такая гипотеза вредна.

Date: 2020-08-20 09:38 (UTC)
vlkamov: Рембрандт. Автопортрет с широко открытыми глазами. (Default)
From: [personal profile] vlkamov
> void application(std::istream &input, std::ostream &output);

> берет ввод из входного потока, обрабатывает, выдаёт результат в выходной поток и ждёт следующего ввода

Задумался о тупиках развития машинных языков. Второй вариант компилировался бы не хуже, а по понятности на 2..3 порядка лучше.