1 /*
2 * Copyright (C) 2019 The Android Open Source Project
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
17 #include "patch_utils.h"
18
19 #include <android-base/file.h>
20 #include <gtest/gtest.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <sstream>
24 #include <string>
25
26 #include <google/protobuf/util/message_differencer.h>
27
28 #include "adb_io.h"
29 #include "sysdeps.h"
30
31 using namespace com::android::fastdeploy;
32 using google::protobuf::util::MessageDifferencer;
33
GetTestFile(const std::string & name)34 static std::string GetTestFile(const std::string& name) {
35 return "fastdeploy/testdata/" + name;
36 }
37
FileMatchesContent(android::base::borrowed_fd input,const char * contents,ssize_t contentsSize)38 bool FileMatchesContent(android::base::borrowed_fd input, const char* contents,
39 ssize_t contentsSize) {
40 adb_lseek(input, 0, SEEK_SET);
41 // Use a temp buffer larger than any test contents.
42 constexpr int BUFFER_SIZE = 2048;
43 char buffer[BUFFER_SIZE];
44 bool result = true;
45 // Validate size of files is equal.
46 ssize_t readAmount = adb_read(input, buffer, BUFFER_SIZE);
47 EXPECT_EQ(readAmount, contentsSize);
48 result = memcmp(buffer, contents, readAmount) == 0;
49 for (int i = 0; i < readAmount; i++) {
50 printf("%x", buffer[i]);
51 }
52 printf(" == ");
53 for (int i = 0; i < contentsSize; i++) {
54 printf("%x", contents[i]);
55 }
56 printf("\n");
57
58 return result;
59 }
60
TEST(PatchUtilsTest,SwapLongWrites)61 TEST(PatchUtilsTest, SwapLongWrites) {
62 TemporaryFile output;
63 PatchUtils::WriteLong(0x0011223344556677, output.fd);
64 adb_lseek(output.fd, 0, SEEK_SET);
65 const char expected[] = {0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00};
66 EXPECT_TRUE(FileMatchesContent(output.fd, expected, 8));
67 }
68
TEST(PatchUtilsTest,PipeWritesAmountToOutput)69 TEST(PatchUtilsTest, PipeWritesAmountToOutput) {
70 std::string expected("Some Data");
71 TemporaryFile input;
72 TemporaryFile output;
73 // Populate input file.
74 WriteFdExactly(input.fd, expected);
75 adb_lseek(input.fd, 0, SEEK_SET);
76 // Open input file for read, and output file for write.
77 PatchUtils::Pipe(input.fd, output.fd, expected.size());
78 // Validate pipe worked
79 EXPECT_TRUE(FileMatchesContent(output.fd, expected.c_str(), expected.size()));
80 }
81
TEST(PatchUtilsTest,SignatureConstMatches)82 TEST(PatchUtilsTest, SignatureConstMatches) {
83 std::string apkFile = GetTestFile("rotating_cube-release.apk");
84 TemporaryFile output;
85 PatchUtils::WriteSignature(output.fd);
86 std::string contents("FASTDEPLOY");
87 EXPECT_TRUE(FileMatchesContent(output.fd, contents.c_str(), contents.size()));
88 }
89
TEST(PatchUtilsTest,GatherMetadata)90 TEST(PatchUtilsTest, GatherMetadata) {
91 std::string apkFile = GetTestFile("rotating_cube-release.apk");
92 APKMetaData actual = PatchUtils::GetHostAPKMetaData(apkFile.c_str());
93
94 std::string expectedMetadata;
95 android::base::ReadFileToString(GetTestFile("rotating_cube-metadata-release.data"),
96 &expectedMetadata);
97 APKMetaData expected;
98 EXPECT_TRUE(expected.ParseFromString(expectedMetadata));
99
100 // Test paths might vary.
101 expected.set_absolute_path(actual.absolute_path());
102
103 std::string actualMetadata;
104 actual.SerializeToString(&actualMetadata);
105
106 expected.SerializeToString(&expectedMetadata);
107
108 EXPECT_EQ(expectedMetadata, actualMetadata);
109 }
110
sanitize(APKMetaData & metadata)111 static inline void sanitize(APKMetaData& metadata) {
112 metadata.clear_absolute_path();
113 for (auto&& entry : *metadata.mutable_entries()) {
114 entry.clear_datasize();
115 }
116 }
117
TEST(PatchUtilsTest,GatherDumpMetadata)118 TEST(PatchUtilsTest, GatherDumpMetadata) {
119 APKMetaData hostMetadata;
120 APKMetaData deviceMetadata;
121
122 hostMetadata = PatchUtils::GetHostAPKMetaData(GetTestFile("sample.apk").c_str());
123
124 {
125 std::string cd;
126 android::base::ReadFileToString(GetTestFile("sample.cd"), &cd);
127
128 APKDump dump;
129 dump.set_cd(std::move(cd));
130
131 deviceMetadata = PatchUtils::GetDeviceAPKMetaData(dump);
132 }
133
134 sanitize(hostMetadata);
135 sanitize(deviceMetadata);
136
137 std::string expectedMetadata;
138 hostMetadata.SerializeToString(&expectedMetadata);
139
140 std::string actualMetadata;
141 deviceMetadata.SerializeToString(&actualMetadata);
142
143 EXPECT_EQ(expectedMetadata, actualMetadata);
144 }
145