blob: bf5ba7b53f7c8793f33577814b899002cf8b3e44 [file] [log] [blame]
// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/performance_manager/graph/node_inline_data.h"
#include <string>
#include "base/test/gtest_util.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace performance_manager {
template <class T>
struct DataWithDefaultCtor : public NodeInlineData<DataWithDefaultCtor<T>> {
T value = {};
};
template <class T>
struct DataWithExplicitCtor : public NodeInlineData<DataWithExplicitCtor<T>> {
explicit DataWithExplicitCtor(T value) : value(std::move(value)) {}
T value;
};
template <class T>
struct SparseDataWithDefaultCtor
: public SparseNodeInlineData<SparseDataWithDefaultCtor<T>> {
T value = {};
};
template <class T>
struct SparseDataWithExplicitCtor
: public SparseNodeInlineData<SparseDataWithExplicitCtor<T>> {
explicit SparseDataWithExplicitCtor(T value) : value(std::move(value)) {}
T value;
};
template <class... Args>
class DummyTestSupportsNodeInlineData : public SupportsNodeInlineData<Args...> {
public:
// Expose DestroyNodeInlineDataStorage().
using SupportsNodeInlineData<Args...>::DestroyNodeInlineDataStorage;
};
TEST(NodeInlineDataTest, MustCreateStorage) {
using TestType = DataWithDefaultCtor<int>;
DummyTestSupportsNodeInlineData<TestType> test_supports_node_data;
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
TestType::Create(&test_supports_node_data); // Does not check.
EXPECT_TRUE(TestType::Exists(&test_supports_node_data));
test_supports_node_data.DestroyNodeInlineDataStorage();
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
}
template <class... Args>
class TestSupportsNodeInlineData : public SupportsNodeInlineData<Args...> {
public:
TestSupportsNodeInlineData() = default;
~TestSupportsNodeInlineData() override {
SupportsNodeInlineData<Args...>::DestroyNodeInlineDataStorage();
}
};
const int kTestIntValue1 = 42;
const int kTestIntValue2 = 2024;
const double kTestDoubleValue1 = 91.0;
const double kTestDoubleValue2 = 1024.0;
const char* kTestStringValue1 = "non-default value";
const char* kTestStringValue2 = "other non-default value";
TEST(NodeInlineDataDeathTest, NonSparseDefaultCtor) {
using TestType = DataWithDefaultCtor<std::string>;
TestSupportsNodeInlineData<TestType> test_supports_node_data;
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
EXPECT_CHECK_DEATH({ TestType::Get(&test_supports_node_data); });
TestType& test_data = TestType::Create(&test_supports_node_data);
EXPECT_TRUE(test_data.value.empty());
test_data.value = kTestStringValue1;
EXPECT_EQ(TestType::Get(&test_supports_node_data).value, kTestStringValue1);
TestType::Destroy(&test_supports_node_data);
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
}
TEST(NodeInlineDataDeathTest, NonSparseExplicitCtor) {
using TestType = DataWithExplicitCtor<std::string>;
TestSupportsNodeInlineData<TestType> test_supports_node_data;
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
EXPECT_CHECK_DEATH({ TestType::Get(&test_supports_node_data); });
TestType& test_data =
TestType::Create(&test_supports_node_data, kTestStringValue1);
EXPECT_TRUE(TestType::Exists(&test_supports_node_data));
EXPECT_EQ(test_data.value, kTestStringValue1);
test_data.value.clear();
EXPECT_EQ(TestType::Get(&test_supports_node_data).value, "");
TestType::Destroy(&test_supports_node_data);
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
}
TEST(NodeInlineDataDeathTest, SparseTypeWithDefaultCtor) {
using TestType = SparseDataWithDefaultCtor<std::string>;
TestSupportsNodeInlineData<TestType> test_supports_node_data;
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
EXPECT_CHECK_DEATH({ TestType::Get(&test_supports_node_data); });
TestType& test_data = TestType::Create(&test_supports_node_data);
EXPECT_TRUE(TestType::Exists(&test_supports_node_data));
EXPECT_EQ(test_data.value, "");
test_data.value = kTestStringValue1;
EXPECT_EQ(TestType::Get(&test_supports_node_data).value, kTestStringValue1);
TestType::Destroy(&test_supports_node_data);
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
}
TEST(NodeInlineDataDeathTest, SparseTypeWithExplicitCtor) {
using TestType = SparseDataWithExplicitCtor<std::string>;
TestSupportsNodeInlineData<TestType> test_supports_node_data;
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
EXPECT_CHECK_DEATH({ TestType::Get(&test_supports_node_data); });
TestType& test_data =
TestType::Create(&test_supports_node_data, kTestStringValue1);
EXPECT_TRUE(TestType::Exists(&test_supports_node_data));
EXPECT_EQ(test_data.value, kTestStringValue1);
test_data.value.clear();
EXPECT_EQ(TestType::Get(&test_supports_node_data).value, "");
TestType::Destroy(&test_supports_node_data);
EXPECT_FALSE(TestType::Exists(&test_supports_node_data));
}
TEST(NodeInlineDataTest, MixMultipleTypesSameStorage) {
using TestTypeInt = DataWithExplicitCtor<int>;
using TestTypeDouble = DataWithExplicitCtor<double>;
using TestTypeString = DataWithExplicitCtor<std::string>;
TestSupportsNodeInlineData<TestTypeInt, TestTypeDouble, TestTypeString>
test_supports_node_data;
EXPECT_FALSE(TestTypeInt::Exists(&test_supports_node_data));
EXPECT_FALSE(TestTypeDouble::Exists(&test_supports_node_data));
EXPECT_FALSE(TestTypeString::Exists(&test_supports_node_data));
TestTypeInt& test_type_int =
TestTypeInt::Create(&test_supports_node_data, kTestIntValue1);
EXPECT_TRUE(TestTypeInt::Exists(&test_supports_node_data));
EXPECT_FALSE(TestTypeDouble::Exists(&test_supports_node_data));
EXPECT_FALSE(TestTypeString::Exists(&test_supports_node_data));
TestTypeDouble& test_type_double =
TestTypeDouble::Create(&test_supports_node_data, kTestDoubleValue1);
EXPECT_TRUE(TestTypeInt::Exists(&test_supports_node_data));
EXPECT_TRUE(TestTypeDouble::Exists(&test_supports_node_data));
EXPECT_FALSE(TestTypeString::Exists(&test_supports_node_data));
TestTypeString& test_type_string =
TestTypeString::Create(&test_supports_node_data, kTestStringValue1);
EXPECT_TRUE(TestTypeInt::Exists(&test_supports_node_data));
EXPECT_TRUE(TestTypeDouble::Exists(&test_supports_node_data));
EXPECT_TRUE(TestTypeString::Exists(&test_supports_node_data));
EXPECT_EQ(test_type_int.value, kTestIntValue1);
EXPECT_EQ(test_type_double.value, kTestDoubleValue1);
EXPECT_EQ(test_type_string.value, kTestStringValue1);
test_type_int.value = kTestIntValue2;
test_type_double.value = kTestDoubleValue2;
test_type_string.value = kTestStringValue2;
EXPECT_EQ(TestTypeInt::Get(&test_supports_node_data).value, kTestIntValue2);
EXPECT_EQ(TestTypeDouble::Get(&test_supports_node_data).value,
kTestDoubleValue2);
EXPECT_EQ(TestTypeString::Get(&test_supports_node_data).value,
kTestStringValue2);
TestTypeInt::Destroy(&test_supports_node_data);
EXPECT_FALSE(TestTypeInt::Exists(&test_supports_node_data));
EXPECT_TRUE(TestTypeDouble::Exists(&test_supports_node_data));
EXPECT_TRUE(TestTypeString::Exists(&test_supports_node_data));
TestTypeDouble::Destroy(&test_supports_node_data);
EXPECT_FALSE(TestTypeInt::Exists(&test_supports_node_data));
EXPECT_FALSE(TestTypeDouble::Exists(&test_supports_node_data));
EXPECT_TRUE(TestTypeString::Exists(&test_supports_node_data));
TestTypeString::Destroy(&test_supports_node_data);
EXPECT_FALSE(TestTypeInt::Exists(&test_supports_node_data));
EXPECT_FALSE(TestTypeDouble::Exists(&test_supports_node_data));
EXPECT_FALSE(TestTypeString::Exists(&test_supports_node_data));
}
TEST(NodeInlineDataTest, MixMultipleTypesDifferentStorage) {
using NonSparseTestType = DataWithExplicitCtor<int>;
using SparseTestType = SparseDataWithExplicitCtor<double>;
TestSupportsNodeInlineData<NonSparseTestType, SparseTestType>
test_supports_node_data;
EXPECT_FALSE(NonSparseTestType::Exists(&test_supports_node_data));
EXPECT_FALSE(SparseTestType::Exists(&test_supports_node_data));
NonSparseTestType& non_sparse_test_type =
NonSparseTestType::Create(&test_supports_node_data, kTestIntValue1);
SparseTestType& sparse_test_type =
SparseTestType::Create(&test_supports_node_data, kTestDoubleValue1);
EXPECT_TRUE(NonSparseTestType::Exists(&test_supports_node_data));
EXPECT_TRUE(SparseTestType::Exists(&test_supports_node_data));
EXPECT_EQ(non_sparse_test_type.value, kTestIntValue1);
EXPECT_EQ(sparse_test_type.value, kTestDoubleValue1);
non_sparse_test_type.value = kTestIntValue2;
sparse_test_type.value = kTestDoubleValue2;
EXPECT_EQ(NonSparseTestType::Get(&test_supports_node_data).value,
kTestIntValue2);
EXPECT_EQ(SparseTestType::Get(&test_supports_node_data).value,
kTestDoubleValue2);
SparseTestType::Destroy(&test_supports_node_data);
EXPECT_TRUE(NonSparseTestType::Exists(&test_supports_node_data));
EXPECT_FALSE(SparseTestType::Exists(&test_supports_node_data));
}
} // namespace performance_manager