diff --git a/src/Interface.cc b/src/Interface.cc index 4434be31..c2cf3a6f 100644 --- a/src/Interface.cc +++ b/src/Interface.cc @@ -15,6 +15,7 @@ * */ +#include "ignition/common/Console.hh" #include "ignition/fuel_tools/Interface.hh" #include "ignition/fuel_tools/WorldIdentifier.hh" @@ -37,6 +38,7 @@ namespace ignition ignition::fuel_tools::ModelIdentifier model; ignition::fuel_tools::WorldIdentifier world; + std::string fileUrl; ignition::common::URI uri(_uri); // Download the model, if it is a model URI if (_client.ParseModelUrl(uri, model) && @@ -44,12 +46,30 @@ namespace ignition { _client.DownloadModel(uri, result); } + // Download the model, if it's a model file URI + else if (_client.ParseModelFileUrl(uri, model, fileUrl) && + !_client.CachedModelFile(uri, result)) + { + auto modelUri = _uri.substr(0, + _uri.find("files", model.UniqueName().size())-1); + _client.DownloadModel(common::URI(modelUri), result); + result += "/" + fileUrl; + } // Download the world, if it is a world URI else if (_client.ParseWorldUrl(uri, world) && !_client.CachedWorld(uri, result)) { _client.DownloadWorld(uri, result); } + // Download the world, if it's a world file URI + else if (_client.ParseWorldFileUrl(uri, world, fileUrl) && + !_client.CachedWorldFile(uri, result)) + { + auto worldUri = _uri.substr(0, + _uri.find("files", world.UniqueName().size())-1); + _client.DownloadWorld(common::URI(worldUri), result); + result += "/" + fileUrl; + } return result; } diff --git a/src/Interface_TEST.cc b/src/Interface_TEST.cc index bfb54220..c0623119 100644 --- a/src/Interface_TEST.cc +++ b/src/Interface_TEST.cc @@ -16,6 +16,7 @@ */ #include +#include #include #include "ignition/fuel_tools/ClientConfig.hh" #include "ignition/fuel_tools/FuelClient.hh" @@ -35,8 +36,10 @@ using namespace ignition; using namespace ignition::fuel_tools; ///////////////////////////////////////////////// -TEST(Interface, FetchResource) +TEST(Interface, FetchResources) { + common::Console::SetVerbosity(4); + // Configure to use binary path as cache ASSERT_EQ(0, ChangeDirectory(PROJECT_BINARY_PATH)); common::removeAll("test_cache"); @@ -44,44 +47,206 @@ TEST(Interface, FetchResource) ClientConfig config; config.SetCacheLocation(common::cwd() + "/test_cache"); - common::URI url{ - "https://fuel.ignitionrobotics.org/1.0/chapulina/models/Test box"}; - // Create client FuelClient client(config); EXPECT_EQ(config.CacheLocation(), client.Config().CacheLocation()); - // Check it is not cached std::string cachedPath; - Result res1 = client.CachedModel(url, cachedPath); - EXPECT_FALSE(res1) << "Cached Path: " << cachedPath; - EXPECT_EQ(Result(ResultType::FETCH_ERROR), res1); - - // Download - std::string path = fetchResourceWithClient(url.Str(), client); - - // Check it was downloaded to `2` - EXPECT_EQ(path, common::cwd() + - "/test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2"); - EXPECT_TRUE(common::exists( - "test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2")); - EXPECT_TRUE(common::exists( - "test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2/" - "model.sdf")); - EXPECT_TRUE(common::exists( - "test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2/" - "model.config")); - - // Check it wasn't downloaded to model root directory - EXPECT_FALSE(common::exists( - "test_cache/fuel.ignitionrobotics.org/chapulina/models" - "/Test box/model.config")); - - // Check it is cached - Result res3 = client.CachedModel(url, cachedPath); - EXPECT_TRUE(res3); - EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res3); - EXPECT_EQ(common::cwd() + - "/test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2", - cachedPath); + + // Model + { + // Check it's not cached + common::URI modelUrl{ + "https://fuel.ignitionrobotics.org/1.0/chapulina/models/Test box"}; + { + Result res = client.CachedModel(modelUrl, cachedPath); + EXPECT_FALSE(res) << "Cached Path: " << cachedPath; + EXPECT_EQ(Result(ResultType::FETCH_ERROR), res); + } + + // Download model + std::string path = fetchResourceWithClient(modelUrl.Str(), client); + + // Check it was downloaded to `2` + EXPECT_EQ(path, common::cwd() + + "/test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2"); + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2")); + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2/" + "model.sdf")); + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2/" + "model.config")); + + // Check it wasn't downloaded to model root directory + EXPECT_FALSE(common::exists( + "test_cache/fuel.ignitionrobotics.org/chapulina/models" + "/Test box/model.config")); + + // Check it is cached + { + Result res = client.CachedModel(modelUrl, cachedPath); + EXPECT_TRUE(res); + EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res); + EXPECT_EQ(common::cwd() + + "/test_cache/fuel.ignitionrobotics.org/chapulina/models/Test box/2", + cachedPath); + } + } + + // Model file + { + // Check neither file nor its model are cached + common::URI modelUrl{ + "https://fuel.ignitionrobotics.org/1.0/openrobotics/models/Bus/1/"}; + common::URI modelFileUrl{ + "https://fuel.ignitionrobotics.org/1.0/openrobotics/models/Bus/1/files" + "/meshes/bus.obj"}; + + { + Result res = client.CachedModel(modelUrl, cachedPath); + EXPECT_FALSE(res) << "Cached Path: " << cachedPath; + EXPECT_EQ(Result(ResultType::FETCH_ERROR), res); + } + { + Result res = client.CachedModelFile(modelFileUrl, cachedPath); + EXPECT_FALSE(res) << "Cached Path: " << cachedPath; + EXPECT_EQ(Result(ResultType::FETCH_ERROR), res); + } + + // Download model file + std::string path = fetchResourceWithClient(modelFileUrl.Str(), client); + + // Check entire model was downloaded to `1` + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/openrobotics/models/Bus/1")); + EXPECT_EQ(path, common::cwd() + + "/test_cache/fuel.ignitionrobotics.org/openrobotics/models/Bus/1/" + "meshes/bus.obj"); + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/openrobotics/models/Bus/1/" + "model.sdf")); + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/openrobotics/models/Bus/1/" + "model.config")); + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/openrobotics/models/Bus/1/" + "meshes/bus.obj")); + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/openrobotics/models/Bus/1/" + "meshes/bus.mtl")); + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/openrobotics/models/Bus/1/" + "materials/textures/bus.png")); + + // Check model is cached + { + Result res = client.CachedModel(modelUrl, cachedPath); + EXPECT_TRUE(res); + EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res); + EXPECT_EQ(common::cwd() + + "/test_cache/fuel.ignitionrobotics.org/openrobotics/models/Bus/1", + cachedPath); + } + + // Check file is cached + { + Result res = client.CachedModelFile(modelFileUrl, cachedPath); + EXPECT_TRUE(res); + EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res); + EXPECT_EQ(common::cwd() + + "/test_cache/fuel.ignitionrobotics.org/openrobotics/models/Bus/1" + "/meshes/bus.obj", + cachedPath); + } + } + + // World + { + // Check it's not cached + common::URI worldUrl{ + "https://fuel.ignitionrobotics.org/1.0/openrobotics/worlds/Test world"}; + { + Result res = client.CachedWorld(worldUrl, cachedPath); + EXPECT_FALSE(res) << "Cached Path: " << cachedPath; + EXPECT_EQ(Result(ResultType::FETCH_ERROR), res); + } + + // Download world + std::string path = fetchResourceWithClient(worldUrl.Str(), client); + + // Check it was downloaded to `1` + EXPECT_EQ(path, common::cwd() + "/test_cache/fuel.ignitionrobotics.org/" + "openrobotics/worlds/Test world/1"); + EXPECT_TRUE(common::exists("test_cache/fuel.ignitionrobotics.org/" + "openrobotics/worlds/Test world/1")); + EXPECT_TRUE(common::exists("test_cache/fuel.ignitionrobotics.org/" + "openrobotics/worlds/Test world/1/test.world")); + + // Check it is cached + { + Result res = client.CachedWorld(worldUrl, cachedPath); + EXPECT_TRUE(res); + EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res); + EXPECT_EQ(common::cwd() + + "/test_cache/fuel.ignitionrobotics.org/openrobotics/worlds/" + "Test world/1", cachedPath); + } + } + + // World file + { + // Check neither file nor its world are cached + common::URI worldUrl{ + "https://fuel.ignitionrobotics.org/1.0/chapulina/worlds/Test world/1/"}; + common::URI worldFileUrl{ + "https://fuel.ignitionrobotics.org/1.0/chapulina/worlds/Test world/1/" + "files/thumbnails/1.png"}; + + { + Result res = client.CachedWorld(worldUrl, cachedPath); + EXPECT_FALSE(res) << "Cached Path: " << cachedPath; + EXPECT_EQ(Result(ResultType::FETCH_ERROR), res); + } + { + Result res = client.CachedWorldFile(worldFileUrl, cachedPath); + EXPECT_FALSE(res) << "Cached Path: " << cachedPath; + EXPECT_EQ(Result(ResultType::FETCH_ERROR), res); + } + + // Download world file + std::string path = fetchResourceWithClient(worldFileUrl.Str(), client); + + // Check entire world was downloaded to `1` + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/chapulina/worlds/Test world/1")); + EXPECT_EQ(path, common::cwd() + + "/test_cache/fuel.ignitionrobotics.org/chapulina/worlds/Test world/1/" + "thumbnails/1.png"); + EXPECT_TRUE(common::exists( + "test_cache/fuel.ignitionrobotics.org/chapulina/worlds/Test world/1/" + "test.world")); + + // Check world is cached + { + Result res = client.CachedWorld(worldUrl, cachedPath); + EXPECT_TRUE(res); + EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res); + EXPECT_EQ(common::cwd() + + "/test_cache/fuel.ignitionrobotics.org/chapulina/worlds/Test world/1", + cachedPath); + } + + // Check file is cached + { + Result res = client.CachedWorldFile(worldFileUrl, cachedPath); + EXPECT_TRUE(res); + EXPECT_EQ(Result(ResultType::FETCH_ALREADY_EXISTS), res); + EXPECT_EQ(common::cwd() + + "/test_cache/fuel.ignitionrobotics.org/chapulina/worlds/Test world/1" + "/thumbnails/1.png", + cachedPath); + } + } }