/* * Copyright (C) 2012 Open Source Robotics Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ // The following is needed to enable the GetMemInfo function for OSX #ifdef __MACH__ # include #endif // __MACH__ #include #include #include "gazebo/common/Console.hh" #include "gazebo/common/Time.hh" #include "gazebo/gazebo.hh" #include "gazebo/gui/GuiIface.hh" #include "gazebo/gui/QTestFixture.hh" #include "gazebo/physics/PhysicsIface.hh" #include "gazebo/rendering/RenderingIface.hh" #include "gazebo/util/LogRecord.hh" ///////////////////////////////////////////////// QTestFixture::QTestFixture() : server(NULL), serverThread(NULL), resMaxPercentChange(0), shareMaxPercentChange(0), residentStart(0), shareStart(0) { } ///////////////////////////////////////////////// void QTestFixture::initTestCase() { // Verbose mode gazebo::common::Console::SetQuiet(false); // Initialize the informational logger. This will log warnings, and // errors. gzLogInit("qtest-", "test.log"); // Initialize the data logger. This will log state information. gazebo::util::LogRecord::Instance()->Init("test"); // Add local search paths gazebo::common::SystemPaths::Instance()->AddGazeboPaths(PROJECT_SOURCE_PATH); std::string path = PROJECT_SOURCE_PATH; path += "/worlds"; gazebo::common::SystemPaths::Instance()->AddGazeboPaths(path); path = TEST_PATH; gazebo::common::SystemPaths::Instance()->AddGazeboPaths(path); } ///////////////////////////////////////////////// void QTestFixture::init() { this->resMaxPercentChange = 3.0; this->shareMaxPercentChange = 1.0; this->serverThread = NULL; this->GetMemInfo(this->residentStart, this->shareStart); gazebo::rendering::load(); if (!gazebo::gui::register_metatypes()) gzerr << "Unable to register Qt metatypes" << std::endl; } ///////////////////////////////////////////////// void QTestFixture::Load(const std::string &_worldFilename, bool _paused, bool _serverScene, bool _clientScene) { #if (OGRE_VERSION >= ((1 << 16) | (9 << 8) | 0)) && defined(__APPLE__) this->resMaxPercentChange *= 2.0; #endif // Create, load, and run the server in its own thread this->serverThread = new boost::thread( boost::bind(&QTestFixture::RunServer, this, _worldFilename, _paused, _serverScene)); // Wait for the server to come up // Use a 60 second timeout. int waitCount = 0, maxWaitCount = 6000; while ((!this->server || !this->server->GetInitialized()) && ++waitCount < maxWaitCount) gazebo::common::Time::MSleep(10); if (!this->server || !this->server->GetInitialized() || waitCount >= maxWaitCount) { gzerr << "Unable to initialize server. Potential reasons:" << std::endl; gzerr << "\tIncorrect world name?" << std::endl; gzerr << "\tConnection problem downloading models" << std::endl; return; } if (_clientScene) { gazebo::rendering::create_scene( gazebo::physics::get_world()->GetName(), true); } } ///////////////////////////////////////////////// void QTestFixture::RunServer(const std::string &_worldFilename, bool _paused, bool _createScene) { this->server = new gazebo::Server(); this->server->PreLoad(); this->server->LoadFile(_worldFilename); this->SetPause(_paused); if (_createScene) gazebo::rendering::create_scene( gazebo::physics::get_world()->GetName(), false); this->server->Run(); delete this->server; this->server = NULL; } ///////////////////////////////////////////////// void QTestFixture::SetPause(bool _pause) { gazebo::physics::pause_worlds(_pause); } ///////////////////////////////////////////////// void QTestFixture::ProcessEventsAndDraw(QMainWindow *_mainWindow, const unsigned int _repeat, const unsigned int _ms) { for (size_t i = 0; i < _repeat; ++i) { gazebo::common::Time::MSleep(_ms); QCoreApplication::processEvents(); if (_mainWindow) _mainWindow->repaint(); } } ///////////////////////////////////////////////// void QTestFixture::cleanup() { if (this->server) { this->server->Stop(); if (this->serverThread) { this->serverThread->join(); } } delete this->serverThread; this->serverThread = NULL; gazebo::rendering::fini(); double residentEnd, shareEnd; this->GetMemInfo(residentEnd, shareEnd); // Calculate the percent change from the initial resident and shared memory double resPercentChange = (residentEnd - residentStart) / residentStart; double sharePercentChange = (shareEnd - shareStart) / shareStart; std::cout << "SharePercentChange[" << sharePercentChange << "] " << "ShareMaxPercentChange[" << this->shareMaxPercentChange << "]\n"; std::cout << "ResPercentChange[" << resPercentChange << "]" << "ResMaxPercentChange[" << this->resMaxPercentChange << "]\n"; // Make sure the percent change values are reasonable. QVERIFY(resPercentChange < this->resMaxPercentChange); QVERIFY(sharePercentChange < this->shareMaxPercentChange); } ///////////////////////////////////////////////// void QTestFixture::cleanupTestCase() { } ///////////////////////////////////////////////// void QTestFixture::GetMemInfo(double &_resident, double &_share) { #ifdef __linux__ int totalSize, residentPages, sharePages; totalSize = residentPages = sharePages = 0; std::ifstream buffer("/proc/self/statm"); buffer >> totalSize >> residentPages >> sharePages; buffer.close(); // in case x86-64 is configured to use 2MB pages int64_t pageSizeKb = sysconf(_SC_PAGE_SIZE) / 1024; _resident = residentPages * pageSizeKb; _share = sharePages * pageSizeKb; #elif __MACH__ // /proc is only available on Linux // for OSX, use task_info to get resident and virtual memory struct task_basic_info t_info; mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; if (KERN_SUCCESS != task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count)) { gzerr << "failure calling task_info\n"; return; } _resident = static_cast(t_info.resident_size/1024); _share = static_cast(t_info.virtual_size/1024); #else gzerr << "Unsupported architecture\n"; return; #endif }