File: combining_upload_list_unittest.cc

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (297 lines) | stat: -rw-r--r-- 11,688 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/upload_list/combining_upload_list.h"

#include <array>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/time/time.h"
#include "components/upload_list/text_log_upload_list.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class CombiningUploadListTest : public testing::Test {
 public:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    first_reader_ = base::MakeRefCounted<TextLogUploadList>(first_log_path());
    second_reader_ = base::MakeRefCounted<TextLogUploadList>(second_log_path());
    third_reader_ = base::MakeRefCounted<TextLogUploadList>(third_log_path());
  }

 protected:
  base::FilePath first_log_path() {
    return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("uploads1.log"));
  }

  base::FilePath second_log_path() {
    return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("uploads2.log"));
  }

  base::FilePath third_log_path() {
    return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("uploads3.log"));
  }

  base::ScopedTempDir temp_dir_;
  base::test::TaskEnvironment task_environment_;
  scoped_refptr<UploadList> first_reader_;
  scoped_refptr<UploadList> second_reader_;
  scoped_refptr<UploadList> third_reader_;
};

TEST_F(CombiningUploadListTest, ThreeWayCombine) {
  constexpr char kFirstList[] = R"(
1614000000,ddee0000
1614004000,ddee0004
1614008000,ddee0008
1614012000,ddee0012
  )";
  ASSERT_TRUE(base::WriteFile(first_log_path(), kFirstList));

  constexpr char kSecondList[] = R"(
{"upload_time":"1614002000","upload_id":"ddee0002"}
{"upload_time":"1614006000","upload_id":"ddee0006"}
{"upload_time":"1614010000","upload_id":"ddee0010"}
  )";
  ASSERT_TRUE(base::WriteFile(second_log_path(), kSecondList));

  constexpr char kThirdList[] = R"(
{"upload_time":"1614014000","upload_id":"ddee0014"}
  )";
  ASSERT_TRUE(base::WriteFile(third_log_path(), kThirdList));

  std::vector<scoped_refptr<UploadList>> sublists = {
      first_reader_, second_reader_, third_reader_};
  auto combined_upload_list(
      base::MakeRefCounted<CombiningUploadList>(sublists));

  base::RunLoop run_loop;
  combined_upload_list->Load(run_loop.QuitClosure());
  run_loop.Run();

  // Expect the reports to be returned newest first.
  const auto kExpectedUploadTimes = std::to_array<base::Time>({
      base::Time::FromSecondsSinceUnixEpoch(
          1614014000),  // 14: Largest time value
      base::Time::FromSecondsSinceUnixEpoch(1614012000),  // 12
      base::Time::FromSecondsSinceUnixEpoch(1614010000),  // 10
      base::Time::FromSecondsSinceUnixEpoch(1614008000),  //  8
      base::Time::FromSecondsSinceUnixEpoch(1614006000),  //  6
      base::Time::FromSecondsSinceUnixEpoch(1614004000),  //  4
      base::Time::FromSecondsSinceUnixEpoch(1614002000),  //  2
      base::Time::FromSecondsSinceUnixEpoch(
          1614000000),  //  0: Smallest time value
  });
  // clang-format off
  const auto kExpectedUploadIds = std::to_array<std::string>({
      "ddee0014",  // Note that the last two digits correspond to the fourth
      "ddee0012",  // and fifth digits of the time, for easy correspondence.
      "ddee0010",
      "ddee0008",
      "ddee0006",
      "ddee0004",
      "ddee0002",
      "ddee0000",
  });
  // clang-format on

  std::vector<const UploadList::UploadInfo*> actual =
      combined_upload_list->GetUploads(20);
  ASSERT_EQ(actual.size(), std::size(kExpectedUploadTimes));

  for (size_t i = 0; i < std::size(kExpectedUploadTimes); i++) {
    EXPECT_EQ(actual[i]->upload_time, kExpectedUploadTimes[i])
        << " for index " << i;
    EXPECT_EQ(actual[i]->state, UploadList::UploadInfo::State::Uploaded)
        << " for index " << i;
    EXPECT_EQ(actual[i]->upload_id, kExpectedUploadIds[i])
        << " for index " << i;
  }

  static constexpr int kSmallerUploadsSize = 3;
  actual = combined_upload_list->GetUploads(kSmallerUploadsSize);
  ASSERT_EQ(actual.size(),
            std::vector<const UploadList::UploadInfo*>::size_type{
                kSmallerUploadsSize});

  for (size_t i = 0; i < kSmallerUploadsSize; i++) {
    EXPECT_EQ(actual[i]->upload_time, kExpectedUploadTimes[i])
        << " for index " << i;
    EXPECT_EQ(actual[i]->state, UploadList::UploadInfo::State::Uploaded)
        << " for index " << i;
    EXPECT_EQ(actual[i]->upload_id, kExpectedUploadIds[i])
        << " for index " << i;
  }
}

TEST_F(CombiningUploadListTest, SortCaptureTimeOrUploadTime) {
  // If we have both capture_time or upload_time, we sort by capture_time, but
  // we'll use upload_time if that's what we have.
  constexpr char kUploadAndCaptureTimes[] = R"(
{"capture_time":"1614001000","upload_id":"ddee0001","upload_time":"1614999959"}
{"capture_time":"1614004000","upload_id":"ddee0004","upload_time":"1614999999"}
{"capture_time":"1614007000","upload_id":"ddee0007","upload_time":"1600000000"}
  )";
  ASSERT_TRUE(base::WriteFile(first_log_path(), kUploadAndCaptureTimes));
  constexpr char kJustCaptureTimes[] = R"(
{"capture_time":"1614002000","upload_id":"ddee0002"}
{"capture_time":"1614005000","upload_id":"ddee0005"}
{"capture_time":"1614008000","upload_id":"ddee0008"}
  )";
  ASSERT_TRUE(base::WriteFile(second_log_path(), kJustCaptureTimes));
  constexpr char kJustUploadTimes[] = R"(
{"upload_time":"1614003000","upload_id":"ddee0003"}
{"upload_time":"1614006000","upload_id":"ddee0006"}
{"upload_time":"1614009000","upload_id":"ddee0009"}
  )";
  ASSERT_TRUE(base::WriteFile(third_log_path(), kJustUploadTimes));

  std::vector<scoped_refptr<UploadList>> sublists = {
      first_reader_, second_reader_, third_reader_};
  auto combined_upload_list(
      base::MakeRefCounted<CombiningUploadList>(sublists));

  base::RunLoop run_loop;
  combined_upload_list->Load(run_loop.QuitClosure());
  run_loop.Run();

  const auto kExpectedUploadTimes = std::to_array<base::Time>({
      base::Time::FromSecondsSinceUnixEpoch(1614009000),
      base::Time(),  // Sorted by capture time 1614008000
      base::Time::FromSecondsSinceUnixEpoch(
          1600000000),  // Sorted by capture time 1614007000
      base::Time::FromSecondsSinceUnixEpoch(1614006000),
      base::Time(),  // Sorted by capture time 1614005000
      base::Time::FromSecondsSinceUnixEpoch(
          1614999999),  // Sorted by capture time 1614004000
      base::Time::FromSecondsSinceUnixEpoch(1614003000),
      base::Time(),  // Sorted by capture time 1614002000
      base::Time::FromSecondsSinceUnixEpoch(
          1614999959),  // Sorted by capture time 1614001000
  });
  // clang-format off
  const auto kExpectedCaptureTimes = std::to_array<base::Time>({
      base::Time(),                         // Sorted by upload_time 1614009000
      base::Time::FromSecondsSinceUnixEpoch(1614008000),
      base::Time::FromSecondsSinceUnixEpoch(1614007000),
      base::Time(),                         // Sorted by upload_time 1614006000
      base::Time::FromSecondsSinceUnixEpoch(1614005000),
      base::Time::FromSecondsSinceUnixEpoch(1614004000),
      base::Time(),                         // Sorted by upload_time 1614003000
      base::Time::FromSecondsSinceUnixEpoch(1614002000),
      base::Time::FromSecondsSinceUnixEpoch(1614001000),
  });
  const auto kExpectedUploadIds = std::to_array<std::string>({
      "ddee0009",  // Here, the last digit matches the fourth digit of the time
      "ddee0008",  // we expect to be used as the sort key.
      "ddee0007",
      "ddee0006",
      "ddee0005",
      "ddee0004",
      "ddee0003",
      "ddee0002",
      "ddee0001",
  });
  // clang-format on

  const std::vector<const UploadList::UploadInfo*> actual =
      combined_upload_list->GetUploads(20);
  ASSERT_EQ(actual.size(), std::size(kExpectedUploadTimes));

  for (size_t i = 0; i < std::size(kExpectedUploadTimes); i++) {
    EXPECT_EQ(actual[i]->upload_time, kExpectedUploadTimes[i])
        << " for index " << i;
    EXPECT_EQ(actual[i]->capture_time, kExpectedCaptureTimes[i])
        << " for index " << i;
    EXPECT_EQ(actual[i]->upload_id, kExpectedUploadIds[i])
        << " for index " << i;
  }
}

TEST_F(CombiningUploadListTest, Clear) {
  constexpr char kUploadAndCaptureTimes[] = R"(
{"capture_time":"1614001000","upload_id":"ddee0001","upload_time":"1614999959"}
{"capture_time":"1614004000","upload_id":"ddee0004","upload_time":"1614999999"}
{"capture_time":"1614007000","upload_id":"ddee0007","upload_time":"1600000000"}
)";
  ASSERT_TRUE(base::WriteFile(first_log_path(), kUploadAndCaptureTimes));
  constexpr char kJustCaptureTimes[] = R"(
{"capture_time":"1614002000","upload_id":"ddee0002"}
{"capture_time":"1614005000","upload_id":"ddee0005"}
{"capture_time":"1614008000","upload_id":"ddee0008"}
)";
  ASSERT_TRUE(base::WriteFile(second_log_path(), kJustCaptureTimes));
  constexpr char kJustUploadTimes[] = R"(
{"upload_time":"1614003000","upload_id":"ddee0003"}
{"upload_time":"1614006000","upload_id":"ddee0006"}
{"upload_time":"1614009000","upload_id":"ddee0009"}
)";
  ASSERT_TRUE(base::WriteFile(third_log_path(), kJustUploadTimes));

  std::vector<scoped_refptr<UploadList>> sublists = {
      first_reader_, second_reader_, third_reader_};
  auto combined_upload_list(
      base::MakeRefCounted<CombiningUploadList>(sublists));

  base::RunLoop run_loop;
  combined_upload_list->Clear(base::Time::FromSecondsSinceUnixEpoch(1614004000),
                              base::Time::FromSecondsSinceUnixEpoch(1614006001),
                              run_loop.QuitClosure());
  run_loop.Run();

  // Should have removed the middle entry from each file.
  std::string first_contents;
  base::ReadFileToString(first_log_path(), &first_contents);
  // Can't use raw string here because of the 80 column rule.
  EXPECT_EQ(first_contents,
            "{\"capture_time\":\"1614001000\",\"upload_id\":\"ddee0001\","
            "\"upload_time\":\"1614999959\"}\n"
            "{\"capture_time\":\"1614007000\",\"upload_id\":\"ddee0007\","
            "\"upload_time\":\"1600000000\"}\n");
  std::string second_contents;
  base::ReadFileToString(second_log_path(), &second_contents);
  EXPECT_EQ(second_contents,
            R"({"capture_time":"1614002000","upload_id":"ddee0002"}
{"capture_time":"1614008000","upload_id":"ddee0008"}
)");

  std::string third_contents;
  base::ReadFileToString(third_log_path(), &third_contents);
  EXPECT_EQ(third_contents,
            R"({"upload_time":"1614003000","upload_id":"ddee0003"}
{"upload_time":"1614009000","upload_id":"ddee0009"}
)");
}

class MockUploadList final : public UploadList {
 public:
  MOCK_METHOD0(LoadUploadList, std::vector<std::unique_ptr<UploadInfo>>());
  MOCK_METHOD2(ClearUploadList, void(const base::Time&, const base::Time&));
  MOCK_METHOD1(RequestSingleUpload, void(const std::string&));

 protected:
  ~MockUploadList() override = default;
};

TEST_F(CombiningUploadListTest, RequestSingleUpload) {
  auto mock_list1 = base::MakeRefCounted<MockUploadList>();
  auto mock_list2 = base::MakeRefCounted<MockUploadList>();
  auto combined_lists = base::MakeRefCounted<CombiningUploadList>(
      std::vector<scoped_refptr<UploadList>>({mock_list1, mock_list2}));

  constexpr char kLocalId[] = "12345";
  EXPECT_CALL(*mock_list1, RequestSingleUpload(kLocalId));
  EXPECT_CALL(*mock_list2, RequestSingleUpload(kLocalId));
  combined_lists->RequestSingleUploadAsync(kLocalId);
}

}  // namespace