1 // Copyright (C) 2017 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 #define DEBUG false 15 #include "Log.h" 16 17 #include <android-base/file.h> 18 #include <android/util/ProtoFileReader.h> 19 #include <android/util/ProtoOutputStream.h> 20 #include <android/util/protobuf.h> 21 #include <fcntl.h> 22 #include <gtest/gtest.h> 23 #include <signal.h> 24 #include <string.h> 25 26 #include "FdBuffer.h" 27 #include "incidentd_util.h" 28 29 using namespace android; 30 using namespace android::base; 31 using namespace android::os::incidentd; 32 using ::testing::Test; 33 34 const std::string kTestPath = GetExecutableDirectory(); 35 const std::string kTestDataPath = kTestPath + "/testdata/"; 36 37 status_t read(sp<ProtoFileReader> reader, size_t size) { 38 uint8_t const* buf; 39 while (size > 0 && (buf = reader->readBuffer()) != nullptr) { 40 size_t amt = reader->currentToRead(); 41 if (size < amt) { 42 amt = size; 43 } 44 reader->move(amt); 45 size -= amt; 46 } 47 48 return NO_ERROR; 49 } 50 51 TEST(ProtoFileReaderTest, ParseOneLevel) { 52 const std::string testFile = kTestDataPath + "protoFile.txt"; 53 size_t msg1Size = 10; 54 size_t msg2Size = 5 * 1024; 55 { 56 // Create a proto file 57 // TestProto { 58 // optional Section1 section1 = 1; 59 // optional Section2 section2 = 2; 60 // } 61 62 unique_fd fd(open(testFile.c_str(), O_WRONLY | O_CREAT | O_CLOEXEC, S_IRUSR | S_IWUSR)); 63 ASSERT_NE(fd.get(), -1); 64 ProtoOutputStream proto; 65 string field1; 66 field1.resize(msg1Size, 'h'); 67 string field2; 68 field2.resize(msg2Size, 'a'); 69 proto.write(FIELD_TYPE_MESSAGE | 1, field1.data(), field1.length()); 70 proto.write(FIELD_TYPE_MESSAGE | 2, field2.data(), field2.length()); 71 proto.flush(fd); 72 } 73 74 int fd = open(testFile.c_str(), O_RDONLY | O_CLOEXEC); 75 ASSERT_NE(fd, -1); 76 77 status_t err; 78 sp<ProtoFileReader> reader = new ProtoFileReader(fd); 79 int i = 0; 80 size_t msg_size[2]; 81 while (reader->hasNext()) { 82 uint64_t fieldTag = reader->readRawVarint(); 83 uint32_t fieldId = read_field_id(fieldTag); 84 uint8_t wireType = read_wire_type(fieldTag); 85 ASSERT_EQ(WIRE_TYPE_LENGTH_DELIMITED, wireType); 86 size_t sectionSize = reader->readRawVarint(); 87 if (i < 2) { 88 msg_size[i] = sectionSize; 89 } 90 err = read(reader, sectionSize); 91 ASSERT_EQ(NO_ERROR, err); 92 i++; 93 } 94 95 ASSERT_EQ(2, i); 96 97 ASSERT_EQ(msg1Size, msg_size[0]); 98 ASSERT_EQ(msg2Size, msg_size[1]); 99 close(fd); 100 } 101