Skip to content

Commit

Permalink
Backport test utilities from sdf10 (#731)
Browse files Browse the repository at this point in the history
Adds sdf::testing::SourceFile, sdf::testing::TestFile, sdf::testing::env, and sdf::testing::setenv and updates tests to use them. This makes it easier to backport other changes from newer branches.

Signed-off-by: Addisu Z. Taddese <addisu@openrobotics.org>
  • Loading branch information
azeey committed Oct 18, 2021
1 parent 8cbc9b5 commit 344312c
Show file tree
Hide file tree
Showing 38 changed files with 390 additions and 249 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ if (BUILD_SDF_TEST)
)
endif()

include_directories(${PROJECT_SOURCE_DIR}/test)
sdf_build_tests(${gtest_sources})

if (NOT WIN32)
Expand Down
6 changes: 2 additions & 4 deletions src/Converter_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1887,13 +1887,11 @@ TEST(Converter, MuchNewerVersion)

static std::string ConvertDoc_15_16()
{
return sdf::filesystem::append(PROJECT_SOURCE_PATH, "sdf", "1.6",
"1_5.convert");
return sdf::testing::SourceFile("sdf", "1.6", "1_5.convert");
}
static std::string ConvertDoc_16_17()
{
return sdf::filesystem::append(PROJECT_SOURCE_PATH, "sdf", "1.7",
"1_6.convert");
return sdf::testing::SourceFile("sdf", "1.7", "1_6.convert");
}

/////////////////////////////////////////////////
Expand Down
9 changes: 3 additions & 6 deletions src/FrameSemantics_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@
TEST(FrameSemantics, buildFrameAttachedToGraph_Model)
{
const std::string testFile =
sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf",
"model_frame_attached_to.sdf");
sdf::testing::TestFile("sdf", "model_frame_attached_to.sdf");

// Load the SDF file
sdf::Root root;
Expand Down Expand Up @@ -103,8 +102,7 @@ TEST(FrameSemantics, buildFrameAttachedToGraph_Model)
TEST(FrameSemantics, buildFrameAttachedToGraph_World)
{
const std::string testFile =
sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf",
"world_frame_attached_to.sdf");
sdf::testing::TestFile("sdf", "world_frame_attached_to.sdf");

// Load the SDF file
sdf::Root root;
Expand Down Expand Up @@ -198,8 +196,7 @@ TEST(FrameSemantics, buildFrameAttachedToGraph_World)
TEST(FrameSemantics, buildPoseRelativeToGraph)
{
const std::string testFile =
sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf",
"model_frame_relative_to_joint.sdf");
sdf::testing::TestFile("sdf", "model_frame_relative_to_joint.sdf");

// Load the SDF file
sdf::Root root;
Expand Down
8 changes: 4 additions & 4 deletions src/ign_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -721,7 +721,7 @@ int main(int argc, char **argv)
{
// Set IGN_CONFIG_PATH to the directory where the .yaml configuration file
// is located.
setenv("IGN_CONFIG_PATH", IGN_CONFIG_PATH, 1);
sdf::testing::setenv("IGN_CONFIG_PATH", IGN_CONFIG_PATH);

// Make sure that we load the library recently built and not the one installed
// in your system. This is done by placing the the current build directory
Expand All @@ -732,13 +732,13 @@ int main(int argc, char **argv)
#ifndef _WIN32
std::string testLibraryPath = IGN_TEST_LIBRARY_PATH;

char *currentLibraryPath = std::getenv("LD_LIBRARY_PATH");
if (currentLibraryPath)
std::string currentLibraryPath;
if (sdf::testing::env("LD_LIBRARY_PATH", currentLibraryPath))
{
testLibraryPath = testLibraryPath + ":" + currentLibraryPath;
}

setenv("LD_LIBRARY_PATH", testLibraryPath.c_str(), 1);
sdf::testing::setenv("LD_LIBRARY_PATH", testLibraryPath);
#endif

::testing::InitGoogleTest(&argc, argv);
Expand Down
40 changes: 21 additions & 19 deletions src/parser_TEST.cc
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@ sdf::SDFPtr InitSDF()
/////////////////////////////////////////////////
TEST(Parser, ReusedSDFVersion)
{
std::string pathBase = PROJECT_SOURCE_PATH;
pathBase += "/test/sdf";
const std::string path17 = pathBase +"/model_link_relative_to.sdf";
const std::string path16 = pathBase +"/joint_complete.sdf";
const auto path17 = sdf::testing::TestFile(
"sdf", "model_link_relative_to.sdf");
const auto path16 = sdf::testing::TestFile("sdf", "joint_complete.sdf");

// Call readFile API that always converts
sdf::SDFPtr sdf = InitSDF();
Expand All @@ -85,9 +84,7 @@ TEST(Parser, ReusedSDFVersion)
/////////////////////////////////////////////////
TEST(Parser, readFileConversions)
{
std::string pathBase = PROJECT_SOURCE_PATH;
pathBase += "/test/sdf";
const std::string path = pathBase +"/joint_complete.sdf";
const auto path = sdf::testing::TestFile("sdf", "joint_complete.sdf");

// Call readFile API that always converts
{
Expand Down Expand Up @@ -346,16 +343,13 @@ TEST(Parser, addNestedModel)
/////////////////////////////////////////////////
TEST(Parser, NameUniqueness)
{
std::string pathBase = PROJECT_SOURCE_PATH;
pathBase += "/test/sdf";

// These tests are copies of the ones in ign_TEST.cc but use direct calls to
// name uniqueness validator functions instead of going through ign.

// Check an SDF file with sibling elements of the same type (world)
// that have duplicate names.
{
std::string path = pathBase +"/world_duplicate.sdf";
const auto path = sdf::testing::TestFile("sdf", "world_duplicate.sdf");
sdf::SDFPtr sdf = InitSDF();
EXPECT_TRUE(sdf::readFile(path, sdf));
EXPECT_FALSE(sdf::recursiveSameTypeUniqueNames(sdf->Root()));
Expand All @@ -368,7 +362,8 @@ TEST(Parser, NameUniqueness)
// Check an SDF file with sibling elements of different types (model, light)
// that have duplicate names.
{
std::string path = pathBase +"/world_sibling_same_names.sdf";
const auto path = sdf::testing::TestFile("sdf",
"world_sibling_same_names.sdf");
sdf::SDFPtr sdf = InitSDF();
EXPECT_TRUE(sdf::readFile(path, sdf));
EXPECT_FALSE(sdf::recursiveSiblingUniqueNames(sdf->Root()));
Expand All @@ -381,7 +376,8 @@ TEST(Parser, NameUniqueness)
// Check an SDF file with sibling elements of the same type (link)
// that have duplicate names.
{
std::string path = pathBase +"/model_duplicate_links.sdf";
const auto path = sdf::testing::TestFile("sdf",
"model_duplicate_links.sdf");
sdf::SDFPtr sdf = InitSDF();
EXPECT_TRUE(sdf::readFile(path, sdf));
EXPECT_FALSE(sdf::recursiveSameTypeUniqueNames(sdf->Root()));
Expand All @@ -394,7 +390,8 @@ TEST(Parser, NameUniqueness)
// Check an SDF file with sibling elements of the same type (joint)
// that have duplicate names.
{
std::string path = pathBase +"/model_duplicate_joints.sdf";
const auto path = sdf::testing::TestFile("sdf",
"model_duplicate_joints.sdf");
sdf::SDFPtr sdf = InitSDF();
EXPECT_TRUE(sdf::readFile(path, sdf));
EXPECT_FALSE(sdf::recursiveSameTypeUniqueNames(sdf->Root()));
Expand All @@ -407,7 +404,8 @@ TEST(Parser, NameUniqueness)
// Check an SDF file with sibling elements of different types (link, joint)
// that have duplicate names.
{
std::string path = pathBase +"/model_link_joint_same_name.sdf";
const auto path = sdf::testing::TestFile("sdf",
"model_link_joint_same_name.sdf");
sdf::SDFPtr sdf = InitSDF();
EXPECT_TRUE(sdf::readFile(path, sdf));
EXPECT_FALSE(sdf::recursiveSiblingUniqueNames(sdf->Root()));
Expand All @@ -420,7 +418,8 @@ TEST(Parser, NameUniqueness)
// Check an SDF file with sibling elements of the same type (collision)
// that have duplicate names.
{
std::string path = pathBase +"/link_duplicate_sibling_collisions.sdf";
const auto path = sdf::testing::TestFile("sdf",
"link_duplicate_sibling_collisions.sdf");
sdf::SDFPtr sdf = InitSDF();
EXPECT_TRUE(sdf::readFile(path, sdf));
EXPECT_FALSE(sdf::recursiveSameTypeUniqueNames(sdf->Root()));
Expand All @@ -433,7 +432,8 @@ TEST(Parser, NameUniqueness)
// Check an SDF file with sibling elements of the same type (visual)
// that have duplicate names.
{
std::string path = pathBase +"/link_duplicate_sibling_visuals.sdf";
const auto path = sdf::testing::TestFile("sdf",
"link_duplicate_sibling_visuals.sdf");
sdf::SDFPtr sdf = InitSDF();
EXPECT_TRUE(sdf::readFile(path, sdf));
EXPECT_FALSE(sdf::recursiveSiblingUniqueNames(sdf->Root()));
Expand All @@ -446,7 +446,8 @@ TEST(Parser, NameUniqueness)
// Check an SDF file with cousin elements of the same type (collision)
// that have duplicate names. This is a valid file.
{
std::string path = pathBase +"/link_duplicate_cousin_collisions.sdf";
const auto path = sdf::testing::TestFile("sdf",
"link_duplicate_cousin_collisions.sdf");
sdf::SDFPtr sdf = InitSDF();
EXPECT_TRUE(sdf::readFile(path, sdf));
EXPECT_TRUE(sdf::recursiveSameTypeUniqueNames(sdf->Root()));
Expand All @@ -460,7 +461,8 @@ TEST(Parser, NameUniqueness)
// Check an SDF file with cousin elements of the same type (visual)
// that have duplicate names. This is a valid file.
{
std::string path = pathBase +"/link_duplicate_cousin_visuals.sdf";
const auto path = sdf::testing::TestFile("sdf",
"link_duplicate_cousin_visuals.sdf");
sdf::SDFPtr sdf = InitSDF();
EXPECT_TRUE(sdf::readFile(path, sdf));
EXPECT_TRUE(sdf::recursiveSameTypeUniqueNames(sdf->Root()));
Expand Down
139 changes: 139 additions & 0 deletions test/env.hh
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (C) 2021 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.
*
*/

// Note: this is a direct copy from ignition::common,
// and can be removed when sdformat has common as a dependency

#ifndef SDF_TEST_ENV_HH
#define SDF_TEST_ENV_HH

#include <cstdlib>
#include <string>

#ifdef _WIN32
#include <windows.h>
#endif

namespace sdf
{
namespace testing
{

/// \brief Find the environment variable '_name' and return its value.
///
/// Note: the intention is to put this in ign-util, and remove it
/// from sdformat once the depcnency is in place
///
/// \param[in] _name Name of the environment variable.
/// \param[out] _value Value if the variable was found.
/// \param[in] _allowEmpty Allow set-but-empty variables.
/// (Unsupported on Windows)
/// \return True if the variable was found or false otherwise.
bool env(const std::string &_name,
std::string &_value,
bool _allowEmpty)
{
std::string v;
bool valid = false;
#ifdef _WIN32
// Unused on Windows, suppress warning
(void) _allowEmpty;
const DWORD buffSize = 32767;
static char buffer[buffSize];
if (GetEnvironmentVariable(_name.c_str(), buffer, buffSize))
{
v = buffer;
}

if (!v.empty())
{
valid = true;
}

#else
const char *cvar = std::getenv(_name.c_str());
if (cvar != nullptr)
{
v = cvar;
valid = true;

if (v[0] == '\0' && !_allowEmpty)
{
valid = false;
}
}
#endif
if (valid)
{
_value = v;
return true;
}
return false;
}

bool env(const std::string &_name, std::string &_value)
{
return env(_name, _value, false);
}

/// \brief Set the environment variable '_name'.
///
/// Note that on Windows setting an empty string (_value=="")
/// is the equivalent of unsetting the variable.
///
/// \param[in] _name Name of the environment variable.
/// \param[in] _value Value of the variable to be set.
/// \return True if the variable was set or false otherwise.
bool setenv(const std::string &_name,
const std::string &_value)
{
#ifdef _WIN32
if (0 != _putenv_s(_name.c_str(), _value.c_str()))
{
return false;
}
#else
if (0 != ::setenv(_name.c_str(), _value.c_str(), true))
{
return false;
}
#endif
return true;
}

/// \brief Unset the environment variable '_name'.
/// \param[in] _name Name of the environment variable.
/// \return True if the variable was unset or false otherwise.
bool unsetenv(const std::string &_name)
{
#ifdef _WIN32
if (0 != _putenv_s(_name.c_str(), ""))
{
return false;
}
#else
if (0 != ::unsetenv(_name.c_str()))
{
return false;
}
#endif
return true;
}
} // namespace testing
} // namespace sdf

#endif
6 changes: 2 additions & 4 deletions test/integration/actor_dom.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
TEST(DOMActor, LoadActors)
{
const std::string testFile =
sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf",
"world_complete.sdf");
sdf::testing::TestFile("sdf", "world_complete.sdf");

sdf::Root root;
sdf::Errors errors = root.Load(testFile);
Expand Down Expand Up @@ -145,8 +144,7 @@ TEST(DOMActor, CopySdfLoadedProperties)
// Verify that copying an actor also copies the underlying ElementPtr
// Joints and Links
const std::string testFile =
sdf::filesystem::append(PROJECT_SOURCE_PATH, "test", "sdf",
"world_complete.sdf");
sdf::testing::TestFile("sdf", "world_complete.sdf");

sdf::Root root;
sdf::Errors errors = root.Load(testFile);
Expand Down
9 changes: 5 additions & 4 deletions test/integration/audio.cc
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,13 @@

#include "test_config.h"


//////////////////////////////////////////////////
TEST(SDFParser, AudioSDF_FullParameters_noThrow)
{
const std::string sdfTestFile = sdf::filesystem::append(
PROJECT_SOURCE_PATH, "test", "integration", "audio.sdf");
const auto sdfTestFile =
sdf::testing::TestFile("integration", "audio.sdf");

sdf::SDFPtr p(new sdf::SDF());
sdf::init(p);
ASSERT_TRUE(sdf::readFile(sdfTestFile , p));
ASSERT_TRUE(sdf::readFile(sdfTestFile, p));
}
Loading

0 comments on commit 344312c

Please sign in to comment.