1 /******************************************************************************
2 *
3 * Copyright (C) 2014 Google, Inc.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 #include <gtest/gtest.h>
20
21 #include "AllocationTestHarness.h"
22
23 extern "C" {
24 #include <stdint.h>
25 #include <unistd.h>
26
27 #include "allocator.h"
28 #include "eager_reader.h"
29 #include "osi.h"
30 #include "semaphore.h"
31 #include "thread.h"
32 }
33
34 #define BUFFER_SIZE 32
35
36 static const char *small_data = "white chocolate lindor truffles";
37 static const char *large_data =
38 "Let him make him examine and thoroughly sift everything he reads, and "
39 "lodge nothing in his fancy upon simple authority and upon trust. "
40 "Aristotle's principles will then be no more principles to him, than those "
41 "of Epicurus and the Stoics: let this diversity of opinions be propounded "
42 "to, and laid before him; he will himself choose, if he be able; if not, "
43 "he will remain in doubt. "
44 ""
45 " \"Che non men the saver, dubbiar m' aggrata.\" "
46 " [\"I love to doubt, as well as to know.\"--Dante, Inferno, xi. 93] "
47 ""
48 "for, if he embrace the opinions of Xenophon and Plato, by his own reason, "
49 "they will no more be theirs, but become his own. Who follows another, "
50 "follows nothing, finds nothing, nay, is inquisitive after nothing. "
51 ""
52 " \"Non sumus sub rege; sibi quisque se vindicet.\" "
53 " [\"We are under no king; let each vindicate himself.\" --Seneca, Ep.,33] "
54 ""
55 "let him, at least, know that he knows. it will be necessary that he "
56 "imbibe their knowledge, not that he be corrupted with their precepts; "
57 "and no matter if he forget where he had his learning, provided he know "
58 "how to apply it to his own use. truth and reason are common to every "
59 "one, and are no more his who spake them first, than his who speaks them "
60 "after: 'tis no more according to plato, than according to me, since both "
61 "he and i equally see and understand them. bees cull their several sweets "
62 "from this flower and that blossom, here and there where they find them, "
63 "but themselves afterwards make the honey, which is all and purely their "
64 "own, and no more thyme and marjoram: so the several fragments he borrows "
65 "from others, he will transform and shuffle together to compile a work "
66 "that shall be absolutely his own; that is to say, his judgment: "
67 "his instruction, labour and study, tend to nothing else but to form that. ";
68
69 static semaphore_t *done;
70
71 class EagerReaderTest : public AllocationTestHarness {
72 protected:
SetUp()73 virtual void SetUp() {
74 AllocationTestHarness::SetUp();
75 pipe(pipefd);
76 done = semaphore_new(0);
77 }
78
TearDown()79 virtual void TearDown() {
80 semaphore_free(done);
81 AllocationTestHarness::TearDown();
82 }
83
84 int pipefd[2];
85 };
86
expect_data(eager_reader_t * reader,void * context)87 static void expect_data(eager_reader_t *reader, void *context) {
88 char *data = (char *)context;
89 int length = strlen(data);
90
91 for (int i = 0; i < length; i++) {
92 uint8_t byte;
93 EXPECT_EQ((size_t)1, eager_reader_read(reader, &byte, 1, true));
94 EXPECT_EQ(data[i], byte);
95 }
96
97 semaphore_post(done);
98 }
99
expect_data_multibyte(eager_reader_t * reader,void * context)100 static void expect_data_multibyte(eager_reader_t *reader, void *context) {
101 char *data = (char *)context;
102 int length = strlen(data);
103
104 for (int i = 0; i < length;) {
105 uint8_t buffer[28];
106 int bytes_to_read = (length - i) > 28 ? 28 : (length - i);
107 int bytes_read = eager_reader_read(reader, buffer, bytes_to_read, false);
108 EXPECT_EQ(bytes_to_read, bytes_read);
109 for (int j = 0; j < bytes_read && i < length; j++, i++) {
110 EXPECT_EQ(data[i], buffer[j]);
111 }
112 }
113
114 semaphore_post(done);
115 }
116
TEST_F(EagerReaderTest,test_new_free_simple)117 TEST_F(EagerReaderTest, test_new_free_simple) {
118 eager_reader_t *reader = eager_reader_new(pipefd[0], &allocator_malloc, BUFFER_SIZE, SIZE_MAX, "test_thread");
119 ASSERT_TRUE(reader != NULL);
120 eager_reader_free(reader);
121 }
122
TEST_F(EagerReaderTest,test_small_data)123 TEST_F(EagerReaderTest, test_small_data) {
124 eager_reader_t *reader = eager_reader_new(pipefd[0], &allocator_malloc, BUFFER_SIZE, SIZE_MAX, "test_thread");
125
126 thread_t *read_thread = thread_new("read_thread");
127 eager_reader_register(reader, thread_get_reactor(read_thread), expect_data, (void *)small_data);
128
129 write(pipefd[1], small_data, strlen(small_data));
130
131 semaphore_wait(done);
132 eager_reader_free(reader);
133 thread_free(read_thread);
134 }
135
TEST_F(EagerReaderTest,test_large_data_multibyte)136 TEST_F(EagerReaderTest, test_large_data_multibyte) {
137 eager_reader_t *reader = eager_reader_new(pipefd[0], &allocator_malloc, BUFFER_SIZE, SIZE_MAX, "test_thread");
138
139 thread_t *read_thread = thread_new("read_thread");
140 eager_reader_register(reader, thread_get_reactor(read_thread), expect_data_multibyte, (void *)large_data);
141
142 write(pipefd[1], large_data, strlen(large_data));
143
144 semaphore_wait(done);
145 eager_reader_free(reader);
146 thread_free(read_thread);
147 }
148