summaryrefslogtreecommitdiff
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 @@
1add_executable(tests 1add_executable(tests
2 common/param_package.cpp 2 common/param_package.cpp
3 common/ring_buffer.cpp
3 core/arm/arm_test_common.cpp 4 core/arm/arm_test_common.cpp
4 core/arm/arm_test_common.h 5 core/arm/arm_test_common.h
5 core/core_timing.cpp 6 core/core_timing.cpp
6 glad.cpp
7 tests.cpp 7 tests.cpp
8) 8)
9 9
10create_target_directory_groups(tests) 10create_target_directory_groups(tests)
11 11
12target_link_libraries(tests PRIVATE common core) 12target_link_libraries(tests PRIVATE common core)
13target_link_libraries(tests PRIVATE glad) # To support linker work-around
14target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads) 13target_link_libraries(tests PRIVATE ${PLATFORM_LIBRARIES} catch-single-include Threads::Threads)
15 14
16add_test(NAME tests COMMAND tests) 15add_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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include <array>
7#include <cstddef>
8#include <numeric>
9#include <thread>
10#include <vector>
11#include <catch2/catch.hpp>
12#include "common/ring_buffer.h"
13
14namespace Common {
15
16TEST_CASE("RingBuffer: Basic Tests", "[common]") {
17 RingBuffer<char, 4, 1> buf;
18
19 // Pushing values into a ring buffer with space should succeed.
20 for (std::size_t i = 0; i < 4; i++) {
21 const char elem = static_cast<char>(i);
22 const std::size_t count = buf.Push(&elem, 1);
23 REQUIRE(count == 1);
24 }
25
26 REQUIRE(buf.Size() == 4);
27
28 // Pushing values into a full ring buffer should fail.
29 {
30 const char elem = static_cast<char>(42);
31 const std::size_t count = buf.Push(&elem, 1);
32 REQUIRE(count == 0);
33 }
34
35 REQUIRE(buf.Size() == 4);
36
37 // Popping multiple values from a ring buffer with values should succeed.
38 {
39 const std::vector<char> popped = buf.Pop(2);
40 REQUIRE(popped.size() == 2);
41 REQUIRE(popped[0] == 0);
42 REQUIRE(popped[1] == 1);
43 }
44
45 REQUIRE(buf.Size() == 2);
46
47 // Popping a single value from a ring buffer with values should succeed.
48 {
49 const std::vector<char> popped = buf.Pop(1);
50 REQUIRE(popped.size() == 1);
51 REQUIRE(popped[0] == 2);
52 }
53
54 REQUIRE(buf.Size() == 1);
55
56 // Pushing more values than space available should partially suceed.
57 {
58 std::vector<char> to_push(6);
59 std::iota(to_push.begin(), to_push.end(), 88);
60 const std::size_t count = buf.Push(to_push);
61 REQUIRE(count == 3);
62 }
63
64 REQUIRE(buf.Size() == 4);
65
66 // Doing an unlimited pop should pop all values.
67 {
68 const std::vector<char> popped = buf.Pop();
69 REQUIRE(popped.size() == 4);
70 REQUIRE(popped[0] == 3);
71 REQUIRE(popped[1] == 88);
72 REQUIRE(popped[2] == 89);
73 REQUIRE(popped[3] == 90);
74 }
75
76 REQUIRE(buf.Size() == 0);
77}
78
79TEST_CASE("RingBuffer: Threaded Test", "[common]") {
80 RingBuffer<char, 4, 2> buf;
81 const char seed = 42;
82 const std::size_t count = 1000000;
83 std::size_t full = 0;
84 std::size_t empty = 0;
85
86 const auto next_value = [](std::array<char, 2>& value) {
87 value[0] += 1;
88 value[1] += 2;
89 };
90
91 std::thread producer{[&] {
92 std::array<char, 2> value = {seed, seed};
93 std::size_t i = 0;
94 while (i < count) {
95 if (const std::size_t c = buf.Push(&value[0], 1); c > 0) {
96 REQUIRE(c == 1);
97 i++;
98 next_value(value);
99 } else {
100 full++;
101 std::this_thread::yield();
102 }
103 }
104 }};
105
106 std::thread consumer{[&] {
107 std::array<char, 2> value = {seed, seed};
108 std::size_t i = 0;
109 while (i < count) {
110 if (const std::vector<char> v = buf.Pop(1); v.size() > 0) {
111 REQUIRE(v.size() == 2);
112 REQUIRE(v[0] == value[0]);
113 REQUIRE(v[1] == value[1]);
114 i++;
115 next_value(value);
116 } else {
117 empty++;
118 std::this_thread::yield();
119 }
120 }
121 }};
122
123 producer.join();
124 consumer.join();
125
126 REQUIRE(buf.Size() == 0);
127 printf("RingBuffer: Threaded Test: full: %zu, empty: %zu\n", full, empty);
128}
129
130} // 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) {
87 return *Read32(addr) | static_cast<u64>(*Read32(addr + 4)) << 32; 87 return *Read32(addr) | static_cast<u64>(*Read32(addr + 4)) << 32;
88} 88}
89 89
90bool TestEnvironment::TestMemory::ReadBlock(VAddr src_addr, void* dest_buffer, size_t size) { 90bool TestEnvironment::TestMemory::ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) {
91 VAddr addr = src_addr; 91 VAddr addr = src_addr;
92 u8* data = static_cast<u8*>(dest_buffer); 92 u8* data = static_cast<u8*>(dest_buffer);
93 93
94 for (size_t i = 0; i < size; i++, addr++, data++) { 94 for (std::size_t i = 0; i < size; i++, addr++, data++) {
95 *data = *Read8(addr); 95 *data = *Read8(addr);
96 } 96 }
97 97
@@ -126,11 +126,12 @@ bool TestEnvironment::TestMemory::Write64(VAddr addr, u64 data) {
126 return true; 126 return true;
127} 127}
128 128
129bool TestEnvironment::TestMemory::WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size) { 129bool TestEnvironment::TestMemory::WriteBlock(VAddr dest_addr, const void* src_buffer,
130 std::size_t size) {
130 VAddr addr = dest_addr; 131 VAddr addr = dest_addr;
131 const u8* data = static_cast<const u8*>(src_buffer); 132 const u8* data = static_cast<const u8*>(src_buffer);
132 133
133 for (size_t i = 0; i < size; i++, addr++, data++) { 134 for (std::size_t i = 0; i < size; i++, addr++, data++) {
134 env->write_records.emplace_back(8, addr, *data); 135 env->write_records.emplace_back(8, addr, *data);
135 if (env->mutable_memory) 136 if (env->mutable_memory)
136 env->SetMemory8(addr, *data); 137 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;
19namespace ArmTests { 19namespace ArmTests {
20 20
21struct WriteRecord { 21struct WriteRecord {
22 WriteRecord(size_t size, VAddr addr, u64 data) : size(size), addr(addr), data(data) {} 22 WriteRecord(std::size_t size, VAddr addr, u64 data) : size(size), addr(addr), data(data) {}
23 size_t size; 23 std::size_t size;
24 VAddr addr; 24 VAddr addr;
25 u64 data; 25 u64 data;
26 bool operator==(const WriteRecord& o) const { 26 bool operator==(const WriteRecord& o) const {
@@ -71,14 +71,14 @@ private:
71 boost::optional<u32> Read32(VAddr addr) override; 71 boost::optional<u32> Read32(VAddr addr) override;
72 boost::optional<u64> Read64(VAddr addr) override; 72 boost::optional<u64> Read64(VAddr addr) override;
73 73
74 bool ReadBlock(VAddr src_addr, void* dest_buffer, size_t size) override; 74 bool ReadBlock(VAddr src_addr, void* dest_buffer, std::size_t size) override;
75 75
76 bool Write8(VAddr addr, u8 data) override; 76 bool Write8(VAddr addr, u8 data) override;
77 bool Write16(VAddr addr, u16 data) override; 77 bool Write16(VAddr addr, u16 data) override;
78 bool Write32(VAddr addr, u32 data) override; 78 bool Write32(VAddr addr, u32 data) override;
79 bool Write64(VAddr addr, u64 data) override; 79 bool Write64(VAddr addr, u64 data) override;
80 80
81 bool WriteBlock(VAddr dest_addr, const void* src_buffer, size_t size) override; 81 bool WriteBlock(VAddr dest_addr, const void* src_buffer, std::size_t size) override;
82 82
83 std::unordered_map<VAddr, u8> data; 83 std::unordered_map<VAddr, u8> data;
84 }; 84 };
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 @@
1// Copyright 2016 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <catch2/catch.hpp>
6#include <glad/glad.h>
7
8// This is not an actual test, but a work-around for issue #2183.
9// If tests uses functions in core but doesn't explicitly use functions in glad, the linker of macOS
10// will error about undefined references from video_core to glad. So we explicitly use a glad
11// function here to shut up the linker.
12TEST_CASE("glad fake test", "[dummy]") {
13 REQUIRE(&gladLoadGL != nullptr);
14}