Skip to content

Download dependencies #123

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

Merged
merged 11 commits into from
Nov 30, 2020
Merged
Show file tree
Hide file tree
Changes from all 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
49 changes: 49 additions & 0 deletions src/FuelClient.cc
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,55 @@ Result FuelClient::DownloadModel(const ModelIdentifier &_id,
if (!this->dataPtr->cache->SaveModel(newId, resp.data, true))
return Result(ResultType::FETCH_ERROR);

// Locate any dependencies from the input model and download them.
std::string path;
ignition::msgs::FuelMetadata meta;
if (this->CachedModel(ignition::common::URI(newId.UniqueName()), path))
{
std::string metadataPath =
ignition::common::joinPaths(path, "metadata.pbtxt");
std::string modelConfigPath =
ignition::common::joinPaths(path, "model.config");

bool foundMetadataPath = ignition::common::exists(metadataPath);
bool foundModelConfigPath = ignition::common::exists(modelConfigPath);

if (foundMetadataPath || foundModelConfigPath)
{
std::string modelPath =
(foundMetadataPath) ? metadataPath : modelConfigPath;

// Read the pbtxt file.
std::ifstream inputFile(modelPath);
std::string inputStr((std::istreambuf_iterator<char>(inputFile)),
std::istreambuf_iterator<char>());

if (foundMetadataPath)
{
// Parse the file into the fuel metadata message
google::protobuf::TextFormat::ParseFromString(inputStr, &meta);
}
else
{
if (!ignition::msgs::ConvertFuelMetadata(inputStr, meta))
{
return Result(ResultType::UPLOAD_ERROR);
}
}

for (int i = 0; i < meta.dependencies_size(); ++i)
{
std::string dependencyPath;
ignition::common::URI dependencyURI(meta.dependencies(i).uri());

// If the model is not already cached, download it; this prevents
// any sort of cyclic dependencies from running infinitely
if (!this->CachedModel(dependencyURI, dependencyPath))
this->DownloadModel(dependencyURI, dependencyPath);
}
}
}

return Result(ResultType::FETCH);
}

Expand Down
70 changes: 70 additions & 0 deletions src/FuelClient_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,76 @@ TEST_F(FuelClientTest, IGN_UTILS_TEST_DISABLED_ON_WIN32(DownloadModel))
EXPECT_NE(std::string::npos, modelSdf.find("<roughness_map>https://"));
}

// Download model with a dependency specified within its `metadata.pbtxt`
{
common::URI url{
"https://fuel.ignitionrobotics.org/1.0/JShep1/models/hatchback_red_1"};
common::URI depUrl{
"https://fuel.ignitionrobotics.org/1.0/JShep1/models/hatchback_1"};

// Check it is not cached
std::string cachedPath;
Result res1 = client.CachedModel(url, cachedPath);
EXPECT_FALSE(res1);
EXPECT_EQ(Result(ResultType::FETCH_ERROR), res1);

// Check the dependency is not cached
Result res2 = client.CachedModel(depUrl, cachedPath);
EXPECT_FALSE(res2);
EXPECT_EQ(Result(ResultType::FETCH_ERROR), res2);

// Download
std::string path;
Result res3 = client.DownloadModel(url, path);
EXPECT_TRUE(res3);
EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res3);

// Check it is cached
Result res4 = client.CachedModel(url, cachedPath);
EXPECT_TRUE(res4);
EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res4);

// Check the dependency is cached
Result res5 = client.CachedModel(depUrl, cachedPath);
EXPECT_TRUE(res5);
EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res5);
}

// Download model with a dependency specified within its `model.config`
{
common::URI url{
"https://fuel.ignitionrobotics.org/1.0/JShep1/models/hatchback_red_2"};
common::URI depUrl{
"https://fuel.ignitionrobotics.org/1.0/JShep1/models/hatchback_2"};

// Check it is not cached
std::string cachedPath;
Result res1 = client.CachedModel(url, cachedPath);
EXPECT_FALSE(res1);
EXPECT_EQ(Result(ResultType::FETCH_ERROR), res1);

// Check the dependency is not cached
Result res2 = client.CachedModel(depUrl, cachedPath);
EXPECT_FALSE(res2);
EXPECT_EQ(Result(ResultType::FETCH_ERROR), res2);

// Download
std::string path;
Result res3 = client.DownloadModel(url, path);
EXPECT_TRUE(res3);
EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res3);

// Check it is cached
Result res4 = client.CachedModel(url, cachedPath);
EXPECT_TRUE(res4);
EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res4);

// Check the dependency is cached
Result res5 = client.CachedModel(depUrl, cachedPath);
EXPECT_TRUE(res5);
EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res5);
}

// Try using nonexistent URL
{
std::string url{
Expand Down