/* This file is part of MAUS: http://micewww.pp.rl.ac.uk:8080/projects/maus * * MAUS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * MAUS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with MAUS. If not, see . * */ #include #include "gtest/gtest.h" #include "json/json.h" #include "src/common_cpp/Utils/Exception.hh" #include "src/common_cpp/Converter/ConverterFactory.hh" #include "src/common_cpp/Utils/PyObjectWrapper.hh" namespace MAUS { // Stupid C++, why can't I do EXPECT_EQ(PyErr_Occurred(), NULL)? PyObject* null = NULL; // force the compiler to build conversions from all supported types... // This does nothing, just checks we can compile the code TEST(PyObjectWrapperTest, TestUnwrapNullObject) { PyObject* args = NULL; EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_EQ(PyErr_Occurred(), null); } TEST(PyObjectWrapperTest, TestUnwrapBadObject) { PyObject* args = PyLong_FromLong(0); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); EXPECT_THROW(PyObjectWrapper::unwrap(args), Exception); Py_DECREF(args); EXPECT_EQ(PyErr_Occurred(), null); } template void test_unwrap(PyObject* py_data) { // Unwrap as data TEMP* data_out = PyObjectWrapper::unwrap(py_data); EXPECT_EQ(data_out->GetSpill()->GetRunNumber(), 99); delete data_out; // Unwrap as data std::string* str_out = PyObjectWrapper::unwrap(py_data); Json::Value* json_tmp = ConverterFactory().convert(str_out); EXPECT_EQ((*json_tmp)["run_number"], 99); delete json_tmp; delete str_out; // Unwrap as Json Json::Value* json_out = PyObjectWrapper::unwrap(py_data); EXPECT_EQ((*json_out)["run_number"], 99); delete json_out; // Unwrap as PyObject PyObject* py_out = PyObjectWrapper::unwrap(py_data); EXPECT_EQ(py_out->ob_refcnt, 1); // py_run_number is a borrowed ref (so no decref) PyObject* py_run_number = PyDict_GetItemString(py_out, "run_number"); int run_number = PyInt_AsLong(py_run_number); EXPECT_EQ(run_number, 99); Py_DECREF(py_out); EXPECT_EQ(PyErr_Occurred(), null); } TEST(PyObjectWrapperTest, TestWrapUnwrapDataObject) { std::string test = std::string("{\"daq_event_type\":\"\",\"errors\":{},")+ std::string("\"maus_event_type\":\"Spill\",\"run_number\":99,")+ std::string("\"spill_number\":666}"); std::cerr << "Data " << std::flush; Data* data_in = ConverterFactory().convert(&test); PyObject* py_data = PyObjectWrapper::wrap(data_in); EXPECT_EQ(py_data->ob_refcnt, 1); test_unwrap(py_data); EXPECT_EQ(py_data->ob_refcnt, 1); Py_DECREF(py_data); std::cerr << "String " << std::flush; PyObject* py_str = PyObjectWrapper::wrap(new std::string(test)); EXPECT_EQ(py_str->ob_refcnt, 1); test_unwrap(py_str); Py_DECREF(py_str); std::cerr << "Json " << std::flush; Json::Value* json_value = ConverterFactory().convert (new std::string(test)); PyObject* py_json = PyObjectWrapper::wrap(json_value); EXPECT_EQ(py_json->ob_refcnt, 1); test_unwrap(py_json); Py_DECREF(py_json); std::cerr << "PyObject" << std::endl; PyObject* py_dict = ConverterFactory().convert (new std::string(test)); EXPECT_EQ(py_dict->ob_refcnt, 1); PyObject* py_run_number = PyDict_GetItemString(py_dict, "run_number"); int run_number = PyInt_AsLong(py_run_number); EXPECT_EQ(run_number, 99); PyObject* py_py_dict = PyObjectWrapper::wrap(py_dict); EXPECT_EQ(py_py_dict->ob_refcnt, 1); EXPECT_EQ(py_py_dict, py_dict); // it was a null op test_unwrap(py_dict); Py_DECREF(py_dict); EXPECT_EQ(PyErr_Occurred(), null); } TEST(PyObjectWrapperTest, TestDeleteJsonCppPyCapsule) { EXPECT_THROW(PyObjectWrapper::delete_jsoncpp_pycapsule(NULL), Exception); PyObject* py_int = PyLong_FromLong(0); EXPECT_THROW(PyObjectWrapper::delete_jsoncpp_pycapsule(py_int), Exception); Py_DECREF(py_int); Json::Value* json = new Json::Value(); void* void_json = static_cast(json); PyObject *py_no_name = PyCapsule_New(void_json, "", NULL); EXPECT_THROW(PyObjectWrapper::delete_jsoncpp_pycapsule(py_no_name), Exception); Py_DECREF(py_no_name); PyObject* py_okay = PyCapsule_New(void_json, "JsonCpp", NULL); PyObjectWrapper::delete_jsoncpp_pycapsule(py_okay); // and this deletes json Py_DECREF(py_okay); EXPECT_EQ(PyErr_Occurred(), null); } } // namespace MAUS