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

Add Sina as Axom component #1378

Open
wants to merge 56 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
89413c6
establish directory structure and copy/paste headers/sources
bgunnar5 Apr 24, 2024
c8bdb57
add doxygen mainpage for sina
bgunnar5 Apr 24, 2024
4455cc7
first pass at the cmake file for sina component
bgunnar5 Apr 24, 2024
857a449
Merge branch 'LLNL:develop' into feature/bgunnar5/sina-integration
bgunnar5 Apr 29, 2024
d8d7a49
move sina to axom and add cmake files so it can be built
bgunnar5 May 8, 2024
39e5a2e
add doxygen mainpage for sina
bgunnar5 May 8, 2024
a370f6f
merge prior changes to this branch made on diff computer
bgunnar5 May 8, 2024
3c40f1a
Merge branch 'develop' of https://github.com/bgunnar5/axom into featu…
bgunnar5 May 8, 2024
a5fba8b
remove extra adiak list append and uncomment test addition
bgunnar5 May 29, 2024
44e6f74
add tests for sina
bgunnar5 May 29, 2024
f212627
initial add of examples
bgunnar5 May 30, 2024
45628bf
get doxygen docs up and running
bgunnar5 Jun 21, 2024
234e1eb
start work on sphinx docs
bgunnar5 Jun 21, 2024
c9b9cca
finish creating sina docs
bgunnar5 Jun 27, 2024
76c7c86
fix references to sina namespace in doxygen
bgunnar5 Jun 27, 2024
7d78852
add sina fortran interface
bgunnar5 Jul 3, 2024
2fbb425
Merge branch 'develop' of https://github.com/LLNL/axom into feature/b…
bgunnar5 Jul 3, 2024
b23292f
fix small issues with docs
bgunnar5 Jul 9, 2024
d9de3ef
make ordering alphabetical for cmakedefines
bgunnar5 Jul 9, 2024
7bf7fc8
fix indentation on doxygen page
bgunnar5 Jul 9, 2024
f15a501
protect against GMOCK not available
bgunnar5 Jul 9, 2024
46d0fcd
move document examples to actual examples
bgunnar5 Jul 10, 2024
5c181c7
add copyright header to sina files
bgunnar5 Jul 10, 2024
4a635bf
move cpp/hpp files to same directory for core and tests
bgunnar5 Jul 11, 2024
820ce9f
remove CppBridge for C++<14
bgunnar5 Jul 11, 2024
10dccf7
replace AXOM_SINA_USE_ADIAK with AXOM_USE_ADIAK
bgunnar5 Jul 11, 2024
d998fac
change doxygen syntax to match axom's standard
bgunnar5 Jul 12, 2024
4d7c8c2
remove unused config file and reference to msub job in docs
bgunnar5 Jul 16, 2024
2860e09
fix issue with Maestro link
bgunnar5 Jul 16, 2024
c8e1f39
convert Datum to pass by reference
bgunnar5 Jul 16, 2024
6f271a3
Merge branch 'develop' of https://github.com/LLNL/axom into feature/b…
bgunnar5 Jul 16, 2024
a57111a
run make style
bgunnar5 Jul 17, 2024
66c3163
Merge branch 'develop' into pr-from-fork/1376
bgunnar5 Jul 17, 2024
917aa27
disable sina for osx_gcc and windows azure tests
bgunnar5 Aug 1, 2024
b9b415b
add custom sina matchers so that blueos will build
bgunnar5 Aug 1, 2024
a516da9
Merge branch 'pr-from-fork/1376' of https://github.com/LLNL/axom into…
bgunnar5 Aug 1, 2024
48b311f
Merge branch 'develop' of https://github.com/LLNL/axom into feature/b…
bgunnar5 Aug 1, 2024
3ef59eb
remove code check call from Sina CMake and run make style
bgunnar5 Aug 5, 2024
5856843
add compiler flag for xl fortran builds
bgunnar5 Aug 7, 2024
5d39439
Merge branch 'develop' of https://github.com/LLNL/axom into feature/b…
bgunnar5 Aug 7, 2024
70b4716
Merge branch 'develop' of https://github.com/LLNL/axom into feature/b…
bgunnar5 Aug 7, 2024
f9285ca
Merge branch 'develop' of https://github.com/LLNL/axom into feature/b…
bgunnar5 Aug 8, 2024
64ce0ec
update sina description in doxygen mainpage
bgunnar5 Aug 8, 2024
0ee8cf9
Merge branch 'develop' of https://github.com/LLNL/axom into feature/b…
bgunnar5 Aug 12, 2024
4552083
add version for sina
bgunnar5 Aug 12, 2024
0c279e3
Merge branch 'develop' into pr-from-fork/1376
rhornung67 Aug 15, 2024
caab17d
Update src/axom/sina/core/ID.hpp
bgunnar5 Aug 30, 2024
bce3aaa
implementation -> header in hpp file brief statements
bgunnar5 Aug 30, 2024
274851f
make docs suggestions from PR
bgunnar5 Aug 30, 2024
528d0d9
modify code block comments for docs
bgunnar5 Aug 30, 2024
6246b2d
some final fixes for sina docs
bgunnar5 Aug 30, 2024
dbf9d5a
fix python interpreter package find to not use deprecated call
bgunnar5 Aug 30, 2024
ae026bf
move custom XL flag to just be used for sina fortran example executable
bgunnar5 Aug 30, 2024
cbcbce0
Merge branch 'develop' of https://github.com/LLNL/axom into feature/b…
bgunnar5 Aug 30, 2024
03aca6d
Merge branch 'pr-from-fork/1376' of https://github.com/LLNL/axom into…
bgunnar5 Aug 30, 2024
7289033
fix python executable variable name
bgunnar5 Sep 4, 2024
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
Prev Previous commit
Next Next commit
add tests for sina
  • Loading branch information
bgunnar5 committed May 29, 2024
commit 44e6f74f7b3d3657b06dd2a8b95d20d675adfa2f
68 changes: 68 additions & 0 deletions src/axom/sina/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Copyright (c) 2017-2024, Lawrence Livermore National Security, LLC and
# other Axom Project Developers. See the top-level LICENSE file for details.
#
# SPDX-License-Identifier: (BSD-3-Clause)
#------------------------------------------------------------------------------
# Sina unit tests
#------------------------------------------------------------------------------

#------------------------------------------------------------------------------
# Specify list of tests
#------------------------------------------------------------------------------

set(gtest_sina_tests
src/sina_ConduitUtil.cpp
src/sina_CppBridge.cpp
src/sina_Curve.cpp
src/sina_CurveSet.cpp
src/sina_DataHolder.cpp
src/sina_Datum.cpp
src/sina_Document.cpp
src/sina_File.cpp
src/sina_ID.cpp
src/sina_Record.cpp
src/sina_Relationship.cpp
src/sina_Run.cpp
)

# Define Sina test utility sources and headers
set(sina_test_utils_sources
src/ConduitTestUtils.cpp
src/TestRecord.cpp
)
set(sina_test_utils_headers
include/ConduitTestUtils.hpp
include/TestRecord.hpp
)

# Define Sina test dependencies
set(sina_gtests_depends_on sina gtest gmock conduit::conduit)

# Add tests using Adiak if necessary and Adiak dependency
blt_list_append( TO gtest_sina_tests ELEMENTS src/sina_AdiakWriter.cpp IF AXOM_SINA_USE_ADIAK)
blt_list_append( TO sina_gtests_depends_on ELEMENTS adiak::adiak IF AXOM_SINA_USE_ADIAK )

# Create a library for the test utilities so they can be used
axom_add_library(
NAME sina_test_utils
SOURCES ${sina_test_utils_sources}
HEADERS ${sina_test_utils_headers}
DEPENDS_ON ${sina_gtests_depends_on}
FOLDER axom/sina/tests)

#------------------------------------------------------------------------------
# Add gtest C++ tests
#------------------------------------------------------------------------------
foreach(test ${gtest_sina_tests})
get_filename_component( test_name ${test} NAME_WE )
axom_add_executable(NAME ${test_name}_test
SOURCES ${test}
OUTPUT_DIR ${TEST_OUTPUT_DIRECTORY}
DEPENDS_ON sina_test_utils
FOLDER axom/sina/tests
)

axom_add_test( NAME ${test_name}
COMMAND ${test_name}_test
)
endforeach()
39 changes: 39 additions & 0 deletions src/axom/sina/tests/include/ConduitTestUtils.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef SINA_CONDUITTESTUTILS_HPP
#define SINA_CONDUITTESTUTILS_HPP

#include <string>

#include "gmock/gmock.h"

#include "conduit.hpp"

namespace axom
{
namespace sina
{
namespace testing
{

/**
* Parse a JSON value.
*
* @param valueAsString the value as a string
* @return the value as a Conduit node
*/
conduit::Node parseJsonValue(std::string const &valueAsString);

// A matcher which verifies that a given Conduit node produces the expected
// JSON string
MATCHER_P(MatchesJson, expectedJsonString, "") {
conduit::Node expected = parseJsonValue(expectedJsonString);
*result_listener << "Given node is " << arg.to_json_default();
conduit::Node diff;
bool differ = expected.diff(arg, diff);
return !differ;
}

} // end testing namespace
} // end sina namespace
} // end axom namespace

#endif //SINA_CONDUITTESTUTILS_HPP
81 changes: 81 additions & 0 deletions src/axom/sina/tests/include/TestRecord.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef SINA_TESTRECORD_HPP
#define SINA_TESTRECORD_HPP

#include "axom/sina/include/ConduitUtil.hpp"
#include "axom/sina/include/Record.hpp"

namespace axom
{
namespace sina
{
namespace testing
{

char constexpr TEST_RECORD_VALUE_KEY[] = "testKey";

/**
* A TestRecord is a class template that's a subclass of Record and simply
* stores a value of a specified type.
*
* @tparam T the type of the value to store
*/
template<typename T>
class TestRecord : public Record {
public:

/**
* Create a new TestRecord.
*
* @param id the ID of the record. It is always a global ID.
* @param type the type of the record
* @param value the value of the record
*/
TestRecord(std::string id, std::string type, T value);

/**
* Create a new TestRecord from its conduit Node representation.
*
* NOTE: This needs to be implemented explicitly for each type of value
*
* @param asValue the record in its Node representation
*/
explicit TestRecord(conduit::Node const &asValue);

/**
* Get the record's value.
*
* @return the record's value
*/
const T &getValue() const noexcept {
return value;
}

conduit::Node toNode() const override;

private:
T value;
};

template<typename T>
TestRecord<T>::TestRecord(std::string id, std::string type, T value_) :
Record{ID{std::move(id), IDType::Global}, std::move(type)},
value{std::move(value_)} {}

template<>
TestRecord<std::string>::TestRecord(conduit::Node const &asNode);

template<>
TestRecord<int>::TestRecord(conduit::Node const &asJson);

template<typename T>
conduit::Node TestRecord<T>::toNode() const {
auto asJson = Record::toNode();
asJson[TEST_RECORD_VALUE_KEY] = value;
return asJson;
}

} // end testing namespace
} // end sina namespace
} // end axom namespace

#endif //SINA_TESTRECORD_HPP
24 changes: 24 additions & 0 deletions src/axom/sina/tests/src/ConduitTestUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "axom/sina/tests/include/ConduitTestUtils.hpp"

namespace axom
{
namespace sina
{
namespace testing
{

conduit::Node parseJsonValue(std::string const &valueAsString) {
// If we just try to do node.parse(valueAsString, "json"), then passing
// in strings does not work. We need to create a document with a key
// so that valueAsString can be parsed as a value.
conduit::Node node;
std::string fullContents = "{\"TEST_KEY\": ";
fullContents += valueAsString;
fullContents += "}";
node.parse(fullContents, "json");
return node.child("TEST_KEY");
}

} // end testing namespace
} // end sina namespace
} // end axom namespace
23 changes: 23 additions & 0 deletions src/axom/sina/tests/src/TestRecord.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "axom/sina/tests/include/TestRecord.hpp"

namespace axom
{
namespace sina
{
namespace testing
{

template<>
TestRecord<std::string>::TestRecord(conduit::Node const &asNode) :
Record{asNode},
value{getRequiredString(TEST_RECORD_VALUE_KEY, asNode, "TestRecord")} {}

template<>
TestRecord<int>::TestRecord(conduit::Node const &asNode) :
Record{asNode},
value{getRequiredField(TEST_RECORD_VALUE_KEY, asNode,
"TestRecord").as_int()} {}

} // end testing namespace
} // end sina namespace
} // end axom namespace
154 changes: 154 additions & 0 deletions src/axom/sina/tests/src/sina_AdiakWriter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
#include "axom/sina/include/AdiakWriter.hpp"

#ifdef AXOM_SINA_USE_ADIAK

#include <stdexcept>
#include <string>
#include <vector>

#include "gtest/gtest.h"
#include "gmock/gmock.h"

#include "adiak.hpp"
extern "C" {
#include "adiak_tool.h"
#include "adiak.h"
}

#include "axom/sina/include/Datum.hpp"
#include "axom/sina/include/ID.hpp"
#include "axom/sina/include/Run.hpp"

namespace axom
{
namespace sina
{
namespace testing
{
namespace
{

using ::testing::HasSubstr;
using ::testing::DoubleEq;
using ::testing::ElementsAre;

char const EXPECTED_DATA_KEY[] = "data";
char const EXPECTED_FILES_KEY[] = "files";

class AdiakWriterTest : public ::testing::Test {

protected:
static void SetUpTestCase() {
adiak::init(nullptr);
adiak_register_cb(1, adiak_category_all, AdiakWriterTest::callbackWrapper, 0, &current_test);
}

void SetUp() override {
current_test=this;
}

static void callbackWrapper(const char *name, adiak_category_t category, const char *subcategory, adiak_value_t *val, adiak_datatype_t *adiak_type, void *adiakwriter){
auto test = static_cast<AdiakWriterTest**>(adiakwriter);
adiakSinaCallback(name, category, subcategory, val, adiak_type, &((*test)->record));
}

axom::sina::Record record{axom::sina::ID{"test_run", axom::sina::IDType::Local}, "test_type"};
static AdiakWriterTest *current_test;
};

AdiakWriterTest *AdiakWriterTest::current_test;

TEST_F(AdiakWriterTest, basic_assignment) {
//adiak::init(nullptr);
//adiak_register_cb(1, adiak_category_all, sina::adiakSinaCallback, 0, callback_record_ptr);
std::string name1 = "name1";
std::string value1 = "value1";
std::vector<std::string> tags1 = {"string"};
std::string name2 = "name2";
int value2 = 2;
std::vector<std::string> tags2 = {"int"};
auto result1 = adiak::value(name1, value1);
auto result2 = adiak::value(name2, value2);
EXPECT_TRUE(result1 && result2);
auto asNode = record.toNode();
EXPECT_EQ(value1, asNode[EXPECTED_DATA_KEY][name1]["value"].as_string());
EXPECT_EQ(value2, int(asNode[EXPECTED_DATA_KEY][name2]["value"].as_double()));
EXPECT_EQ(tags1[0], asNode[EXPECTED_DATA_KEY][name1]["tags"][0].as_string());
EXPECT_EQ(tags2[0], asNode[EXPECTED_DATA_KEY][name2]["tags"][0].as_string());
}

TEST_F(AdiakWriterTest, scalar_types) {
std::string name1 = "my_long";
long value1 = 0;
std::string name2 = "my_double";
double value2 = 3.14;
auto result1 = adiak::value(name1, value1);
auto result2 = adiak::value(name2, value2);
EXPECT_TRUE(result1 && result2);
auto asNode = record.toNode();
EXPECT_EQ(value1, asNode[EXPECTED_DATA_KEY][name1]["value"].as_float64());
EXPECT_EQ(value2, asNode[EXPECTED_DATA_KEY][name2]["value"].as_double());
}

// No extra test for string_types (besides date) as they're handled identically
TEST_F(AdiakWriterTest, date_type) {
std::string name1 = "my_date";
auto result = adiak::value(name1, adiak::date(1568397849));
EXPECT_TRUE(result);
auto toNode = record.toNode();
EXPECT_EQ("Fri, 13 Sep 2019 11:04:09 -0700", toNode[EXPECTED_DATA_KEY][name1]["value"].as_string());
}

TEST_F(AdiakWriterTest, list_types) {
std::string name1 = "my_scalar_list";
std::vector<double> value1{4.5, 0, 5.12, 42};
std::string name2 = "my_string_list";
std::set<std::string> value2{"spam", "egg and bacon", "egg and spam"};
auto result1 = adiak::value(name1, value1);
auto result2 = adiak::value(name2, value2);
EXPECT_TRUE(result1 && result2);
auto asNode = record.toNode();
auto doub_array = asNode[EXPECTED_DATA_KEY][name1]["value"].as_double_ptr();
std::vector<double>scal_child_vals(doub_array, doub_array+asNode[EXPECTED_DATA_KEY][name1]["value"].dtype().number_of_elements());
EXPECT_EQ(value1, scal_child_vals);
std::set<std::string> node_vals;
auto val_itr = asNode[EXPECTED_DATA_KEY][name2]["value"].children();
while(val_itr.has_next())
node_vals.insert(val_itr.next().as_string());
EXPECT_EQ(value2, node_vals);
}

TEST_F(AdiakWriterTest, files) {
std::string name1 = "my_bash";
std::string value1 = "/bin/bash";
std::string name2 = "my_cat_pics";
std::string value2 = "~/pictures/neighbor_cat.png";
std::vector<std::string> tags2{name2};
auto result1 = adiak::value(name1, adiak::path(value1));
auto result2 = adiak::value(name2, adiak::path(value2));
EXPECT_TRUE(result1 && result2);
auto asNode = record.toNode();
EXPECT_FALSE(asNode[EXPECTED_FILES_KEY].child(value1).dtype().is_empty());
EXPECT_EQ(1, asNode[EXPECTED_FILES_KEY].child(value2)["tags"].number_of_children());
EXPECT_EQ(tags2[0], asNode[EXPECTED_FILES_KEY].child(value2)["tags"][0].as_string());
}

TEST_F(AdiakWriterTest, files_list){
std::string fileListName = "my_gecko_pics";
std::string fileListVal1 = "~/pictures/spike.png";
std::string fileListVal2 = "~/pictures/sandy.png";
std::vector<adiak::path> fileListAdiak{adiak::path(fileListVal1), adiak::path(fileListVal2)};
std::vector<std::string> tags = {"string"};
EXPECT_TRUE(adiak::value(fileListName, fileListAdiak));
auto asNode = record.toNode();
EXPECT_FALSE(asNode[EXPECTED_FILES_KEY].child(fileListVal1).dtype().is_empty());
EXPECT_EQ(1, asNode[EXPECTED_FILES_KEY].child(fileListVal2)["tags"].number_of_children());
EXPECT_EQ(fileListName, asNode[EXPECTED_FILES_KEY].child(fileListVal2)["tags"][0].as_string());
}

} // end nameless namespace
} // end testing namespace
} // end sina namespace
} // end axom namespace

#endif // AXOM_SINA_USE_ADIAK
Loading