Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(614)

Side by Side Diff: third_party/WebKit/Source/modules/fetch/BytesConsumerTestUtil.cpp

Issue 2269953004: Implment BytesConsumer::tee (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "modules/fetch/BytesConsumerTestUtil.h"
6
7 #include "core/dom/ExecutionContext.h"
8 #include "core/dom/TaskRunnerHelper.h"
9 #include "platform/testing/UnitTestHelpers.h"
10 #include "public/platform/WebTaskRunner.h"
11 #include "wtf/Assertions.h"
12 #include "wtf/Functional.h"
13
14 namespace blink {
15
16 using Result = BytesConsumer::Result;
17
18 BytesConsumerTestUtil::ReplayingBytesConsumer::ReplayingBytesConsumer(ExecutionC ontext* executionContext)
19 : m_executionContext(executionContext)
20 {
21 }
22
23 BytesConsumerTestUtil::ReplayingBytesConsumer::~ReplayingBytesConsumer()
24 {
25 }
26
27 Result BytesConsumerTestUtil::ReplayingBytesConsumer::beginRead(const char** buf fer, size_t* available)
28 {
29 ++m_notificationToken;
30 if (m_commands.isEmpty()) {
31 switch (m_state) {
32 case BytesConsumer::InternalState::Readable:
33 case BytesConsumer::InternalState::Waiting:
34 return Result::ShouldWait;
35 case BytesConsumer::InternalState::Closed:
36 return Result::Done;
37 case BytesConsumer::InternalState::Errored:
38 return Result::Error;
39 }
40 }
41 const Command& command = m_commands[0];
42 switch (command.getName()) {
43 case Command::Data:
44 DCHECK_LE(m_offset, command.body().size());
45 *buffer = command.body().data() + m_offset;
46 *available = command.body().size() - m_offset;
47 return Result::Ok;
48 case Command::Done:
49 m_commands.removeFirst();
50 close();
51 return Result::Done;
52 case Command::Error: {
53 Error e(String::fromUTF8(command.body().data(), command.body().size()));
54 m_commands.removeFirst();
55 error(std::move(e));
56 return Result::Error;
57 }
58 case Command::Wait:
59 m_commands.removeFirst();
60 m_state = InternalState::Waiting;
61 TaskRunnerHelper::get(TaskType::Networking, m_executionContext)->postTas k(
62 BLINK_FROM_HERE,
63 WTF::bind(&ReplayingBytesConsumer::notifyAsReadable, wrapPersistent( this), m_notificationToken));
64 return Result::ShouldWait;
65 }
66 NOTREACHED();
67 return Result::Error;
68 }
69
70 Result BytesConsumerTestUtil::ReplayingBytesConsumer::endRead(size_t read)
71 {
72 DCHECK(!m_commands.isEmpty());
73 const Command& command = m_commands[0];
74 DCHECK_EQ(Command::Data, command.getName());
75 m_offset += read;
76 DCHECK_LE(m_offset, command.body().size());
77 if (m_offset < command.body().size())
78 return Result::Ok;
79
80 m_offset = 0;
81 m_commands.removeFirst();
82 return Result::Ok;
83 }
84
85 void BytesConsumerTestUtil::ReplayingBytesConsumer::setClient(Client* client)
86 {
87 DCHECK(!m_client);
88 DCHECK(client);
89 m_client = client;
90 ++m_notificationToken;
91 }
92
93 void BytesConsumerTestUtil::ReplayingBytesConsumer::clearClient()
94 {
95 DCHECK(m_client);
96 m_client = nullptr;
97 ++m_notificationToken;
98 }
99
100 void BytesConsumerTestUtil::ReplayingBytesConsumer::cancel()
101 {
102 close();
103 m_isCancelled = true;
104 }
105
106 BytesConsumer::PublicState BytesConsumerTestUtil::ReplayingBytesConsumer::getPub licState() const
107 {
108 return getPublicStateFromInternalState(m_state);
109 }
110
111 BytesConsumer::Error BytesConsumerTestUtil::ReplayingBytesConsumer::getError() c onst
112 {
113 return m_error;
114 }
115
116 void BytesConsumerTestUtil::ReplayingBytesConsumer::notifyAsReadable(int notific ationToken)
117 {
118 if (m_notificationToken != notificationToken) {
119 // The notification is cancelled.
120 return;
121 }
122 DCHECK(m_client);
123 DCHECK_NE(InternalState::Closed, m_state);
124 DCHECK_NE(InternalState::Errored, m_state);
125 m_client->onStateChange();
126 }
127
128 void BytesConsumerTestUtil::ReplayingBytesConsumer::close()
129 {
130 m_commands.clear();
131 m_offset = 0;
132 m_state = InternalState::Closed;
133 ++m_notificationToken;
134 }
135
136 void BytesConsumerTestUtil::ReplayingBytesConsumer::error(const Error& e)
137 {
138 m_commands.clear();
139 m_offset = 0;
140 m_error = e;
141 m_state = InternalState::Errored;
142 ++m_notificationToken;
143 }
144
145 DEFINE_TRACE(BytesConsumerTestUtil::ReplayingBytesConsumer)
146 {
147 visitor->trace(m_executionContext);
148 visitor->trace(m_client);
149 BytesConsumer::trace(visitor);
150 }
151
152 BytesConsumerTestUtil::Reader::Reader(BytesConsumer* consumer)
153 : m_consumer(consumer)
154 {
155 m_consumer->setClient(this);
156 }
157
158 void BytesConsumerTestUtil::Reader::onStateChange()
159 {
160 while (true) {
161 // We choose 3 here because of the following reasons.
162 // - We want to split a string with multiple chunks, so we need to
163 // choose a small number.
164 // - An odd number is preferable to check an out-of-range error.
165 // - With 1, every chunk consists of one byte it's too simple.
166 char buffer[3];
167 size_t read = 0;
168 switch (m_consumer->read(buffer, sizeof(buffer), &read)) {
169 case BytesConsumer::Result::Ok:
170 m_data.append(buffer, read);
171 break;
172 case BytesConsumer::Result::ShouldWait:
173 return;
174 case BytesConsumer::Result::Done:
175 m_result = BytesConsumer::Result::Done;
176 return;
177 case BytesConsumer::Result::Error:
178 m_result = BytesConsumer::Result::Error;
179 return;
180 }
181 }
182 }
183
184 std::pair<BytesConsumer::Result, Vector<char>> BytesConsumerTestUtil::Reader::ru n()
185 {
186 onStateChange();
187 while (m_result != BytesConsumer::Result::Done && m_result != BytesConsumer: :Result::Error)
188 testing::runPendingTasks();
189 testing::runPendingTasks();
190 return std::make_pair(m_result, std::move(m_data));
191 }
192
193 BytesConsumerTestUtil::TwoPhaseReader::TwoPhaseReader(BytesConsumer* consumer)
194 : m_consumer(consumer)
195 {
196 m_consumer->setClient(this);
197 }
198
199
200 void BytesConsumerTestUtil::TwoPhaseReader::onStateChange()
201 {
202 while (true) {
203 const char* buffer = nullptr;
204 size_t available = 0;
205 switch (m_consumer->beginRead(&buffer, &available)) {
206 case BytesConsumer::Result::Ok: {
207 // We don't use |available| as-is to test cases where endRead
208 // is called with a number smaller than |available|. We choose 3
209 // because of the same reasons as Reader::onStateChange.
210 size_t read = std::max(static_cast<size_t>(3), available);
211 m_data.append(buffer, read);
212 m_consumer->endRead(read);
213 break;
214 }
215 case BytesConsumer::Result::ShouldWait:
216 return;
217 case BytesConsumer::Result::Done:
218 m_result = BytesConsumer::Result::Done;
219 return;
220 case BytesConsumer::Result::Error:
221 m_result = BytesConsumer::Result::Error;
222 return;
223 }
224 }
225 }
226
227 std::pair<BytesConsumer::Result, Vector<char>> BytesConsumerTestUtil::TwoPhaseRe ader::run()
228 {
229 onStateChange();
230 while (m_result != BytesConsumer::Result::Done && m_result != BytesConsumer: :Result::Error)
231 testing::runPendingTasks();
232 testing::runPendingTasks();
233 return std::make_pair(m_result, std::move(m_data));
234 }
235
236 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698