-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtest.cc
109 lines (100 loc) · 3.07 KB
/
test.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <iostream>
#include <string>
#include <vector>
#include "test.hh"
#ifdef _MSC_VER
#define popen _popen
#define pclose _pclose
#endif
/////////////////////////////////////////////////////////////////////////////////////////////////////
//test_t
//arguments:
//'cmd' NCO executable full path
//'arg' arguments for NCO executable
//'expected': expected output as an array of strings (each element is 1 line of output)
/////////////////////////////////////////////////////////////////////////////////////////////////////
test_t::test_t(std::string cmd, const std::string &arg, const char **expected, int verbose)
{
std::vector<std::string> out;
cmd += " ";
cmd += arg;
out = exec(cmd);
std::cout << "TESTING " << cmd << "... ";
if (compare(out, expected) > 0) //returns number of lines of output that differ
{
std::cout << "FAILURE" << std::endl;
}
else
{
std::cout << "PASSED" << std::endl;
}
if (!verbose) return;
std::cout << "OUTPUT" << std::endl;
for (int idx = 0; idx < out.size(); idx++)
{
std::cout << out.at(idx);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//exec()
//uses the popen() function, that creates a bidirectional pipe,
//forking, and invoking the shell;
//popen() returns a pointer to a stream that can be used to either read from or write to the pipe
//'cmd' NCO executable full path concatenated with argumants (including data file full path)
//function returns the output of 'cmd' to stdout as a vector of strings
/////////////////////////////////////////////////////////////////////////////////////////////////////
std::vector<std::string> test_t::exec(const std::string &cmd)
{
std::vector<std::string> vec;
const int PATH_MAX = 1024;
char buf[PATH_MAX];
FILE* fp = popen(cmd.c_str(), "r");
if (fp == NULL)
{
assert(0);
}
while (fgets(buf, PATH_MAX, fp) != NULL)
{
std::string str(buf);
vec.push_back(str);
}
pclose(fp);
return vec;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
//compare()
//compares an expected vector of strings with another vector of strings (output)
//returns number of lines of output that differ
/////////////////////////////////////////////////////////////////////////////////////////////////////
int test_t::compare(const std::vector<std::string> &out, const char **exps)
{
int nbr = 0;
std::vector<std::string> exp;
while (*exps != 0)
{
std::string str(*exps);
exp.push_back(str);
exps++;
}
assert(exp.size() == out.size());
for (int idx = 0; idx < out.size(); idx++)
{
std::string outs = out.at(idx);
std::string exps = exp.at(idx);
//remove '\n' from output (last character)
assert(outs.at(outs.size() - 1) == '\n');
outs = outs.substr(0, outs.size() - 1);
if (outs.compare(exps) != 0)
{
std::cout << "EXPECTED ";
std::cout << exps << "\n";
std::cout << "RESULT ";
std::cout << outs << "\n";;
nbr++;
}
}
return nbr;
}