принудительное блокирование fgets (то есть подделка "интерактивного устройства") - PullRequest
1 голос
/ 04 марта 2010

У меня есть приложение на C, которое предоставляет «оболочку» для ввода команд. Я пытаюсь написать какой-нибудь автоматический тест-код для приложения (используя CUnit). Ввод "shell" читается из stdin так:

fgets(buf, sizeof(buf), stdin);

Я могу автоматически «записывать» команды в приложение, используя freopen () и помещая его в промежуточный файл. Когда приложение выполняется «нормально», блоки вызова fgets () доступны до тех пор, пока символы доступны, потому что это «интерактивное устройство», но не в промежуточном файле. Итак, как я могу подделать fgets, думая, что промежуточный файл является «интерактивным устройством».

Программа на C для Windows (XP) скомпилирована с использованием MinGW.

Привет!

Ответы [ 3 ]

1 голос
/ 04 марта 2010

Простое использование файла не сработает, как указали другие ответы. Итак, вам нужно решить, что вы собираетесь делать вместо этого. FIFO (именованный канал) или обычный (анонимный) канал может использоваться для подачи тестируемой интерактивной программы - или, в Unix, вы можете использовать псевдо-tty. Преимущество всего этого заключается в том, что программа блокируется при отсутствии чтения данных, ожидая получения следующей информации, а не сразу решая, что «нет данных для чтения, должна быть EOF».

Затем вам потребуется полуинтеллектуальная (или даже интеллектуальная) программа, периодически записывающая данные в канал для чтения тестируемой программой. Эта программа должна знать, как долго делать паузы между сообщениями, которые она пишет. Это может быть так же просто, как «подождите одну секунду; напишите следующую строку данных ». Или вы можете сделать что-то более сложное.

Одна известная мне схема имеет две программы - программу захвата для записи того, что пользователь вводит, и времени его (таким образом, файл «данных» структурирован; в нем есть записи, состоящие из задержки (в секундах и долях второй) плюс набор символов для отправки (количество и список байтов). Он запускается для захвата того, что пользователь вводит, и записи (а также для отправки данных в программу). Затем существует вторая программа воспроизведения, которая читает файл и интерпретирует задержки и последовательности символов.

Эта схема работает адекватно, если входная последовательность стабильна; если одна и та же последовательность нажатий клавиш всегда необходима для получения требуемого результата. Если данные, отправляемые в программу, должны адаптироваться к тому, что делает тестируемая программа, и к ее ответам, и могут делать разные вещи в разное время, то вам, вероятно, лучше перейти к « ожидайте ». Это дает возможность делать все, что вам нужно - по крайней мере, для программ без графического интерфейса.

1 голос
/ 04 марта 2010

fgets не блокируется при чтении из файла, поскольку он достигает конца файла, в результате чего EOF устанавливается в потоке и, таким образом, вызывает fgets немедленный возврат. Когда вы используете интерактивный ввод, EOF никогда не устанавливается, если, конечно, вы не наберете Ctrl-Z (или Ctrl-D в системе UNIX).

Если вы действительно хотите использовать промежуточный файл, я думаю, вам нужно улучшить свою оболочку, чтобы при достижении EOF она очищалась и повторно тестировалась после подходящего ожидания. Такая функция должна работать, я думаю: -

void waitForEofClear(FILE *f)
{
   while (feof(f)) {
      clearerr(f);
      sleep(1);
   }
}

Вы можете позвонить до fgets: -

waitForEofClear(stdin);
fgets(buf, sizeof(buf), stdin);
0 голосов
/ 04 марта 2010

Я не уверен, что такое эквивалент Windows, но в Linux я бы сделал промежуточный файл fifo. Если бы я собирался сделать настоящий нетривиальный автопилот, я бы завернул его в ожидаемый сценарий.

...