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