Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow using plugin file names and environment variables compatible with Garden and later #2275

Merged
merged 7 commits into from
Jan 12, 2024
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 15 additions & 3 deletions include/gz/sim/Util.hh
Original file line number Diff line number Diff line change
Expand Up @@ -287,19 +287,31 @@ namespace ignition
std::optional<math::Vector3d> IGNITION_GAZEBO_VISIBLE sphericalCoordinates(
Entity _entity, const EntityComponentManager &_ecm);

/// \brief Environment variable holding resource paths.
/// \brief Environment variable holding resource paths. Prefer using
/// GZ_SIM_RESOURCE_PATH for compatibility with newer versions of Gazebo.
const std::string kResourcePathEnv{"IGN_GAZEBO_RESOURCE_PATH"};
/// \brief Environment variable holding resource paths.
const std::string kResourcePathEnvGzSim{"GZ_SIM_RESOURCE_PATH"};
azeey marked this conversation as resolved.
Show resolved Hide resolved

/// \brief Environment variable used by SDFormat to find URIs inside
/// `<include>`
const std::string kSdfPathEnv{"SDF_PATH"};

/// \brief Environment variable holding server config paths.
/// \brief Environment variable holding server config paths. Prefer using
/// GZ_SIM_SERVER_CONFIG_PATH for compatibility with newer versions of
/// Gazebo.
const std::string kServerConfigPathEnv{"IGN_GAZEBO_SERVER_CONFIG_PATH"};
/// \brief Environment variable holding server config paths.
const std::string kServerConfigPathEnvGzSim{"GZ_SIM_SERVER_CONFIG_PATH"};

/// \brief Environment variable holding paths to custom rendering engine
/// plugins.
/// plugins. Prefer using GZ_SIM_RENDER_ENGINE_PATH for compatibility with
/// newer versions of Gazebo
const std::string kRenderPluginPathEnv{"IGN_GAZEBO_RENDER_ENGINE_PATH"};
/// \brief Environment variable holding paths to custom rendering engine
/// plugins.
const std::string kRenderPluginPathEnvGzSim{"GZ_SIM_RENDER_ENGINE_PATH"};

}
}
}
Expand Down
5 changes: 2 additions & 3 deletions src/Conversions.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1713,9 +1713,8 @@ msgs::ParticleEmitter ignition::gazebo::convert(const sdf::ParticleEmitter &_in)
{
std::string path = asFullPath(_in.ColorRangeImage(), _in.FilePath());

common::SystemPaths systemPaths;
systemPaths.SetFilePathEnv(kResourcePathEnv);
std::string absolutePath = systemPaths.FindFile(path);
const std::string absolutePath =
common::SystemPaths::LocateLocalFile(path, gazebo::resourcePaths());

if (!absolutePath.empty())
out.mutable_color_range_image()->set_data(absolutePath);
Expand Down
54 changes: 35 additions & 19 deletions src/ServerConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -922,30 +922,26 @@ ignition::gazebo::parsePluginsFromString(const std::string &_str)
std::list<ServerConfig::PluginInfo>
ignition::gazebo::loadPluginInfo(bool _isPlayback)
{
std::list<ServerConfig::PluginInfo> ret;

// 1. Check contents of environment variable
std::string envConfig;
bool configSet = common::env(kServerConfigPathEnv,
envConfig,
true);

if (configSet)
auto parsePlugins = [](const std::string &_serverConfigPathEnv,
const std::string &_envConfig)
{
if (common::exists(envConfig))
std::list<ServerConfig::PluginInfo> ret;
if (common::exists(_envConfig))
{
// Parse configuration stored in environment variable
ret = gz::sim::parsePluginsFromFile(envConfig);
ret = gz::sim::parsePluginsFromFile(_envConfig);
if (ret.empty())
{
// This may be desired behavior, but warn just in case.
// Some users may want to defer all loading until later
// during runtime.
ignwarn << kServerConfigPathEnv
<< " set but no plugins found\n";
ignwarn << _serverConfigPathEnv
<< " set but no plugins found\n";
}
igndbg << "Loaded (" << ret.size() << ") plugins from file " <<
"[" << envConfig << "]\n";
"[" << _envConfig << "]\n";

return ret;
}
Expand All @@ -954,11 +950,31 @@ ignition::gazebo::loadPluginInfo(bool _isPlayback)
// This may be desired behavior, but warn just in case.
// Some users may want to defer all loading until late
// during runtime.
ignwarn << kServerConfigPathEnv
<< " set but no file found,"
<< " no plugins loaded\n";
ignwarn << _serverConfigPathEnv
<< " set but no file found,"
<< " no plugins loaded\n";
return ret;
}
};

{
std::string envConfig;
bool configSet = common::env(kServerConfigPathEnv, envConfig, true);
if (configSet)
{
return parsePlugins(kServerConfigPathEnv, envConfig);
}
}

// Process the gz-sim environment variable the same way. If the IGN variable
// is set, it will have precedence.
{
std::string envConfig;
bool configSet = common::env(kServerConfigPathEnvGzSim, envConfig, true);
if (configSet)
{
return parsePlugins(kServerConfigPathEnvGzSim, envConfig);
}
}

std::string configFilename;
Expand Down Expand Up @@ -989,7 +1005,7 @@ ignition::gazebo::loadPluginInfo(bool _isPlayback)
{
ignerr << "Failed to create directory [" << defaultConfigDir
<< "]." << std::endl;
return ret;
return {};
}

if (!common::exists(installedConfig))
Expand All @@ -998,14 +1014,14 @@ ignition::gazebo::loadPluginInfo(bool _isPlayback)
<< "] to default config [" << defaultConfig << "]."
<< "(file " << installedConfig << " doesn't exist)"
<< std::endl;
return ret;
return {};
}
else if (!common::copyFile(installedConfig, defaultConfig))
{
ignerr << "Failed to copy installed config [" << installedConfig
<< "] to default config [" << defaultConfig << "]."
<< std::endl;
return ret;
return {};
}
else
{
Expand All @@ -1015,7 +1031,7 @@ ignition::gazebo::loadPluginInfo(bool _isPlayback)
}
}

ret = gz::sim::parsePluginsFromFile(defaultConfig);
const auto ret = gz::sim::parsePluginsFromFile(defaultConfig);

if (ret.empty())
{
Expand Down
35 changes: 28 additions & 7 deletions src/ServerConfig_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -198,14 +198,8 @@ TEST(LoadPluginInfo, FromEmptyEnv)
EXPECT_TRUE(common::unsetenv(kServerConfigPathEnv));
}

//////////////////////////////////////////////////
TEST(LoadPluginInfo, FromValidEnv)
void testFromValidEnvPlugins()
{
auto validPath = common::joinPaths(PROJECT_SOURCE_PATH,
"test", "worlds", "server_valid2.config");

ASSERT_TRUE(common::setenv(kServerConfigPathEnv, validPath));

auto plugins = loadPluginInfo();
ASSERT_EQ(2u, plugins.size());

Expand All @@ -226,9 +220,36 @@ TEST(LoadPluginInfo, FromValidEnv)
EXPECT_EQ("gz::sim::TestModelSystem", plugin->Name());
EXPECT_EQ("gz::sim::TestModelSystem", plugin->Plugin().Name());

}
//////////////////////////////////////////////////
TEST(LoadPluginInfo, FromValidEnv)
{
auto validPath = common::joinPaths(PROJECT_SOURCE_PATH,
"test", "worlds", "server_valid2.config");

ASSERT_TRUE(common::setenv(kServerConfigPathEnv, validPath));

SCOPED_TRACE("FromValidEnv");
testFromValidEnvPlugins();

EXPECT_TRUE(common::unsetenv(kServerConfigPathEnv));
}

//////////////////////////////////////////////////
TEST(LoadPluginInfo, FromValidEnvGzSimCompatibility)
{
auto validPath = common::joinPaths(PROJECT_SOURCE_PATH,
"test", "worlds", "server_valid2.config");

ASSERT_TRUE(common::unsetenv(kServerConfigPathEnv));
ASSERT_TRUE(common::setenv(kServerConfigPathEnvGzSim, validPath));

SCOPED_TRACE("FromValidEnvGzSimCompatibility");
testFromValidEnvPlugins();

EXPECT_TRUE(common::unsetenv(kServerConfigPathEnvGzSim));
}

//////////////////////////////////////////////////
TEST(ServerConfig, GenerateRecordPlugin)
{
Expand Down
6 changes: 3 additions & 3 deletions src/ServerPrivate.hh
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ namespace ignition
/// string and return value of false will be used if the resource could
/// not be found.
///
/// Fuel will be checked and then the GZ_GAZEBO_RESOURCE_PATH environment
/// variable paths. This service will not check for files relative to
/// working directory of the Gazebo server.
/// Fuel will be checked and then paths from IGN_GAZEBO_RESOURCE_PATH and
/// GZ_SIM_RESOURCE_PATH environment variables. This service will not
/// check for files relative to working directory of the Gazebo server.
///
/// \param[in] _req Request filled with a resource URI to resolve.
/// Example values could be:
Expand Down
42 changes: 36 additions & 6 deletions src/Server_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -912,13 +912,12 @@ TEST_P(ServerFixture, Seed)
}

/////////////////////////////////////////////////
TEST_P(ServerFixture, IGN_UTILS_TEST_DISABLED_ON_WIN32(ResourcePath))
void testResourcePaths(const std::string &_envVariable)
{
common::setenv("IGN_GAZEBO_RESOURCE_PATH",
common::setenv(_envVariable,
(common::joinPaths(PROJECT_SOURCE_PATH, "test", "worlds:") +
common::joinPaths(PROJECT_SOURCE_PATH,
"test", "worlds", "models")).c_str());

ServerConfig serverConfig;
serverConfig.SetSdfFile("resource_paths.sdf");
gz::sim::Server server(serverConfig);
Expand Down Expand Up @@ -998,16 +997,31 @@ TEST_P(ServerFixture, IGN_UTILS_TEST_DISABLED_ON_WIN32(ResourcePath))
EXPECT_TRUE(server.HasEntity("scheme_resource_uri"));
EXPECT_TRUE(server.HasEntity("the_link"));
EXPECT_TRUE(server.HasEntity("the_visual"));
common::unsetenv(_envVariable);
}

/////////////////////////////////////////////////
TEST_P(ServerFixture, GetResourcePaths)
TEST_P(ServerFixture, ResourcePath)
{
common::setenv("IGN_GAZEBO_RESOURCE_PATH",
SCOPED_TRACE("ResourcePaths");
testResourcePaths("IGN_GAZEBO_RESOURCE_PATH");
}

/////////////////////////////////////////////////
TEST_P(ServerFixture, ResourcePathGzSimCompatibility)
{
common::unsetenv("IGN_GAZEBO_RESOURCE_PATH");
SCOPED_TRACE("ResourcePathGzSimCompatibility");
testResourcePaths("GZ_SIM_RESOURCE_PATH");
}

/////////////////////////////////////////////////
void testGetResourcePaths(const std::string &_envVariable)
{
common::setenv(_envVariable,
std::string("/tmp/some/path") +
common::SystemPaths::Delimiter() +
std::string("/home/user/another_path"));

ServerConfig serverConfig;
gz::sim::Server server(serverConfig);

Expand All @@ -1030,6 +1044,22 @@ TEST_P(ServerFixture, GetResourcePaths)
EXPECT_EQ(2, res.data_size());
EXPECT_EQ("/tmp/some/path", res.data(0));
EXPECT_EQ("/home/user/another_path", res.data(1));
common::unsetenv(_envVariable);
}

/////////////////////////////////////////////////
TEST_P(ServerFixture, GetResourcePaths)
{
SCOPED_TRACE("GetResourcePaths");
testGetResourcePaths("IGN_GAZEBO_RESOURCE_PATH");
}

/////////////////////////////////////////////////
TEST_P(ServerFixture, GetResourcePathsGzSimCompatibility)
{
common::unsetenv("IGN_GAZEBO_RESOURCE_PATH");
SCOPED_TRACE("GetResourcePathsGzSimCompatibility");
testGetResourcePaths("GZ_SIM_RESOURCE_PATH");
}

/////////////////////////////////////////////////
Expand Down
23 changes: 21 additions & 2 deletions src/SystemLoader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ class ignition::gazebo::SystemLoaderPrivate
gz::common::SystemPaths systemPaths;
systemPaths.SetPluginPathEnv(pluginPathEnv);

// Also add GZ_SYSTEM_SIM_PLUGIN_PATH for compatibility with Garden and
// later.
for (const auto &path :
common::SystemPaths::PathsFromEnv(this->pluginPathEnvGzSim))
{
systemPaths.AddPluginPaths(path);
}

for (const auto &path : this->systemPluginPaths)
systemPaths.AddPluginPaths(path);

Expand All @@ -62,14 +70,22 @@ class ignition::gazebo::SystemLoaderPrivate
public: bool InstantiateSystemPlugin(const sdf::Plugin &_sdfPlugin,
ignition::plugin::PluginPtr &_gzPlugin)
{
const std::string gzSimPrefix{"gz-sim"};
auto filename = _sdfPlugin.Filename();
auto pos = filename.find(gzSimPrefix);
if (pos != std::string::npos)
{
filename.replace(pos, gzSimPrefix.size(), "ignition-gazebo");
}

std::list<std::string> paths = this->PluginPaths();
common::SystemPaths systemPaths;
for (const auto &p : paths)
{
systemPaths.AddPluginPaths(p);
}

auto pathToLib = systemPaths.FindSharedLibrary(_sdfPlugin.Filename());
auto pathToLib = systemPaths.FindSharedLibrary(filename);
if (pathToLib.empty())
{
// We assume gz::sim corresponds to the levels feature
Expand Down Expand Up @@ -125,8 +141,11 @@ class ignition::gazebo::SystemLoaderPrivate
return true;
}

// Default plugin search path environment variable
// Default plugin search path environment variable. Prefer
// GZ_SYSTEM_SIM_PLUGIN_PATH for compatibility with future versions of Gazebo.
public: std::string pluginPathEnv{"IGN_GAZEBO_SYSTEM_PLUGIN_PATH"};
// Default plugin search path environment variable
public: std::string pluginPathEnvGzSim{"GZ_SIM_SYSTEM_PLUGIN_PATH"};

/// \brief Plugin loader instace
public: gz::plugin::Loader loader;
Expand Down
Loading