Skip to content

Commit f22b24b

Browse files
author
Madhuri Gummalla
authored
Merge pull request #329 from Microsoft/users/madhurig/pipeToFileAndTool
Add option to pipe to file and another tool
2 parents e4fd4e8 + 057056b commit f22b24b

File tree

2 files changed

+401
-60
lines changed

2 files changed

+401
-60
lines changed

node/test/toolrunnertests.ts

Lines changed: 271 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ describe('Toolrunner Tests', function () {
394394
done(err);
395395
});
396396
})
397-
it('Exec pipe output to another tool, succeeds if both tools succeed', function(done) {
397+
it('Exec pipe output to another tool, succeeds if both tools succeed', function (done) {
398398
this.timeout(20000);
399399

400400
var _testExecOptions = <trm.IExecOptions>{
@@ -457,7 +457,7 @@ describe('Toolrunner Tests', function () {
457457
});
458458
}
459459
})
460-
it('Exec pipe output to another tool, fails if first tool fails', function(done) {
460+
it('Exec pipe output to another tool, fails if first tool fails', function (done) {
461461
this.timeout(20000);
462462

463463
var _testExecOptions = <trm.IExecOptions>{
@@ -497,7 +497,7 @@ describe('Toolrunner Tests', function () {
497497
done(err);
498498
}
499499
else {
500-
assert(err && err.message && err.message.indexOf('print-output.exe') >=0, 'error from print-output.exe is not reported');
500+
assert(err && err.message && err.message.indexOf('print-output.exe') >= 0, 'error from print-output.exe is not reported');
501501
done();
502502
}
503503
})
@@ -530,7 +530,7 @@ describe('Toolrunner Tests', function () {
530530
}
531531
else {
532532
//assert(output && output.length > 0 && output.indexOf('ps: illegal option') >= 0, `error output "ps: illegal option" is expected. actual "${output}"`);
533-
assert(err && err.message && err.message.indexOf('/bin/ps') >=0, 'error from ps is not reported');
533+
assert(err && err.message && err.message.indexOf('/bin/ps') >= 0, 'error from ps is not reported');
534534
done();
535535
}
536536
})
@@ -539,7 +539,7 @@ describe('Toolrunner Tests', function () {
539539
})
540540
}
541541
})
542-
it('Exec pipe output to another tool, fails if second tool fails', function(done) {
542+
it('Exec pipe output to another tool, fails if second tool fails', function (done) {
543543
this.timeout(20000);
544544

545545
var _testExecOptions = <trm.IExecOptions>{
@@ -586,7 +586,7 @@ describe('Toolrunner Tests', function () {
586586
}
587587
else {
588588
assert(errOut && errOut.length > 0 && errOut.indexOf('some error message') >= 0, 'error output from match-input.exe is expected');
589-
assert(err && err.message && err.message.indexOf('match-input.exe') >=0, 'error from find does not match expeced. actual: ' + err.message);
589+
assert(err && err.message && err.message.indexOf('match-input.exe') >= 0, 'error from find does not match expeced. actual: ' + err.message);
590590
done();
591591
}
592592
})
@@ -634,6 +634,270 @@ describe('Toolrunner Tests', function () {
634634
});
635635
}
636636
})
637+
it('Exec pipe output to file and another tool, succeeds if both tools succeed', function (done) {
638+
this.timeout(20000);
639+
640+
var _testExecOptions = <trm.IExecOptions>{
641+
cwd: __dirname,
642+
env: {},
643+
silent: false,
644+
failOnStdErr: false,
645+
ignoreReturnCode: false,
646+
outStream: testutil.getNullStream(),
647+
errStream: testutil.getNullStream()
648+
};
649+
650+
const testFile = path.join(testutil.getTestTemp(), 'BothToolsSucceed.log');
651+
652+
if (os.platform() === 'win32') {
653+
var matchExe = tl.tool(compileMatchExe())
654+
.arg('0') // exit code
655+
.arg('line 2'); // match value
656+
var outputExe = tl.tool(compileOutputExe())
657+
.arg('0') // exit code
658+
.arg('line 1')
659+
.arg('line 2')
660+
.arg('line 3');
661+
outputExe.pipeExecOutputToTool(matchExe, testFile);
662+
663+
var output = '';
664+
outputExe.on('stdout', (data) => {
665+
output += data.toString();
666+
});
667+
668+
outputExe.exec(_testExecOptions)
669+
.then(function (code) {
670+
assert.equal(code, 0, 'return code of exec should be 0');
671+
assert(output && output.length > 0 && output.indexOf('line 2') >= 0, 'should have emitted stdout ' + output);
672+
assert(fs.existsSync(testFile), 'Log of first tool output is created when both tools succeed');
673+
const fileContents = fs.readFileSync(testFile);
674+
assert(fileContents.indexOf('line 2') >= 0, 'Log file of first tool should have stdout from first tool: ' + fileContents);
675+
done();
676+
})
677+
.fail(function (err) {
678+
done(err);
679+
});
680+
}
681+
else {
682+
var grep = tl.tool(tl.which('grep', true));
683+
grep.arg('node');
684+
685+
var ps = tl.tool(tl.which('ps', true));
686+
ps.arg('ax');
687+
ps.pipeExecOutputToTool(grep, testFile);
688+
689+
var output = '';
690+
ps.on('stdout', (data) => {
691+
output += data.toString();
692+
});
693+
694+
ps.exec(_testExecOptions)
695+
.then(function (code) {
696+
assert.equal(code, 0, 'return code of exec should be 0');
697+
assert(output && output.length > 0 && output.indexOf('node') >= 0, 'should have emitted stdout ' + output);
698+
assert(fs.existsSync(testFile), 'Log of first tool output is created when both tools succeed');
699+
const fileContents = fs.readFileSync(testFile);
700+
assert(fileContents.indexOf('PID') >= 0, 'Log of first tool should have stdout from first tool: ' + fileContents);
701+
done();
702+
})
703+
.fail(function (err) {
704+
done(err);
705+
});
706+
}
707+
})
708+
it('Exec pipe output to another tool, fails if first tool fails', function (done) {
709+
this.timeout(20000);
710+
711+
var _testExecOptions = <trm.IExecOptions>{
712+
cwd: __dirname,
713+
env: {},
714+
silent: false,
715+
failOnStdErr: false,
716+
ignoreReturnCode: false,
717+
outStream: testutil.getNullStream(),
718+
errStream: testutil.getNullStream()
719+
};
720+
721+
const testFile = path.join(testutil.getTestTemp(), 'FirstToolFails.log');
722+
723+
if (os.platform() === 'win32') {
724+
var matchExe = tl.tool(compileMatchExe())
725+
.arg('0') // exit code
726+
.arg('line 2'); // match value
727+
var outputExe = tl.tool(compileOutputExe())
728+
.arg('1') // exit code
729+
.arg('line 1')
730+
.arg('line 2')
731+
.arg('line 3');
732+
outputExe.pipeExecOutputToTool(matchExe, testFile);
733+
734+
var output = '';
735+
outputExe.on('stdout', (data) => {
736+
output += data.toString();
737+
});
738+
739+
var succeeded = false;
740+
outputExe.exec(_testExecOptions)
741+
.then(function () {
742+
succeeded = true;
743+
assert.fail('print-output.exe | findstr "line 2" was a bad command and it did not fail');
744+
})
745+
.fail(function (err) {
746+
if (succeeded) {
747+
done(err);
748+
}
749+
else {
750+
assert(err && err.message && err.message.indexOf('print-output.exe') >= 0, 'error from print-output.exe is not reported');
751+
assert(fs.existsSync(testFile), 'Log of first tool output is created when first tool fails');
752+
const fileContents = fs.readFileSync(testFile);
753+
assert(fileContents.indexOf('line 3') >= 0, 'Error from first tool should be written to log file: ' + fileContents);
754+
done();
755+
}
756+
})
757+
.fail(function (err) {
758+
done(err);
759+
});
760+
}
761+
else {
762+
var grep = tl.tool(tl.which('grep', true));
763+
grep.arg('ssh');
764+
765+
var ps = tl.tool(tl.which('ps', true));
766+
ps.arg('bad');
767+
ps.pipeExecOutputToTool(grep, testFile);
768+
769+
var output = '';
770+
ps.on('stdout', (data) => {
771+
output += data.toString();
772+
});
773+
774+
var succeeded = false;
775+
ps.exec(_testExecOptions)
776+
.then(function () {
777+
succeeded = true;
778+
assert.fail('ps bad | grep ssh was a bad command and it did not fail');
779+
})
780+
.fail(function (err) {
781+
if (succeeded) {
782+
done(err);
783+
}
784+
else {
785+
assert(err && err.message && err.message.indexOf('/bin/ps') >= 0, 'error from ps is not reported');
786+
assert(fs.existsSync(testFile), 'Log of first tool output is created when first tool fails');
787+
const fileContents = fs.readFileSync(testFile);
788+
assert(fileContents.indexOf('illegal option') >= 0 || fileContents.indexOf('unsupported option') >= 0,
789+
'error from first tool should be written to log file: ' + fileContents);
790+
done();
791+
}
792+
})
793+
.fail(function (err) {
794+
done(err);
795+
})
796+
}
797+
})
798+
it('Exec pipe output to another tool, fails if second tool fails', function (done) {
799+
this.timeout(20000);
800+
801+
var _testExecOptions = <trm.IExecOptions>{
802+
cwd: __dirname,
803+
env: {},
804+
silent: false,
805+
failOnStdErr: false,
806+
ignoreReturnCode: false,
807+
outStream: testutil.getNullStream(),
808+
errStream: testutil.getNullStream()
809+
};
810+
811+
const testFile = path.join(testutil.getTestTemp(), 'SecondToolFails.log');
812+
813+
if (os.platform() === 'win32') {
814+
var matchExe = tl.tool(compileMatchExe())
815+
.arg('1') // exit code
816+
.arg('line 2') // match value
817+
.arg('some error message'); // error
818+
var outputExe = tl.tool(compileOutputExe())
819+
.arg('0') // exit code
820+
.arg('line 1')
821+
.arg('line 2')
822+
.arg('line 3');
823+
outputExe.pipeExecOutputToTool(matchExe, testFile);
824+
825+
var output = '';
826+
outputExe.on('stdout', (data) => {
827+
output += data.toString();
828+
});
829+
830+
var errOut = '';
831+
outputExe.on('stderr', (data) => {
832+
errOut += data.toString();
833+
});
834+
835+
var succeeded = false;
836+
outputExe.exec(_testExecOptions)
837+
.then(function (code) {
838+
succeeded = true;
839+
assert.fail('print-output.exe 0 "line 1" "line 2" "line 3" | match-input.exe 1 "line 2" "some error message" was a bad command and it did not fail');
840+
})
841+
.fail(function (err) {
842+
if (succeeded) {
843+
done(err);
844+
}
845+
else {
846+
assert(errOut && errOut.length > 0 && errOut.indexOf('some error message') >= 0, 'error output from match-input.exe is expected');
847+
assert(err && err.message && err.message.indexOf('match-input.exe') >= 0, 'error from find does not match expeced. actual: ' + err.message);
848+
assert(fs.existsSync(testFile), 'Log of first tool output is created when second tool fails');
849+
const fileContents = fs.readFileSync(testFile);
850+
assert(fileContents.indexOf('some error message') < 0, 'error from second tool should not be in the log for first tool: ' + fileContents);
851+
done();
852+
}
853+
})
854+
.fail(function (err) {
855+
done(err);
856+
});
857+
}
858+
else {
859+
var grep = tl.tool(tl.which('grep', true));
860+
grep.arg('--?');
861+
862+
var ps = tl.tool(tl.which('ps', true));
863+
ps.arg('ax');
864+
ps.pipeExecOutputToTool(grep, testFile);
865+
866+
var output = '';
867+
ps.on('stdout', (data) => {
868+
output += data.toString();
869+
});
870+
871+
var errOut = '';
872+
ps.on('stderr', (data) => {
873+
errOut += data.toString();
874+
})
875+
876+
var succeeded = false;
877+
ps.exec(_testExecOptions)
878+
.then(function (code) {
879+
succeeded = true;
880+
assert.fail('ps ax | grep --? was a bad command and it did not fail');
881+
})
882+
.fail(function (err) {
883+
if (succeeded) {
884+
done(err);
885+
}
886+
else {
887+
assert(errOut && errOut.length > 0 && errOut.indexOf('grep: unrecognized option') >= 0, 'error output from ps command is expected');
888+
// grep is /bin/grep on Linux and /usr/bin/grep on OSX
889+
assert(err && err.message && err.message.match(/\/[usr\/]?bin\/grep/), 'error from grep is not reported. actual: ' + err.message);
890+
assert(fs.existsSync(testFile), 'Log of first tool output is created when second tool fails');
891+
const fileContents = fs.readFileSync(testFile);
892+
assert(fileContents.indexOf('unrecognized option') < 0, 'error from second tool should not be in the first tool log file: ' + fileContents);
893+
done();
894+
}
895+
})
896+
.fail(function (err) {
897+
done(err);
898+
});
899+
}
900+
})
637901
it('handles single args', function (done) {
638902
this.timeout(10000);
639903

@@ -653,7 +917,7 @@ describe('Toolrunner Tests', function () {
653917
assert.equal((node as any).args.length, 5, 'should have 5 args');
654918
assert.equal((node as any).args.toString(), 'one,two,three,four,five', 'should be one,two,three,four,five');
655919
done();
656-
})
920+
})
657921
it('handles padded spaces', function (done) {
658922
this.timeout(10000);
659923

0 commit comments

Comments
 (0)