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

Re-enabling Windows tests #376

Merged
merged 10 commits into from
Oct 12, 2023
7 changes: 7 additions & 0 deletions include/gz/fuel_tools/FuelClient.hh
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,13 @@ namespace gz
const std::vector<WorldIdentifier> &_ids,
size_t _jobs = 2);

/// \brief Check if a model is already present in the local cache.
/// \param[in] _id The model identifier
/// \param[out] _path Local path where the model can be found.
/// \return FETCH_ERROR if not cached, FETCH_ALREADY_EXISTS if cached.
public: Result CachedModel(const ModelIdentifier &_id,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to do this for CacheWorld or is it not necessary since we don't include worlds in SDF files?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't covered by existing tests, so I probably didn't notice it. I suppose it's unnecessary without include-ing in SDF.

std::string &_path);

/// \brief Check if a model is already present in the local cache.
/// \param[in] _modelUrl The unique URL of the model on a Fuel server.
/// E.g.: https://fuel.gazebosim.org/1.0/caguero/models/Beer
Expand Down
15 changes: 15 additions & 0 deletions include/gz/fuel_tools/Helpers.hh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,21 @@ namespace gz
{
namespace fuel_tools
{
/// \brief Convert the authority portion of a URI to a string
/// suitable to be used as a path on disk for all platforms.
///
/// It encodes illegal characters on Windows and Linux filesystems with
/// their corresponding URL-encoded values.
///
/// This assumes an authority of the form: username@host:port
/// "@" is encoded as %40
/// ":" is encoded as %3A
///
/// \param[in] _uriAuthority the authority section of the URI to convert.
/// \return String suitable to use in file paths
GZ_FUEL_TOOLS_VISIBLE
std::string sanitizeAuthority(const std::string &_uriAuthority);

/// \brief Convert a URI to a string suitable to use as a path on disk.
/// It strips the scheme and authority's `//` prefix.
/// \param[in] _uri URI to convert.
Expand Down
2 changes: 1 addition & 1 deletion src/ClientConfig.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class gz::fuel_tools::ServerConfigPrivate
}

/// \brief URL to reach server
public: common::URI url{"https://fuel.gazebosim.org"};
public: common::URI url{"https://fuel.gazebosim.org", true};

/// \brief A key to auth with the server
public: std::string key = "";
Expand Down
2 changes: 1 addition & 1 deletion src/CollectionIdentifier_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ TEST(CollectionIdentifier, SetFields)
/////////////////////////////////////////////////
/// \brief Unique Name
// See https://github.com/gazebosim/gz-fuel-tools/issues/231
TEST(CollectionIdentifier, GZ_UTILS_TEST_DISABLED_ON_WIN32(UniqueName))
TEST(CollectionIdentifier, UniqueName)
{
gz::fuel_tools::ServerConfig srv1;
srv1.SetUrl(common::URI("https://localhost:8001"));
Expand Down
71 changes: 44 additions & 27 deletions src/FuelClient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,8 @@ Result FuelClient::ModelDependencies(const ModelIdentifier &_id,
// Locate any dependencies from the input model and download them.
std::string path;
gz::msgs::FuelMetadata meta;
if (this->CachedModel(gz::common::URI(_id.UniqueName()), path))

if (this->CachedModel(_id, path))
{
std::string metadataPath =
gz::common::joinPaths(path, "metadata.pbtxt");
Expand Down Expand Up @@ -1097,7 +1098,11 @@ bool FuelClient::ParseModelUrl(const common::URI &_modelUrl,
}

// Get remaining server information from config
_id.Server().SetUrl(common::URI(scheme + "://" + server));
common::URI serverUri;
serverUri.SetScheme(scheme);
serverUri.SetAuthority(gz::common::URIAuthority("//" + server));

_id.Server().SetUrl(serverUri);
_id.Server().SetVersion(apiVersion);
for (const auto &s : this->dataPtr->config.Servers())
{
Expand Down Expand Up @@ -1163,7 +1168,11 @@ bool FuelClient::ParseWorldUrl(const common::URI &_worldUrl,
}

// Get remaining server information from config
_id.Server().SetUrl(common::URI(scheme + "://" + server));
common::URI serverUri;
serverUri.SetScheme(scheme);
serverUri.SetAuthority(gz::common::URIAuthority("//" + server));

_id.Server().SetUrl(serverUri);
_id.Server().SetVersion(apiVersion);
for (const auto &s : this->dataPtr->config.Servers())
{
Expand Down Expand Up @@ -1231,7 +1240,11 @@ bool FuelClient::ParseModelFileUrl(const common::URI &_modelFileUrl,
}

// Get remaining server information from config
_id.Server().SetUrl(common::URI(scheme + "://" + server));
common::URI serverUri;
serverUri.SetScheme(scheme);
serverUri.SetAuthority(gz::common::URIAuthority("//" + server));

_id.Server().SetUrl(serverUri);
_id.Server().SetVersion(apiVersion);
for (const auto &s : this->dataPtr->config.Servers())
{
Expand Down Expand Up @@ -1300,7 +1313,11 @@ bool FuelClient::ParseWorldFileUrl(const common::URI &_worldFileUrl,
}

// Get remaining server information from config
_id.Server().SetUrl(common::URI(scheme + "://" + server));
common::URI serverUri;
serverUri.SetScheme(scheme);
serverUri.SetAuthority(gz::common::URIAuthority("//" + server));

_id.Server().SetUrl(serverUri);
_id.Server().SetVersion(apiVersion);
for (const auto &s : this->dataPtr->config.Servers())
{
Expand Down Expand Up @@ -1367,7 +1384,11 @@ bool FuelClient::ParseCollectionUrl(const common::URI &_url,
}

// Get remaining server information from config
_id.Server().SetUrl(common::URI(scheme + "://" + server));
common::URI serverUri;
serverUri.SetScheme(scheme);
serverUri.SetAuthority(gz::common::URIAuthority("//" + server));

_id.Server().SetUrl(serverUri);
_id.Server().SetVersion(apiVersion);
for (const auto &s : this->dataPtr->config.Servers())
{
Expand Down Expand Up @@ -1414,9 +1435,6 @@ Result FuelClient::DownloadModel(const common::URI &_modelUrl,
if (!result)
return result;

// TODO(anyone) We shouldn't need to reconstruct the path, SaveModel should
// be changed to return it

// We need to figure out the version for the tip
if (id.Version() == 0 || id.VersionStr() == "tip")
{
Expand All @@ -1425,8 +1443,7 @@ Result FuelClient::DownloadModel(const common::URI &_modelUrl,
}

_path = gz::common::joinPaths(this->Config().CacheLocation(),
id.Server().Url().Path().Str(), id.Owner(), "models", id.Name(),
id.VersionStr());
id.UniqueName(), id.VersionStr());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that UniqueName uses Server().Url().Str(), while the code here previously had Server().Url().Path().Str(). Is this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is because previously when we had a web URL, we weren't setting the authority and treating the whole thing as a path, when really the domain name is the authority in this case

# Before (authority = false)
https://fuel.gazebosim.com/user/model
  Authority: ""
  Path: "fuel.gazebosim.com/user/model"

https://foo@localhost:8080/user/model -> 
  Authority: ""
  Path: "foo@localhost:8080/user/model"

# After (authority = true)
https://fuel.gazebosim.com/user/model
  Authority: "fuel.gazebosim.com"
  Path: "user/model"

https://foo@localhost:8080/user/model -> 
  Authority: "foo@localhost:8080"
  Path: "user/model"

So we need the "full" URL returned by Url() to get the Authority as part of the unique name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I misunderstood Path as a function that somehow converts the URL into a file path, not returning the formal Path of a URL. This makes sense. Thanks!


return result;
}
Expand All @@ -1453,15 +1470,23 @@ Result FuelClient::DownloadWorld(const common::URI &_worldUrl,
}

//////////////////////////////////////////////////
bool FuelClient::CachedModel(const common::URI &_modelUrl)
Result FuelClient::CachedModel(const ModelIdentifier &_id,
std::string &_path)
{
// Get data from URL
ModelIdentifier id;
if (!this->ParseModelUrl(_modelUrl, id))
return Result(ResultType::FETCH_ERROR);
auto modelIter = this->dataPtr->cache->MatchingModel(_id);
if (modelIter)
{
_path = modelIter.PathToModel();
return Result(ResultType::FETCH_ALREADY_EXISTS);
}
return Result(ResultType::FETCH_ERROR);
}

// Check local cache
return this->dataPtr->cache->MatchingModel(id) ? true : false;
//////////////////////////////////////////////////
bool FuelClient::CachedModel(const common::URI &_modelUrl)
{
std::string path;
return this->CachedModel(_modelUrl, path).Type() != ResultType::FETCH_ERROR;
}

//////////////////////////////////////////////////
Expand All @@ -1475,15 +1500,7 @@ Result FuelClient::CachedModel(const common::URI &_modelUrl,
return Result(ResultType::FETCH_ERROR);
}

// Check local cache
auto modelIter = this->dataPtr->cache->MatchingModel(id);
if (modelIter)
{
_path = modelIter.PathToModel();
return Result(ResultType::FETCH_ALREADY_EXISTS);
}

return Result(ResultType::FETCH_ERROR);
return this->CachedModel(id, _path);
}

//////////////////////////////////////////////////
Expand Down
Loading