0

I am writing a tester for a program that is basically a game implemented on the terminal. User types in commands, it prints responses, etc. To test it I want to use a program to print commands more or less at random and then pipe that to the program being tested. Save the output from the program into a file and have the tester save the commands it gives. That creates a log that if something bad happened you can see what series of commands caused it. This is pretty simple to do:

./tester | ./program > results.out

But for the "less random" part it would help to be able to actually see the responses from the program and use scanf or something to pull out information on the game state (ie The tester sends the command to show the cards in hand, and then does some kind of logic to decide on the next command to send).

Based on this question and others, creating the loop itself seems pretty simple:

mkfifo fifo
./tester < fifo | ./program > fifo
rm fifo

But just doing it didn't work so in order to simplify the issue I've made two c programs. Lets call one pipetest1.c:

#include <stdio.h>
int main() {  
char input[10];
printf("test\n");   
scanf("%s",input);
printf("%s\n",input);   
return 0;
}

And the other pipetest2.c:

#include <stdio.h>
int main() {
char input[10];
scanf("%s",input);  
printf("%s\n",input);
scanf("%s",input);
printf("%s\n",input);   
return 0;
}

And then doing

mkfifo fifo
./pipetes1 < fifo | ./pipetes2> fifo
rm fifo

should print "test" twice. If I have understood this correctly anyway. But instead it just hangs. Which I am guessing is because of timing issues and it's getting stuck with both functions waiting for input?

So my questions are:

1) Is there something else that I have messed up here? 2) Or if not, is this a timing issue and is there some relatively easy fix for it? 3) Is this a terrible idea and I should stick to writing the tester such that it doesn't need to know what the responses are?

Community
  • 1
  • 1
HamHamJ
  • 435
  • 2
  • 10
  • by the way, your code will print "test" twice when fixed, but it'll do so where only the other program sees it. If you want it showing up on your terminal, `stderr` is still connected there in the setup you show here. – jthill Nov 27 '13 at 03:47

1 Answers1

1

You've got a network here, traffic being exchanged over communication links. Ordinarily, stdout isn't used for that, so it's set up to hold on to your output until there's a bufferful or, if there's a terminal involved, until you switch over to reading.

The fix is to switch to line-buffering, since your network packets are \n delimited. If they weren't you could switch to no buffering, but regardless, stick

setvbuf(stdout,0,_IOLBF,0);

up front in both programs, and you're good to go.

jthill
  • 55,082
  • 5
  • 77
  • 137