File: system_storage_apitest.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (155 lines) | stat: -rw-r--r-- 5,118 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
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <stddef.h>

#include <atomic>
#include <vector>

#include "base/memory/scoped_refptr.h"
#include "base/run_loop.h"
#include "components/storage_monitor/storage_monitor.h"
#include "components/storage_monitor/test_storage_monitor.h"
#include "extensions/browser/api/system_storage/storage_api_test_util.h"
#include "extensions/browser/api/system_storage/storage_info_provider.h"
#include "extensions/shell/test/shell_apitest.h"
#include "extensions/test/extension_test_message_listener.h"
#include "extensions/test/result_catcher.h"

namespace {

using extensions::StorageUnitInfoList;
using extensions::test::TestStorageUnitInfo;
using extensions::test::kRemovableStorageData;
using storage_monitor::StorageMonitor;
using storage_monitor::TestStorageMonitor;

constexpr TestStorageUnitInfo kTestingData[] = {
    {"dcim:device:001", "0xbeaf", 4098, 1},
    {"path:device:002", "/home", 4098, 2},
    {"path:device:003", "/data", 10000, 3}};

}  // namespace

class TestStorageInfoProvider : public extensions::StorageInfoProvider {
 public:
  TestStorageInfoProvider() = default;

  void set_expected_call_count(int count) { expected_call_count_ = count; }

  void WaitForCallbacks() {
    DCHECK(expected_call_count_);
    if (callback_count_ != expected_call_count_) {
      run_loop_.Run();
    }
  }

 private:
  ~TestStorageInfoProvider() override = default;

  // StorageInfoProvider implementations.
  double GetStorageFreeSpaceFromTransientIdAsync(
      const std::string& transient_id) override;

  // Read on the IO thread, written from another thread.
  std::atomic<int> callback_count_{0};

  // Assumed to be read-only once the test starts.
  int expected_call_count_ = 0;

  base::RunLoop run_loop_;
};

double TestStorageInfoProvider::GetStorageFreeSpaceFromTransientIdAsync(
    const std::string& transient_id) {
  double result = -1;
  std::string device_id =
      StorageMonitor::GetInstance()->GetDeviceIdForTransientId(transient_id);
  for (const auto& info : kTestingData) {
    if (info.device_id == device_id) {
      result = static_cast<double>(info.available_capacity);
      break;
    }
  }
  if (++callback_count_ == expected_call_count_) {
    run_loop_.QuitWhenIdle();
  }
  return result;
}

class SystemStorageApiTest : public extensions::ShellApiTest {
 public:
  SystemStorageApiTest() = default;
  ~SystemStorageApiTest() override = default;

  void SetUpOnMainThread() override {
    ShellApiTest::SetUpOnMainThread();
    TestStorageMonitor::CreateForBrowserTests();
  }

  void SetUpAllMockStorageDevices() {
    for (const auto& entry : kTestingData) {
      AttachRemovableStorage(entry);
    }
  }

  void AttachRemovableStorage(
      const struct TestStorageUnitInfo& removable_storage_info) {
    StorageMonitor::GetInstance()->receiver()->ProcessAttach(
        extensions::test::BuildStorageInfoFromTestStorageUnitInfo(
            removable_storage_info));
  }

  void DetachRemovableStorage(const std::string& id) {
    StorageMonitor::GetInstance()->receiver()->ProcessDetach(id);
  }
};

IN_PROC_BROWSER_TEST_F(SystemStorageApiTest, Storage) {
  SetUpAllMockStorageDevices();
  auto provider = base::MakeRefCounted<TestStorageInfoProvider>();
  extensions::StorageInfoProvider::InitializeForTesting(provider);
  std::vector<std::unique_ptr<ExtensionTestMessageListener>>
      device_ids_listeners;
  for (const auto& entry : kTestingData) {
    device_ids_listeners.push_back(
        std::make_unique<ExtensionTestMessageListener>(
            StorageMonitor::GetInstance()->GetTransientIdForDeviceId(
                entry.device_id)));
  }
  // Set the number of expected callbacks into the StorageInfoProvider.
  provider->set_expected_call_count(device_ids_listeners.size());
  ASSERT_TRUE(RunAppTest("system/storage")) << message_;
  for (const auto& listener : device_ids_listeners)
    EXPECT_TRUE(listener->WaitUntilSatisfied());
  // Wait for the callbacks to complete so they don't run during
  // teardown.
  provider->WaitForCallbacks();
}

IN_PROC_BROWSER_TEST_F(SystemStorageApiTest, StorageAttachment) {
  extensions::ResultCatcher catcher;
  ExtensionTestMessageListener attach_listener("attach");
  ExtensionTestMessageListener detach_listener("detach");

  EXPECT_TRUE(LoadApp("system/storage_attachment"));
  // Simulate triggering onAttached event.
  ASSERT_TRUE(attach_listener.WaitUntilSatisfied());

  AttachRemovableStorage(kRemovableStorageData);

  std::string removable_storage_transient_id =
      StorageMonitor::GetInstance()->GetTransientIdForDeviceId(
          kRemovableStorageData.device_id);
  ExtensionTestMessageListener detach_device_id_listener(
      removable_storage_transient_id);

  // Simulate triggering onDetached event.
  ASSERT_TRUE(detach_listener.WaitUntilSatisfied());
  DetachRemovableStorage(kRemovableStorageData.device_id);

  ASSERT_TRUE(detach_device_id_listener.WaitUntilSatisfied());

  EXPECT_TRUE(catcher.GetNextResult()) << catcher.message();
}