zip_archive_test.cc revision 58aaf46e4d3c9f6ada086f88ecf137a9e04db2d9
1/*
2 * Copyright (C) 2013 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 "ziparchive/zip_archive.h"
18
19#include "getopt.h"
20#include <stdio.h>
21#include <gtest/gtest.h>
22
23static std::string test_data_dir;
24
25static const std::string kValidZip = "valid.zip";
26
27static const uint8_t kATxtContents[] = {
28  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
29  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
30  '\n'
31};
32
33static const uint8_t kBTxtContents[] = {
34  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
35  '\n'
36};
37
38static int32_t OpenArchiveWrapper(const std::string& name,
39                                  ZipArchiveHandle* handle) {
40  const std::string abs_path = test_data_dir + "/" + name;
41  return OpenArchive(abs_path.c_str(), handle);
42}
43
44static void AssertNameEquals(const std::string& name_str,
45                             const ZipEntryName& name) {
46  ASSERT_EQ(name_str.size(), name.name_length);
47  ASSERT_EQ(0, memcmp(name_str.c_str(), name.name, name.name_length));
48}
49
50TEST(ziparchive, Open) {
51  ZipArchiveHandle handle;
52  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
53
54  CloseArchive(handle);
55}
56
57TEST(ziparchive, Iteration) {
58  ZipArchiveHandle handle;
59  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
60
61  void* iteration_cookie;
62  ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, NULL));
63
64  ZipEntry data;
65  ZipEntryName name;
66
67  // b/c.txt
68  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
69  AssertNameEquals("b/c.txt", name);
70
71  // b/d.txt
72  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
73  AssertNameEquals("b/d.txt", name);
74
75  // a.txt
76  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
77  AssertNameEquals("a.txt", name);
78
79  // b.txt
80  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
81  AssertNameEquals("b.txt", name);
82
83  // b/
84  ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
85  AssertNameEquals("b/", name);
86
87  // End of iteration.
88  ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));
89
90  CloseArchive(handle);
91}
92
93TEST(ziparchive, FindEntry) {
94  ZipArchiveHandle handle;
95  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
96
97  ZipEntry data;
98  ASSERT_EQ(0, FindEntry(handle, "a.txt", &data));
99
100  // Known facts about a.txt, from zipinfo -v.
101  ASSERT_EQ(63, data.offset);
102  ASSERT_EQ(kCompressDeflated, data.method);
103  ASSERT_EQ(static_cast<uint32_t>(17), data.uncompressed_length);
104  ASSERT_EQ(static_cast<uint32_t>(13), data.compressed_length);
105  ASSERT_EQ(0x950821c5, data.crc32);
106
107  // An entry that doesn't exist. Should be a negative return code.
108  ASSERT_LT(FindEntry(handle, "nonexistent.txt", &data), 0);
109
110  CloseArchive(handle);
111}
112
113TEST(ziparchive, ExtractToMemory) {
114  ZipArchiveHandle handle;
115  ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
116
117  // An entry that's deflated.
118  ZipEntry data;
119  ASSERT_EQ(0, FindEntry(handle, "a.txt", &data));
120  const uint32_t a_size = data.uncompressed_length;
121  ASSERT_EQ(a_size, sizeof(kATxtContents));
122  uint8_t* buffer = new uint8_t[a_size];
123  ASSERT_EQ(0, ExtractToMemory(handle, &data, buffer, a_size));
124  ASSERT_EQ(0, memcmp(buffer, kATxtContents, a_size));
125  delete[] buffer;
126
127  // An entry that's stored.
128  ASSERT_EQ(0, FindEntry(handle, "b.txt", &data));
129  const uint32_t b_size = data.uncompressed_length;
130  ASSERT_EQ(b_size, sizeof(kBTxtContents));
131  buffer = new uint8_t[b_size];
132  ASSERT_EQ(0, ExtractToMemory(handle, &data, buffer, b_size));
133  ASSERT_EQ(0, memcmp(buffer, kBTxtContents, b_size));
134  delete[] buffer;
135
136  CloseArchive(handle);
137}
138
139int main(int argc, char** argv) {
140  ::testing::InitGoogleTest(&argc, argv);
141
142  static struct option options[] = {
143    { "test_data_dir", required_argument, NULL, 't' },
144    { NULL, 0, NULL, 0 }
145  };
146
147  while (true) {
148    int option_index;
149    const int c = getopt_long_only(argc, argv, "", options, &option_index);
150    if (c == -1) {
151      break;
152    }
153
154    if (c == 't') {
155      test_data_dir = optarg;
156    }
157  }
158
159  if (test_data_dir.size() == 0) {
160    printf("Test data flag (--test_data_dir) required\n\n");
161    return -1;
162  }
163
164  if (test_data_dir[0] != '/') {
165    printf("Test data must be an absolute path, was %s\n\n",
166           test_data_dir.c_str());
167    return -2;
168  }
169
170  return RUN_ALL_TESTS();
171}
172
173