16 #ifndef IMPALA_UDF_TEST_HARNESS_H
17 #define IMPALA_UDF_TEST_HARNESS_H
21 #include <boost/function.hpp>
22 #include <boost/scoped_ptr.hpp>
27 namespace impala_udf {
36 const std::vector<FunctionContext::TypeDesc>& arg_types);
62 template<
typename RET>
65 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
67 std::vector<FunctionContext::TypeDesc> arg_types;
68 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
71 RET ret = fn(context.get());
73 return Validate(context.get(), expected, ret);
76 template<
typename RET,
typename A1>
78 const A1& a1,
const RET& expected,
UdfPrepare init_fn = NULL,
80 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
82 std::vector<FunctionContext::TypeDesc> arg_types;
83 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
86 RET ret = fn(context.get(), a1);
88 return Validate(context.get(), expected, ret);
91 template<
typename RET,
typename A1>
93 const std::vector<A1>& a1,
const RET& expected,
UdfPrepare init_fn = NULL,
95 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
97 std::vector<FunctionContext::TypeDesc> arg_types;
98 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
100 if (!
RunPrepareFn(init_fn, context.get()))
return false;
101 RET ret = fn(context.get(), a1.size(), &a1[0]);
103 return Validate(context.get(), expected, ret);
106 template<
typename RET,
typename A1,
typename A2>
109 const A1& a1,
const A2& a2,
const RET& expected,
UdfPrepare init_fn = NULL,
111 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
113 std::vector<FunctionContext::TypeDesc> arg_types;
114 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
116 if (!
RunPrepareFn(init_fn, context.get()))
return false;
117 RET ret = fn(context.get(), a1, a2);
119 return Validate(context.get(), expected, ret);
122 template<
typename RET,
typename A1,
typename A2>
125 const A1& a1,
const std::vector<A2>& a2,
const RET& expected,
127 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
129 std::vector<FunctionContext::TypeDesc> arg_types;
130 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
132 if (!
RunPrepareFn(init_fn, context.get()))
return false;
133 RET ret = fn(context.get(), a1, a2.size(), &a2[0]);
135 return Validate(context.get(), expected, ret);
138 template<
typename RET,
typename A1,
typename A2,
typename A3>
140 boost::function<RET(
FunctionContext*,
const A1&,
const A2&,
const A3&)> fn,
141 const A1& a1,
const A2& a2,
const A3& a3,
const RET& expected,
143 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
145 std::vector<FunctionContext::TypeDesc> arg_types;
146 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
148 if (!
RunPrepareFn(init_fn, context.get()))
return false;
149 RET ret = fn(context.get(), a1, a2, a3);
151 return Validate(context.get(), expected, ret);
154 template<
typename RET,
typename A1,
typename A2,
typename A3>
156 boost::function<RET(
FunctionContext*,
const A1&,
const A2&,
int,
const A3*)> fn,
157 const A1& a1,
const A2& a2,
const std::vector<A3>& a3,
const RET& expected,
159 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
161 std::vector<FunctionContext::TypeDesc> arg_types;
162 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
164 if (!
RunPrepareFn(init_fn, context.get()))
return false;
165 RET ret = fn(context.get(), a1, a2, a3.size(), &a3[0]);
167 return Validate(context.get(), expected, ret);
170 template<
typename RET,
typename A1,
typename A2,
typename A3,
typename A4>
174 const A1& a1,
const A2& a2,
const A3& a3,
const A4& a4,
const RET& expected,
176 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
178 std::vector<FunctionContext::TypeDesc> arg_types;
179 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
181 if (!
RunPrepareFn(init_fn, context.get()))
return false;
182 RET ret = fn(context.get(), a1, a2, a3, a4);
184 return Validate(context.get(), expected, ret);
187 template<
typename RET,
typename A1,
typename A2,
typename A3,
typename A4>
191 const A1& a1,
const A2& a2,
const A3& a3,
const std::vector<A4>& a4,
193 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
195 std::vector<FunctionContext::TypeDesc> arg_types;
196 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
198 if (!
RunPrepareFn(init_fn, context.get()))
return false;
199 RET ret = fn(context.get(), a1, a2, a3, a4.size(), &a4[0]);
201 return Validate(context.get(), expected, ret);
204 template<
typename RET,
typename A1,
typename A2,
typename A3,
typename A4,
208 const A4&,
const A5&)> fn,
209 const A1& a1,
const A2& a2,
const A3& a3,
const A4& a4,
const A5& a5,
211 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
213 std::vector<FunctionContext::TypeDesc> arg_types;
214 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
216 if (!
RunPrepareFn(init_fn, context.get()))
return false;
217 RET ret = fn(context.get(), a1, a2, a3, a4, a5);
219 return Validate(context.get(), expected, ret);
222 template<
typename RET,
typename A1,
typename A2,
typename A3,
typename A4,
223 typename A5,
typename A6>
226 const A4&,
const A5&,
const A6&)> fn,
227 const A1& a1,
const A2& a2,
const A3& a3,
const A4& a4,
const A5& a5,
228 const A6& a6,
const RET& expected,
UdfPrepare init_fn = NULL,
230 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
232 std::vector<FunctionContext::TypeDesc> arg_types;
233 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
235 if (!
RunPrepareFn(init_fn, context.get()))
return false;
236 RET ret = fn(context.get(), a1, a2, a3, a4, a5, a6);
238 return Validate(context.get(), expected, ret);
241 template<
typename RET,
typename A1,
typename A2,
typename A3,
typename A4,
242 typename A5,
typename A6,
typename A7>
245 const A4&,
const A5&,
const A6&,
const A7&)> fn,
246 const A1& a1,
const A2& a2,
const A3& a3,
const A4& a4,
const A5& a5,
247 const A6& a6,
const A7& a7,
const RET& expected,
UdfPrepare init_fn = NULL,
249 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
251 std::vector<FunctionContext::TypeDesc> arg_types;
252 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
254 if (!
RunPrepareFn(init_fn, context.get()))
return false;
255 RET ret = fn(context.get(), a1, a2, a3, a4, a5, a6, a7);
257 return Validate(context.get(), expected, ret);
260 template<
typename RET,
typename A1,
typename A2,
typename A3,
typename A4,
261 typename A5,
typename A6,
typename A7,
typename A8>
264 const A4&,
const A5&,
const A6&,
const A7&)> fn,
265 const A1& a1,
const A2& a2,
const A3& a3,
const A4& a4,
const A5& a5,
266 const A6& a6,
const A7& a7,
const A8& a8,
const RET& expected,
268 const std::vector<AnyVal*>& constant_args = std::vector<AnyVal*>()) {
270 std::vector<FunctionContext::TypeDesc> arg_types;
271 boost::scoped_ptr<FunctionContext> context(
CreateTestContext(return_type, arg_types));
273 if (!
RunPrepareFn(init_fn, context.get()))
return false;
274 RET ret = fn(context.get(), a1, a2, a3, a4, a5, a6, a7, a8);
276 return Validate(context.get(), expected, ret);
282 std::cerr <<
"Udf Failed: " << context->
error_msg() << std::endl;
288 template<
typename RET>
291 if (!context->
has_error() && actual != expected) {
292 std::cerr <<
"UDF did not return the correct result:" << std::endl
293 <<
" Expected: " <<
DebugString(expected) << std::endl
294 <<
" Actual: " <<
DebugString(actual) << std::endl;
303 if (prepare_fn != NULL) {
312 if (close_fn != NULL) {
void(* UdfClose)(FunctionContext *context, FunctionContext::FunctionStateScope scope)
static void RunCloseFn(UdfClose close_fn, FunctionContext *context)
static bool Validate(FunctionContext *context, const RET &expected, const RET &actual)
Utility class to help test UDFs.
static FunctionContext * CreateTestContext(const FunctionContext::TypeDesc &return_type, const std::vector< FunctionContext::TypeDesc > &arg_types)
void(* UdfPrepare)(FunctionContext *context, FunctionContext::FunctionStateScope scope)
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, const A2 &)> fn, const A1 &a1, const A2 &a2, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
bool has_error() const
Returns true if there's been an error set.
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, const A2 &, int, const A3 *)> fn, const A1 &a1, const A2 &a2, const std::vector< A3 > &a3, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool ValidateUdf(boost::function< RET(FunctionContext *)> fn, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static void SetConstantArgs(FunctionContext *context, const std::vector< AnyVal * > &constant_args)
The AnyVal* values are owned by the caller.
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &)> fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool ValidateUdf(boost::function< RET(FunctionContext *, int, const A1 *)> fn, const std::vector< A1 > &a1, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &)> fn, const A1 &a1, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &)> fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const A8 &a8, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
std::string DebugString(const T &val)
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &)> fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool RunPrepareFn(UdfPrepare prepare_fn, FunctionContext *context)
const char * error_msg() const
Returns the current error message. Returns NULL if there is no error.
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, const A2 &, const A3 &, const A4 &)> fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, const A2 &, const A3 &)> fn, const A1 &a1, const A2 &a2, const A3 &a3, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, int, const A2 *)> fn, const A1 &a1, const std::vector< A2 > &a2, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, const A2 &, const A3 &, int, const A4 *)> fn, const A1 &a1, const A2 &a2, const A3 &a3, const std::vector< A4 > &a4, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool ValidateUdf(boost::function< RET(FunctionContext *, const A1 &, const A2 &, const A3 &, const A4 &, const A5 &, const A6 &, const A7 &)> fn, const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5, const A6 &a6, const A7 &a7, const RET &expected, UdfPrepare init_fn=NULL, UdfClose close_fn=NULL, const std::vector< AnyVal * > &constant_args=std::vector< AnyVal * >())
static bool ValidateError(FunctionContext *context)
static void CloseContext(FunctionContext *context)