0

As a learning project Im writing a simple gui for Apache stresstesting command line tool "ab". It requiers a full URL, including a filename such as index.html or simular, as one of its parameters. If a filename is not specified "ab" echos "Invalid url" and shows a lists of available flags.

I would like to catch this "error" and have tried using NSTasks standarderror output. Can´t really get it to work. Would this even classify as an error that would pipe to a standard error?

Besides validating the URL input before launching the NSTask, do you think I can prevent or rather catch this error?

My simple code:

- (void) stressTest:(NSString *)url withNumberOfRequests:(int)requests sendSimultaneously:(int)connections {

    NSBundle *mainBundle = [NSBundle mainBundle];
    NSString *abPath = [[mainBundle bundlePath] stringByAppendingString:@"/Contents/Resources/ab"];

    NSString* requestsStr = [NSString stringWithFormat:@"%i", requests];
    NSString* connectionsStr = [NSString stringWithFormat:@"%i", connections];

    // Init objects for tasks and pipe
    NSTask *abCmd = [NSTask new];
    NSPipe *outputPipe = [NSPipe pipe];
    [abCmd setLaunchPath:abPath];
    [abCmd setArguments:[NSArray arrayWithObjects:@"-n", requestsStr, @"-c", connectionsStr, url, nil]];
    [abCmd setStandardOutput:outputPipe];
    [abCmd launch];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readCompleted:) name:NSFileHandleReadToEndOfFileCompletionNotification object:[outputPipe fileHandleForReading]];
    [[outputPipe fileHandleForReading] readToEndOfFileInBackgroundAndNotify];
}

- (void)readCompleted:(NSNotification *)notification {

    NSString * tempString = [[NSString alloc] initWithData:[[notification userInfo] objectForKey:NSFileHandleNotificationDataItem] encoding:NSASCIIStringEncoding];
   [resultTextOutlet setString:tempString];
   [[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleReadToEndOfFileCompletionNotification object:[notification object]];
}
Rachel Gallen
  • 27,943
  • 21
  • 72
  • 81
Kalle
  • 452
  • 2
  • 4
  • 19
  • Can you debug and tell us, where the error is exactly. I think it's at the point where you set the launch path, but to be sure. – ipinak Jan 19 '13 at 11:36
  • The error occurs when I lunch the NSTask. It can be repeated in OSX Terminal by typing ab -c 1 -n 1 htp://www.example.com. Ab requiers a filename in the URL. I´m not even sure that it would classify as an "error" that could be piped? – Kalle Jan 19 '13 at 11:58
  • You can pipe it, but you need to take it from the `main()` – ipinak Jan 19 '13 at 20:19
  • Great news but I´m to new at this to understand what that means, sorry! The main loop in my app or the NSApplicationMain? If you have time to elaborate I would appreciate it. However if it is very complex, don´t bather. It´s not a showstopper for me, I just want to learn. I´m currently avoiding the problem by strictly validating the URL before launching the NSEvent. – Kalle Jan 20 '13 at 19:14

1 Answers1

2

ab writes its error messages, including usage information, to standard error. You're currently only reading from standard output. To access the error messages or usage information you'll need to allocate a second NSPipe, pass it to -[NSTask setStandardError:], and then read data from it.

bdash
  • 18,110
  • 1
  • 59
  • 91
  • You are correct! AB does write to standardError, it was me who read it the wrong way. In my code above, add another pipe that listens to -setStandardError and put "nil" instead of the pipe object as the parameter "object:" to the Notification Center. Works fine now. Thanks! – Kalle Jan 21 '13 at 20:25