File: buffer_test.cc

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; 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,811; 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 (148 lines) | stat: -rw-r--r-- 6,102 bytes parent folder | download | duplicates (5)
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
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <limits>

#include "base/check.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "build/build_config.h"
#include "components/cronet/native/test/test_util.h"
#include "cronet_c.h"
#include "partition_alloc/buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

class BufferTest : public ::testing::Test {
 public:
  BufferTest() = default;

  BufferTest(const BufferTest&) = delete;
  BufferTest& operator=(const BufferTest&) = delete;

  ~BufferTest() override {}

 protected:
  static void BufferCallback_OnDestroy(Cronet_BufferCallbackPtr self,
                                       Cronet_BufferPtr buffer);
  bool on_destroy_called() const { return on_destroy_called_; }

  // Provide a task environment for use by TestExecutor instances. Do not
  // initialize the ThreadPool as this is done by the Cronet_Engine
  base::test::SingleThreadTaskEnvironment task_environment_;

 private:
  void set_on_destroy_called(bool value) { on_destroy_called_ = value; }

  bool on_destroy_called_ = false;
};

const uint64_t kTestBufferSize = 20;

// static
void BufferTest::BufferCallback_OnDestroy(Cronet_BufferCallbackPtr self,
                                          Cronet_BufferPtr buffer) {
  CHECK(self);
  Cronet_ClientContext context = Cronet_BufferCallback_GetClientContext(self);
  BufferTest* test = static_cast<BufferTest*>(context);
  CHECK(test);
  test->set_on_destroy_called(true);
  // Free buffer_data.
  void* buffer_data = Cronet_Buffer_GetData(buffer);
  CHECK(buffer_data);
  free(buffer_data);
}

// Test on_destroy that destroys the buffer set in context.
void TestRunnable_DestroyBuffer(Cronet_RunnablePtr self) {
  CHECK(self);
  Cronet_ClientContext context = Cronet_Runnable_GetClientContext(self);
  Cronet_BufferPtr buffer = static_cast<Cronet_BufferPtr>(context);
  CHECK(buffer);
  // Destroy buffer. TestCronet_BufferCallback_OnDestroy should be invoked.
  Cronet_Buffer_Destroy(buffer);
}

// Example of allocating buffer with reasonable size.
TEST_F(BufferTest, TestInitWithAlloc) {
  // Create Cronet buffer and allocate buffer data.
  Cronet_BufferPtr buffer = Cronet_Buffer_Create();
  Cronet_Buffer_InitWithAlloc(buffer, kTestBufferSize);
  EXPECT_TRUE(Cronet_Buffer_GetData(buffer));
  EXPECT_EQ(Cronet_Buffer_GetSize(buffer), kTestBufferSize);
  Cronet_Buffer_Destroy(buffer);
  ASSERT_FALSE(on_destroy_called());
}

#if defined(ARCH_CPU_64_BITS) &&                                              \
    (defined(ADDRESS_SANITIZER) || defined(MEMORY_SANITIZER) ||               \
     defined(THREAD_SANITIZER) ||                                             \
     PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC) || BUILDFLAG(IS_CHROMEOS) || \
     BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_FUCHSIA))
// - ASAN and MSAN malloc by default triggers crash instead of returning null on
//   failure.
// - PartitionAlloc malloc also crashes on allocation failure by design.
// - Fuchsia malloc() also crashes on allocation failure in some kernel builds.
// - On Linux and Chrome OS, the allocator shims crash for large allocations, on
//   purpose.
#define MAYBE_TestInitWithHugeAllocFails DISABLED_TestInitWithHugeAllocFails
#else
#define MAYBE_TestInitWithHugeAllocFails TestInitWithHugeAllocFails
#endif
// Verify behaviour when an unsatisfiably huge buffer allocation is requested.
// On 32-bit platforms, we want to ensure that a 64-bit range allocation size
// is rejected, rather than resulting in a 32-bit truncated allocation.
// Some platforms over-commit allocations, so we request an allocation of the
// whole 64-bit address-space, which cannot possibly be satisfied in a 32- or
// 64-bit process.
TEST_F(BufferTest, MAYBE_TestInitWithHugeAllocFails) {
  Cronet_BufferPtr buffer = Cronet_Buffer_Create();
  const uint64_t kHugeTestBufferSize = std::numeric_limits<uint64_t>::max();
  Cronet_Buffer_InitWithAlloc(buffer, kHugeTestBufferSize);
  EXPECT_FALSE(Cronet_Buffer_GetData(buffer));
  EXPECT_EQ(Cronet_Buffer_GetSize(buffer), 0ull);
  Cronet_Buffer_Destroy(buffer);
  ASSERT_FALSE(on_destroy_called());
}

// Example of initializing buffer with app-allocated data.
TEST_F(BufferTest, TestInitWithDataAndCallback) {
  Cronet_BufferCallbackPtr buffer_callback =
      Cronet_BufferCallback_CreateWith(BufferCallback_OnDestroy);
  Cronet_BufferCallback_SetClientContext(buffer_callback, this);
  // Create Cronet buffer and allocate buffer data.
  Cronet_BufferPtr buffer = Cronet_Buffer_Create();
  Cronet_Buffer_InitWithDataAndCallback(buffer, malloc(kTestBufferSize),
                                        kTestBufferSize, buffer_callback);
  EXPECT_TRUE(Cronet_Buffer_GetData(buffer));
  EXPECT_EQ(Cronet_Buffer_GetSize(buffer), kTestBufferSize);
  Cronet_Buffer_Destroy(buffer);
  ASSERT_TRUE(on_destroy_called());
  Cronet_BufferCallback_Destroy(buffer_callback);
}

// Example of posting application on_destroy to the executor and passing
// buffer to it, expecting buffer to be destroyed and freed.
TEST_F(BufferTest, TestCronetBufferAsync) {
  // Executor provided by the application.
  Cronet_ExecutorPtr executor = cronet::test::CreateTestExecutor();
  Cronet_BufferCallbackPtr buffer_callback =
      Cronet_BufferCallback_CreateWith(BufferCallback_OnDestroy);
  Cronet_BufferCallback_SetClientContext(buffer_callback, this);
  // Create Cronet buffer and allocate buffer data.
  Cronet_BufferPtr buffer = Cronet_Buffer_Create();
  Cronet_Buffer_InitWithDataAndCallback(buffer, malloc(kTestBufferSize),
                                        kTestBufferSize, buffer_callback);
  Cronet_RunnablePtr runnable =
      Cronet_Runnable_CreateWith(TestRunnable_DestroyBuffer);
  Cronet_Runnable_SetClientContext(runnable, buffer);
  Cronet_Executor_Execute(executor, runnable);
  base::RunLoop().RunUntilIdle();
  ASSERT_TRUE(on_destroy_called());
  Cronet_Executor_Destroy(executor);
  Cronet_BufferCallback_Destroy(buffer_callback);
}

}  // namespace