1 /**
2  * Copyright © 2019 IBM Corporation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "extensions/openpower-pels/stream.hpp"
17 
18 #include <iostream>
19 
20 #include <gtest/gtest.h>
21 
22 using namespace openpower::pels;
23 
24 TEST(StreamTest, TestExtract)
25 {
26     std::vector<uint8_t> data{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
27                               0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
28                               0x08, 'h',  'e',  'l',  'l',  'o'};
29     Stream stream{data};
30 
31     {
32         uint8_t v;
33         stream >> v;
34         EXPECT_EQ(v, 0x11);
35     }
36     {
37         uint16_t v;
38         stream >> v;
39         EXPECT_EQ(v, 0x2233);
40     }
41     {
42         uint32_t v;
43         stream >> v;
44         EXPECT_EQ(v, 0x44556677);
45     }
46     {
47         uint64_t v;
48         stream >> v;
49         EXPECT_EQ(v, 0x0102030405060708);
50     }
51     {
52         char v[6] = {0};
53         stream.read(v, 5);
54         EXPECT_EQ(memcmp(v, "hello", 5), 0);
55     }
56 
57     EXPECT_EQ(stream.remaining(), 0);
58 
59     // At the end, so should throw.
60     uint8_t v;
61     EXPECT_THROW(stream >> v, std::out_of_range);
62 }
63 
64 TEST(StreamTest, InputTestNoExpansion)
65 {
66     std::vector<uint8_t> data(256, 0);
67     Stream stream(data);
68     uint8_t v1 = 0x11;
69     uint16_t v2 = 0x2233;
70     uint64_t v3 = 0x445566778899AABB;
71     uint32_t v4 = 0xCCDDEEFF;
72 
73     stream << v3 << v2 << v4 << v1;
74 
75     uint8_t e1;
76     uint16_t e2;
77     uint64_t e3;
78     uint32_t e4;
79 
80     stream.offset(0);
81     stream >> e3 >> e2 >> e4 >> e1;
82 
83     EXPECT_EQ(v1, e1);
84     EXPECT_EQ(v2, e2);
85     EXPECT_EQ(v3, e3);
86     EXPECT_EQ(v4, e4);
87 }
88 
89 TEST(StreamTest, InputTestExpansion)
90 {
91     // The stream will expand the underlying vector
92     std::vector<uint8_t> data;
93     Stream stream(data);
94 
95     uint32_t v1 = 0xAABBCCDD;
96     stream << v1;
97 
98     stream.offset(0);
99     uint32_t e1;
100     stream >> e1;
101     EXPECT_EQ(data.size(), 4);
102     EXPECT_EQ(v1, e1);
103 
104     stream.offset(2);
105 
106     uint64_t v2 = 0x0102030405060708;
107     stream << v2;
108 
109     EXPECT_EQ(data.size(), 10);
110     uint64_t e2;
111     stream.offset(2);
112     stream >> e2;
113 
114     EXPECT_EQ(v2, e2);
115 
116     auto origSize = data.size();
117     uint8_t v3 = 0xCC;
118     stream << v3;
119 
120     EXPECT_EQ(origSize + 1, data.size());
121     stream.offset(stream.offset() - 1);
122     uint8_t e3;
123     stream >> e3;
124     EXPECT_EQ(v3, e3);
125 }
126 
127 TEST(StreamTest, ReadWriteTest)
128 {
129     std::vector<uint8_t> data{0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
130                               0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc};
131     Stream stream{data};
132 
133     auto buf = decltype(data)(data.size());
134     ASSERT_EQ(data.size(), buf.size());
135 
136     stream.read(buf.data(), buf.size());
137 
138     for (size_t i = 0; i < data.size(); i++)
139     {
140         EXPECT_EQ(buf[i], data[i]);
141 
142         // for the next test
143         buf[i] = 0x20 + i;
144     }
145 
146     stream.offset(6);
147     stream.write(buf.data(), 6);
148     for (size_t i = 0; i < 6; i++)
149     {
150         EXPECT_EQ(buf[i], data[i + 6]);
151     }
152 }
153 
154 TEST(StreamTest, TestOffsets)
155 {
156     std::vector<uint8_t> data{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
157     Stream stream{data, 3};
158 
159     {
160         uint8_t v;
161         stream >> v;
162         EXPECT_EQ(v, 0x44);
163         EXPECT_EQ(stream.offset(), 4);
164     }
165 
166     stream.offset(6);
167 
168     {
169         uint8_t v;
170         stream >> v;
171         EXPECT_EQ(v, 0x77);
172         EXPECT_EQ(stream.offset(), 7);
173         EXPECT_EQ(stream.remaining(), 0);
174     }
175 
176     EXPECT_THROW(stream.offset(100), std::out_of_range);
177 }
178 
179 TEST(StreamTest, TestVectorInsertExtract)
180 {
181     std::vector<uint8_t> toInsert{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
182     std::vector<uint8_t> data;
183 
184     // Insert
185     Stream stream{data};
186     stream << toInsert;
187     EXPECT_EQ(data, toInsert);
188 
189     // Extract
190     std::vector<uint8_t> toExtract;
191     toExtract.resize(toInsert.size());
192     stream.offset(0);
193     stream >> toExtract;
194 
195     EXPECT_EQ(data, toExtract);
196 
197     // Go off the end
198     EXPECT_THROW(stream >> toExtract, std::out_of_range);
199 }
200