1 | #include "test.h" |
2 | #include <gtest/gtest.h> |
3 | |
4 | #include <base/system.h> |
5 | |
6 | static const int BUF_SIZE = 64 * 1024; |
7 | |
8 | class Async : public ::testing::Test |
9 | { |
10 | protected: |
11 | ASYNCIO *m_pAio; |
12 | CTestInfo m_Info; |
13 | bool Delete; |
14 | |
15 | void SetUp() override |
16 | { |
17 | IOHANDLE File = io_open(filename: m_Info.m_aFilename, flags: IOFLAG_WRITE); |
18 | ASSERT_TRUE(File); |
19 | m_pAio = aio_new(io: File); |
20 | Delete = false; |
21 | } |
22 | |
23 | ~Async() |
24 | { |
25 | if(Delete) |
26 | { |
27 | fs_remove(filename: m_Info.m_aFilename); |
28 | } |
29 | } |
30 | |
31 | void Write(const char *pText) |
32 | { |
33 | aio_write(aio: m_pAio, buffer: pText, size: str_length(str: pText)); |
34 | } |
35 | |
36 | void Expect(const char *pOutput) |
37 | { |
38 | aio_close(aio: m_pAio); |
39 | aio_wait(aio: m_pAio); |
40 | aio_free(aio: m_pAio); |
41 | |
42 | char aBuf[BUF_SIZE]; |
43 | IOHANDLE File = io_open(filename: m_Info.m_aFilename, flags: IOFLAG_READ); |
44 | ASSERT_TRUE(File); |
45 | int Read = io_read(io: File, buffer: aBuf, size: sizeof(aBuf)); |
46 | io_close(io: File); |
47 | |
48 | ASSERT_EQ(str_length(pOutput), Read); |
49 | ASSERT_TRUE(mem_comp(aBuf, pOutput, Read) == 0); |
50 | Delete = true; |
51 | } |
52 | }; |
53 | |
54 | TEST_F(Async, Empty) |
55 | { |
56 | Expect(pOutput: "" ); |
57 | } |
58 | |
59 | TEST_F(Async, Simple) |
60 | { |
61 | static const char TEXT[] = "a\n" ; |
62 | Write(pText: TEXT); |
63 | Expect(pOutput: TEXT); |
64 | } |
65 | |
66 | TEST_F(Async, Long) |
67 | { |
68 | char aText[BUF_SIZE + 1]; |
69 | for(unsigned i = 0; i < sizeof(aText) - 1; i++) |
70 | { |
71 | aText[i] = 'a'; |
72 | } |
73 | aText[sizeof(aText) - 1] = 0; |
74 | Write(pText: aText); |
75 | Expect(pOutput: aText); |
76 | } |
77 | |
78 | TEST_F(Async, Pieces) |
79 | { |
80 | char aText[BUF_SIZE + 1]; |
81 | for(unsigned i = 0; i < sizeof(aText) - 1; i++) |
82 | { |
83 | aText[i] = 'a'; |
84 | } |
85 | aText[sizeof(aText) - 1] = 0; |
86 | for(unsigned i = 0; i < sizeof(aText) - 1; i++) |
87 | { |
88 | Write(pText: "a" ); |
89 | } |
90 | Expect(pOutput: aText); |
91 | } |
92 | |
93 | TEST_F(Async, Mixed) |
94 | { |
95 | char aText[BUF_SIZE + 1]; |
96 | for(unsigned i = 0; i < sizeof(aText) - 1; i++) |
97 | { |
98 | aText[i] = 'a' + i % 26; |
99 | } |
100 | aText[sizeof(aText) - 1] = 0; |
101 | for(unsigned i = 0; i < sizeof(aText) - 1; i++) |
102 | { |
103 | char w = 'a' + i % 26; |
104 | aio_write(aio: m_pAio, buffer: &w, size: 1); |
105 | } |
106 | Expect(pOutput: aText); |
107 | } |
108 | |
109 | TEST_F(Async, NonDivisor) |
110 | { |
111 | static const int NUM_LETTERS = 13; |
112 | static const int SIZE = BUF_SIZE / NUM_LETTERS * NUM_LETTERS; |
113 | char aText[SIZE + 1]; |
114 | for(unsigned i = 0; i < sizeof(aText) - 1; i++) |
115 | { |
116 | aText[i] = 'a' + i % NUM_LETTERS; |
117 | } |
118 | aText[sizeof(aText) - 1] = 0; |
119 | for(unsigned i = 0; i < (sizeof(aText) - 1) / NUM_LETTERS; i++) |
120 | { |
121 | Write(pText: "abcdefghijklm" ); |
122 | } |
123 | Expect(pOutput: aText); |
124 | } |
125 | |
126 | TEST_F(Async, Transaction) |
127 | { |
128 | static const int NUM_LETTERS = 13; |
129 | static const int SIZE = BUF_SIZE / NUM_LETTERS * NUM_LETTERS; |
130 | char aText[SIZE + 1]; |
131 | for(unsigned i = 0; i < sizeof(aText) - 1; i++) |
132 | { |
133 | aText[i] = 'a' + i % NUM_LETTERS; |
134 | } |
135 | aText[sizeof(aText) - 1] = 0; |
136 | for(unsigned i = 0; i < (sizeof(aText) - 1) / NUM_LETTERS; i++) |
137 | { |
138 | aio_lock(aio: m_pAio); |
139 | for(char c = 'a'; c < 'a' + NUM_LETTERS; c++) |
140 | { |
141 | aio_write_unlocked(aio: m_pAio, buffer: &c, size: 1); |
142 | } |
143 | aio_unlock(aio: m_pAio); |
144 | } |
145 | Expect(pOutput: aText); |
146 | } |
147 | |