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