summaryrefslogtreecommitdiffstats
path: root/src/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/CMakeLists.txt3
-rw-r--r--src/tests/common/ring_buffer.cpp130
-rw-r--r--src/tests/core/arm/arm_test_common.cpp9
-rw-r--r--src/tests/core/arm/arm_test_common.h8
-rw-r--r--src/tests/glad.cpp14
5 files changed, 140 insertions, 24 deletions
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 4d74bb395..37f09ce5f 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -1,16 +1,15 @@
add_executable(tests
common/param_package.cpp
+ common/ring_buffer.cpp
core/arm/arm_test_common.cpp
core/arm/arm_test_common.h
core/core_timing.cpp
- glad.cpp
tests.cpp
)
create_target_directory_groups(tests)
target_link_libraries(tests PRIVATE common core)
-target_link_libraries(tests PRIVATE glad) # To support linker work-around
target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads)
add_test(NAME tests COMMAND tests)
diff --git a/src/tests/common/ring_buffer.cpp b/src/tests/common/ring_buffer.cpp
new file mode 100644
index 000000000..c883c4d56
--- /dev/null
+++ b/src/tests/common/ring_buffer.cpp
@@ -0,0 +1,130 @@
+// Copyright 2018 yuzu emulator team
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include <algorithm>
+#include <array>
+#include <cstddef>
+#include <numeric>
+#include <thread>
+#include <vector>
+#include <catch2/catch.hpp>
+#include "common/ring_buffer.h"
+
+namespace Common {
+
+TEST_CASE("RingBuffer: Basic Tests", "[common]") {
+ RingBuffer<char, 4, 1> buf;
+
+ // Pushing values into a ring buffer with space should succeed.
+ for (std::size_t i = 0; i < 4; i++) {
+ const char elem = static_cast<char>(i);
+ const std::size_t count = buf.Push(&elem, 1);
+ REQUIRE(count == 1);
+ }
+
+ REQUIRE(buf.Size() == 4);
+
+ // Pushing values into a full ring buffer should fail.
+ {
+ const char elem = static_cast<char>(42);
+ const std::size_t count = buf.Push(&elem, 1);
+ REQUIRE(count == 0);
+ }
+
+ REQUIRE(buf.Size() == 4);
+
+ // Popping multiple values from a ring buffer with values should succeed.
+ {
+ const std::vector<char> popped = buf.Pop(2);
+ REQUIRE(popped.size() == 2);
+ REQUIRE(popped[0] == 0);
+ REQUIRE(popped[1] == 1);
+ }
+
+ REQUIRE(buf.Size() == 2);
+
+ // Popping a single value from a ring buffer with values should succeed.
+ {
+ const std::vector<char> popped = buf.Pop(1);
+ REQUIRE(popped.size() == 1);
+ REQUIRE(popped[0] == 2);
+ }
+
+ REQUIRE(buf.Size() == 1);
+
+ // Pushing more values than space available should partially suceed.
+ {
+ std::vector<char> to_push(6);
+ std::iota(to_push.begin(), to_push.end(), 88);
+ const std::size_t count = buf.Push(to_push);
+ REQUIRE(count == 3);
+ }
+
+ REQUIRE(buf.Size() == 4);
+
+ // Doing an unlimited pop should pop all values.
+ {
+ const std::vector<char> popped = buf.Pop();
+ REQUIRE(popped.size() == 4);
+ REQUIRE(popped[0] == 3);
+ REQUIRE(popped[1] == 88);
+ REQUIRE(popped[2] == 89);
+ REQUIRE(popped[3] == 90);
+ }
+
+ REQUIRE(buf.Size() == 0);
+}
+
+TEST_CASE("RingBuffer: Threaded Test", "[common]") {
+ RingBuffer<char, 4, 2> buf;
+ const char seed = 42;
+ const std::size_t count = 1000000;
+ std::size_t full = 0;
+ std::size_t empty = 0;
+
+ const auto next_value = [](std::array<char, 2>& value) {
+ value[0] += 1;
+ value[1] += 2;
+ };
+
+ std::thread producer{[&] {
+ std::array<char, 2> value = {seed, seed};
+ std::size_t i = 0;
+ while (i < count) {
+ if (const std::size_t c = buf.Push(&value[0], 1); c > 0) {
+ REQUIRE(c == 1);
+ i++;
+ next_value(value);
+ } else {
+ full++;
+ std::this_thread::yield();
+ }
+ }
+ }};
+
+ std::thread consumer{[&] {
+ std::array<char, 2> value = {seed, seed};
+ std::size_t i = 0;
+ while (i < count) {
+ if (const std::vector<char> v = buf.Pop(1); v.size() > 0) {
+ REQUIRE(v.size() == 2);
+ REQUIRE(v[0] == value[0]);
+ REQUIRE(v[1] == value[1]);
+ i++;
+ next_value(value);
+ } else {
+ empty++;
+ std::this_thread::yield();
+ }
+ }
+ }};
+
+ producer.join();
+ consumer.join();
+
+ REQUIRE(buf.Size() == 0);
+ printf("RingBuffer: Threaded Test: full: %zu, empty: %zu\n", full, empty);
+}
+
+} // namespace Common
diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp
index 038d57b3a..7c69fc26e 100644
--- a/src/tests/core/arm/arm_test_common.cpp
+++ b/src/tests/core/arm/arm_test_common.cpp
@@ -87,11 +87,11 @@ boost::optional<u64> TestEnvironment::TestMemory::Read64(VAddr addr) {
return *Read32(addr) | static_cast<u64>(*Read32(addr + 4)) << 32;
}
-bool TestEnvironment::TestMemory::ReadBlock(VAddr src_addr, void* dest_buffer, size_t size) {
+bool TestEnvironment::TestMemory::ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) {
VAddr addr = src_addr;
u8* data = static_cast<u8*>(dest_buffer);
- for (size_t i = 0; i < size; i++, addr++, data++) {
+ for (std::size_t i = 0; i < size; i++, addr++, data++) {
*data = *Read8(addr);
}
@@ -126,11 +126,12 @@ bool TestEnvironment::TestMemory::Write64(VAddr addr, u64 data) {
return true;
}
-bool TestEnvironment::TestMemory::WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size) {
+bool TestEnvironment::TestMemory::WriteBlock(VAddr dest_addr, const void* src_buffer,
+ std::size_t size) {
VAddr addr = dest_addr;
const u8* data = static_cast<const u8*>(src_buffer);
- for (size_t i = 0; i < size; i++, addr++, data++) {
+ for (std::size_t i = 0; i < size; i++, addr++, data++) {
env->write_records.emplace_back(8, addr, *data);
if (env->mutable_memory)
env->SetMemory8(addr, *data);
diff --git a/src/tests/core/arm/arm_test_common.h b/src/tests/core/arm/arm_test_common.h
index e4b6df194..5de8dab4e 100644
--- a/src/tests/core/arm/arm_test_common.h
+++ b/src/tests/core/arm/arm_test_common.h
@@ -19,8 +19,8 @@ struct PageTable;
namespace ArmTests {
struct WriteRecord {
- WriteRecord(size_t size, VAddr addr, u64 data) : size(size), addr(addr), data(data) {}
- size_t size;
+ WriteRecord(std::size_t size, VAddr addr, u64 data) : size(size), addr(addr), data(data) {}
+ std::size_t size;
VAddr addr;
u64 data;
bool operator==(const WriteRecord& o) const {
@@ -71,14 +71,14 @@ private:
boost::optional<u32> Read32(VAddr addr) override;
boost::optional<u64> Read64(VAddr addr) override;
- bool ReadBlock(VAddr src_addr, void* dest_buffer, size_t size) override;
+ bool ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) override;
bool Write8(VAddr addr, u8 data) override;
bool Write16(VAddr addr, u16 data) override;
bool Write32(VAddr addr, u32 data) override;
bool Write64(VAddr addr, u64 data) override;
- bool WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size) override;
+ bool WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size) override;
std::unordered_map<VAddr, u8> data;
};
diff --git a/src/tests/glad.cpp b/src/tests/glad.cpp
deleted file mode 100644
index 1797c0e3d..000000000
--- a/src/tests/glad.cpp
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2016 Citra Emulator Project
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <catch2/catch.hpp>
-#include <glad/glad.h>
-
-// This is not an actual test, but a work-around for issue #2183.
-// If tests uses functions in core but doesn't explicitly use functions in glad, the linker of macOS
-// will error about undefined references from video_core to glad. So we explicitly use a glad
-// function here to shut up the linker.
-TEST_CASE("glad fake test", "[dummy]") {
- REQUIRE(&gladLoadGL != nullptr);
-}