spdy_write_queue_unittest.cc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. // Copyright (c) 2013 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. #include "net/spdy/spdy_write_queue.h"
  5. #include <cstddef>
  6. #include <cstring>
  7. #include <string>
  8. #include <utility>
  9. #include "base/bind.h"
  10. #include "base/memory/ref_counted.h"
  11. #include "base/notreached.h"
  12. #include "base/strings/string_number_conversions.h"
  13. #include "net/base/request_priority.h"
  14. #include "net/log/net_log_with_source.h"
  15. #include "net/spdy/spdy_buffer_producer.h"
  16. #include "net/spdy/spdy_stream.h"
  17. #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
  18. #include "testing/gtest/include/gtest/gtest.h"
  19. #include "url/gurl.h"
  20. namespace net {
  21. namespace {
  22. const char kOriginal[] = "original";
  23. const char kRequeued[] = "requeued";
  24. class SpdyWriteQueueTest : public ::testing::Test {};
  25. // Makes a SpdyFrameProducer producing a frame with the data in the
  26. // given string.
  27. std::unique_ptr<SpdyBufferProducer> StringToProducer(const std::string& s) {
  28. auto data = std::make_unique<char[]>(s.size());
  29. std::memcpy(data.get(), s.data(), s.size());
  30. auto frame = std::make_unique<spdy::SpdySerializedFrame>(data.release(),
  31. s.size(), true);
  32. auto buffer = std::make_unique<SpdyBuffer>(std::move(frame));
  33. return std::make_unique<SimpleBufferProducer>(std::move(buffer));
  34. }
  35. // Makes a SpdyBufferProducer producing a frame with the data in the
  36. // given int (converted to a string).
  37. std::unique_ptr<SpdyBufferProducer> IntToProducer(int i) {
  38. return StringToProducer(base::NumberToString(i));
  39. }
  40. // Producer whose produced buffer will enqueue yet another buffer into the
  41. // SpdyWriteQueue upon destruction.
  42. class RequeingBufferProducer : public SpdyBufferProducer {
  43. public:
  44. explicit RequeingBufferProducer(SpdyWriteQueue* queue) {
  45. buffer_ = std::make_unique<SpdyBuffer>(kOriginal, std::size(kOriginal));
  46. buffer_->AddConsumeCallback(
  47. base::BindRepeating(RequeingBufferProducer::ConsumeCallback, queue));
  48. }
  49. std::unique_ptr<SpdyBuffer> ProduceBuffer() override {
  50. return std::move(buffer_);
  51. }
  52. static void ConsumeCallback(SpdyWriteQueue* queue,
  53. size_t size,
  54. SpdyBuffer::ConsumeSource source) {
  55. auto buffer = std::make_unique<SpdyBuffer>(kRequeued, std::size(kRequeued));
  56. auto buffer_producer =
  57. std::make_unique<SimpleBufferProducer>(std::move(buffer));
  58. queue->Enqueue(MEDIUM, spdy::SpdyFrameType::RST_STREAM,
  59. std::move(buffer_producer), base::WeakPtr<SpdyStream>(),
  60. TRAFFIC_ANNOTATION_FOR_TESTS);
  61. }
  62. private:
  63. std::unique_ptr<SpdyBuffer> buffer_;
  64. };
  65. // Produces a frame with the given producer and returns a copy of its
  66. // data as a string.
  67. std::string ProducerToString(std::unique_ptr<SpdyBufferProducer> producer) {
  68. std::unique_ptr<SpdyBuffer> buffer = producer->ProduceBuffer();
  69. return std::string(buffer->GetRemainingData(), buffer->GetRemainingSize());
  70. }
  71. // Produces a frame with the given producer and returns a copy of its
  72. // data as an int (converted from a string).
  73. int ProducerToInt(std::unique_ptr<SpdyBufferProducer> producer) {
  74. int i = 0;
  75. EXPECT_TRUE(base::StringToInt(ProducerToString(std::move(producer)), &i));
  76. return i;
  77. }
  78. // Makes a SpdyStream with the given priority and a NULL SpdySession
  79. // -- be careful to not call any functions that expect the session to
  80. // be there.
  81. std::unique_ptr<SpdyStream> MakeTestStream(RequestPriority priority) {
  82. return std::make_unique<SpdyStream>(
  83. SPDY_BIDIRECTIONAL_STREAM, base::WeakPtr<SpdySession>(), GURL(), priority,
  84. 0, 0, NetLogWithSource(), TRAFFIC_ANNOTATION_FOR_TESTS,
  85. false /* detect_broken_connection */);
  86. }
  87. // Add some frame producers of different priority. The producers
  88. // should be dequeued in priority order with their associated stream.
  89. TEST_F(SpdyWriteQueueTest, DequeuesByPriority) {
  90. SpdyWriteQueue write_queue;
  91. std::unique_ptr<SpdyBufferProducer> producer_low = StringToProducer("LOW");
  92. std::unique_ptr<SpdyBufferProducer> producer_medium =
  93. StringToProducer("MEDIUM");
  94. std::unique_ptr<SpdyBufferProducer> producer_highest =
  95. StringToProducer("HIGHEST");
  96. std::unique_ptr<SpdyStream> stream_medium = MakeTestStream(MEDIUM);
  97. std::unique_ptr<SpdyStream> stream_highest = MakeTestStream(HIGHEST);
  98. // A NULL stream should still work.
  99. write_queue.Enqueue(LOW, spdy::SpdyFrameType::HEADERS,
  100. std::move(producer_low), base::WeakPtr<SpdyStream>(),
  101. TRAFFIC_ANNOTATION_FOR_TESTS);
  102. write_queue.Enqueue(MEDIUM, spdy::SpdyFrameType::HEADERS,
  103. std::move(producer_medium), stream_medium->GetWeakPtr(),
  104. TRAFFIC_ANNOTATION_FOR_TESTS);
  105. write_queue.Enqueue(HIGHEST, spdy::SpdyFrameType::RST_STREAM,
  106. std::move(producer_highest), stream_highest->GetWeakPtr(),
  107. TRAFFIC_ANNOTATION_FOR_TESTS);
  108. spdy::SpdyFrameType frame_type = spdy::SpdyFrameType::DATA;
  109. std::unique_ptr<SpdyBufferProducer> frame_producer;
  110. base::WeakPtr<SpdyStream> stream;
  111. MutableNetworkTrafficAnnotationTag traffic_annotation;
  112. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  113. &traffic_annotation));
  114. EXPECT_EQ(spdy::SpdyFrameType::RST_STREAM, frame_type);
  115. EXPECT_EQ("HIGHEST", ProducerToString(std::move(frame_producer)));
  116. EXPECT_EQ(stream_highest.get(), stream.get());
  117. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  118. &traffic_annotation));
  119. EXPECT_EQ(spdy::SpdyFrameType::HEADERS, frame_type);
  120. EXPECT_EQ("MEDIUM", ProducerToString(std::move(frame_producer)));
  121. EXPECT_EQ(stream_medium.get(), stream.get());
  122. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  123. &traffic_annotation));
  124. EXPECT_EQ(spdy::SpdyFrameType::HEADERS, frame_type);
  125. EXPECT_EQ("LOW", ProducerToString(std::move(frame_producer)));
  126. EXPECT_EQ(nullptr, stream.get());
  127. EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  128. &traffic_annotation));
  129. }
  130. // Add some frame producers with the same priority. The producers
  131. // should be dequeued in FIFO order with their associated stream.
  132. TEST_F(SpdyWriteQueueTest, DequeuesFIFO) {
  133. SpdyWriteQueue write_queue;
  134. std::unique_ptr<SpdyBufferProducer> producer1 = IntToProducer(1);
  135. std::unique_ptr<SpdyBufferProducer> producer2 = IntToProducer(2);
  136. std::unique_ptr<SpdyBufferProducer> producer3 = IntToProducer(3);
  137. std::unique_ptr<SpdyStream> stream1 = MakeTestStream(DEFAULT_PRIORITY);
  138. std::unique_ptr<SpdyStream> stream2 = MakeTestStream(DEFAULT_PRIORITY);
  139. std::unique_ptr<SpdyStream> stream3 = MakeTestStream(DEFAULT_PRIORITY);
  140. write_queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::HEADERS,
  141. std::move(producer1), stream1->GetWeakPtr(),
  142. TRAFFIC_ANNOTATION_FOR_TESTS);
  143. write_queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::HEADERS,
  144. std::move(producer2), stream2->GetWeakPtr(),
  145. TRAFFIC_ANNOTATION_FOR_TESTS);
  146. write_queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::RST_STREAM,
  147. std::move(producer3), stream3->GetWeakPtr(),
  148. TRAFFIC_ANNOTATION_FOR_TESTS);
  149. spdy::SpdyFrameType frame_type = spdy::SpdyFrameType::DATA;
  150. std::unique_ptr<SpdyBufferProducer> frame_producer;
  151. base::WeakPtr<SpdyStream> stream;
  152. MutableNetworkTrafficAnnotationTag traffic_annotation;
  153. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  154. &traffic_annotation));
  155. EXPECT_EQ(spdy::SpdyFrameType::HEADERS, frame_type);
  156. EXPECT_EQ(1, ProducerToInt(std::move(frame_producer)));
  157. EXPECT_EQ(stream1.get(), stream.get());
  158. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  159. &traffic_annotation));
  160. EXPECT_EQ(spdy::SpdyFrameType::HEADERS, frame_type);
  161. EXPECT_EQ(2, ProducerToInt(std::move(frame_producer)));
  162. EXPECT_EQ(stream2.get(), stream.get());
  163. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  164. &traffic_annotation));
  165. EXPECT_EQ(spdy::SpdyFrameType::RST_STREAM, frame_type);
  166. EXPECT_EQ(3, ProducerToInt(std::move(frame_producer)));
  167. EXPECT_EQ(stream3.get(), stream.get());
  168. EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  169. &traffic_annotation));
  170. }
  171. // Enqueue a bunch of writes and then call
  172. // RemovePendingWritesForStream() on one of the streams. No dequeued
  173. // write should be for that stream.
  174. TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) {
  175. SpdyWriteQueue write_queue;
  176. std::unique_ptr<SpdyStream> stream1 = MakeTestStream(DEFAULT_PRIORITY);
  177. std::unique_ptr<SpdyStream> stream2 = MakeTestStream(DEFAULT_PRIORITY);
  178. for (int i = 0; i < 100; ++i) {
  179. base::WeakPtr<SpdyStream> stream =
  180. (((i % 3) == 0) ? stream1 : stream2)->GetWeakPtr();
  181. write_queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::HEADERS,
  182. IntToProducer(i), stream, TRAFFIC_ANNOTATION_FOR_TESTS);
  183. }
  184. write_queue.RemovePendingWritesForStream(stream2.get());
  185. for (int i = 0; i < 100; i += 3) {
  186. spdy::SpdyFrameType frame_type = spdy::SpdyFrameType::DATA;
  187. std::unique_ptr<SpdyBufferProducer> frame_producer;
  188. base::WeakPtr<SpdyStream> stream;
  189. MutableNetworkTrafficAnnotationTag traffic_annotation;
  190. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  191. &traffic_annotation));
  192. EXPECT_EQ(spdy::SpdyFrameType::HEADERS, frame_type);
  193. EXPECT_EQ(i, ProducerToInt(std::move(frame_producer)));
  194. EXPECT_EQ(stream1.get(), stream.get());
  195. EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
  196. traffic_annotation);
  197. }
  198. spdy::SpdyFrameType frame_type = spdy::SpdyFrameType::DATA;
  199. std::unique_ptr<SpdyBufferProducer> frame_producer;
  200. base::WeakPtr<SpdyStream> stream;
  201. MutableNetworkTrafficAnnotationTag traffic_annotation;
  202. EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  203. &traffic_annotation));
  204. }
  205. // Enqueue a bunch of writes and then call
  206. // RemovePendingWritesForStreamsAfter(). No dequeued write should be for
  207. // those streams without a stream id, or with a stream_id after that
  208. // argument.
  209. TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStreamsAfter) {
  210. SpdyWriteQueue write_queue;
  211. std::unique_ptr<SpdyStream> stream1 = MakeTestStream(DEFAULT_PRIORITY);
  212. stream1->set_stream_id(1);
  213. std::unique_ptr<SpdyStream> stream2 = MakeTestStream(DEFAULT_PRIORITY);
  214. stream2->set_stream_id(3);
  215. std::unique_ptr<SpdyStream> stream3 = MakeTestStream(DEFAULT_PRIORITY);
  216. stream3->set_stream_id(5);
  217. // No stream id assigned.
  218. std::unique_ptr<SpdyStream> stream4 = MakeTestStream(DEFAULT_PRIORITY);
  219. base::WeakPtr<SpdyStream> streams[] = {
  220. stream1->GetWeakPtr(), stream2->GetWeakPtr(),
  221. stream3->GetWeakPtr(), stream4->GetWeakPtr()
  222. };
  223. for (int i = 0; i < 100; ++i) {
  224. write_queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::HEADERS,
  225. IntToProducer(i), streams[i % std::size(streams)],
  226. TRAFFIC_ANNOTATION_FOR_TESTS);
  227. }
  228. write_queue.RemovePendingWritesForStreamsAfter(stream1->stream_id());
  229. for (int i = 0; i < 100; i += std::size(streams)) {
  230. spdy::SpdyFrameType frame_type = spdy::SpdyFrameType::DATA;
  231. std::unique_ptr<SpdyBufferProducer> frame_producer;
  232. base::WeakPtr<SpdyStream> stream;
  233. MutableNetworkTrafficAnnotationTag traffic_annotation;
  234. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  235. &traffic_annotation))
  236. << "Unable to Dequeue i: " << i;
  237. EXPECT_EQ(spdy::SpdyFrameType::HEADERS, frame_type);
  238. EXPECT_EQ(i, ProducerToInt(std::move(frame_producer)));
  239. EXPECT_EQ(stream1.get(), stream.get());
  240. EXPECT_EQ(MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
  241. traffic_annotation);
  242. }
  243. spdy::SpdyFrameType frame_type = spdy::SpdyFrameType::DATA;
  244. std::unique_ptr<SpdyBufferProducer> frame_producer;
  245. base::WeakPtr<SpdyStream> stream;
  246. MutableNetworkTrafficAnnotationTag traffic_annotation;
  247. EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  248. &traffic_annotation));
  249. }
  250. // Enqueue a bunch of writes and then call Clear(). The write queue
  251. // should clean up the memory properly, and Dequeue() should return
  252. // false.
  253. TEST_F(SpdyWriteQueueTest, Clear) {
  254. SpdyWriteQueue write_queue;
  255. for (int i = 0; i < 100; ++i) {
  256. write_queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::HEADERS,
  257. IntToProducer(i), base::WeakPtr<SpdyStream>(),
  258. TRAFFIC_ANNOTATION_FOR_TESTS);
  259. }
  260. write_queue.Clear();
  261. spdy::SpdyFrameType frame_type = spdy::SpdyFrameType::DATA;
  262. std::unique_ptr<SpdyBufferProducer> frame_producer;
  263. base::WeakPtr<SpdyStream> stream;
  264. MutableNetworkTrafficAnnotationTag traffic_annotation;
  265. EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  266. &traffic_annotation));
  267. }
  268. TEST_F(SpdyWriteQueueTest, RequeingProducerWithoutReentrance) {
  269. SpdyWriteQueue queue;
  270. queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::HEADERS,
  271. std::make_unique<RequeingBufferProducer>(&queue),
  272. base::WeakPtr<SpdyStream>(), TRAFFIC_ANNOTATION_FOR_TESTS);
  273. {
  274. spdy::SpdyFrameType frame_type;
  275. std::unique_ptr<SpdyBufferProducer> producer;
  276. base::WeakPtr<SpdyStream> stream;
  277. MutableNetworkTrafficAnnotationTag traffic_annotation;
  278. EXPECT_TRUE(
  279. queue.Dequeue(&frame_type, &producer, &stream, &traffic_annotation));
  280. EXPECT_TRUE(queue.IsEmpty());
  281. EXPECT_EQ(std::string(kOriginal),
  282. producer->ProduceBuffer()->GetRemainingData());
  283. }
  284. // |producer| was destroyed, and a buffer is re-queued.
  285. EXPECT_FALSE(queue.IsEmpty());
  286. spdy::SpdyFrameType frame_type;
  287. std::unique_ptr<SpdyBufferProducer> producer;
  288. base::WeakPtr<SpdyStream> stream;
  289. MutableNetworkTrafficAnnotationTag traffic_annotation;
  290. EXPECT_TRUE(
  291. queue.Dequeue(&frame_type, &producer, &stream, &traffic_annotation));
  292. EXPECT_EQ(std::string(kRequeued),
  293. producer->ProduceBuffer()->GetRemainingData());
  294. }
  295. TEST_F(SpdyWriteQueueTest, ReentranceOnClear) {
  296. SpdyWriteQueue queue;
  297. queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::HEADERS,
  298. std::make_unique<RequeingBufferProducer>(&queue),
  299. base::WeakPtr<SpdyStream>(), TRAFFIC_ANNOTATION_FOR_TESTS);
  300. queue.Clear();
  301. EXPECT_FALSE(queue.IsEmpty());
  302. spdy::SpdyFrameType frame_type;
  303. std::unique_ptr<SpdyBufferProducer> producer;
  304. base::WeakPtr<SpdyStream> stream;
  305. MutableNetworkTrafficAnnotationTag traffic_annotation;
  306. EXPECT_TRUE(
  307. queue.Dequeue(&frame_type, &producer, &stream, &traffic_annotation));
  308. EXPECT_EQ(std::string(kRequeued),
  309. producer->ProduceBuffer()->GetRemainingData());
  310. }
  311. TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesAfter) {
  312. std::unique_ptr<SpdyStream> stream = MakeTestStream(DEFAULT_PRIORITY);
  313. stream->set_stream_id(2);
  314. SpdyWriteQueue queue;
  315. queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::HEADERS,
  316. std::make_unique<RequeingBufferProducer>(&queue),
  317. stream->GetWeakPtr(), TRAFFIC_ANNOTATION_FOR_TESTS);
  318. queue.RemovePendingWritesForStreamsAfter(1);
  319. EXPECT_FALSE(queue.IsEmpty());
  320. spdy::SpdyFrameType frame_type;
  321. std::unique_ptr<SpdyBufferProducer> producer;
  322. base::WeakPtr<SpdyStream> weak_stream;
  323. MutableNetworkTrafficAnnotationTag traffic_annotation;
  324. EXPECT_TRUE(
  325. queue.Dequeue(&frame_type, &producer, &weak_stream, &traffic_annotation));
  326. EXPECT_EQ(std::string(kRequeued),
  327. producer->ProduceBuffer()->GetRemainingData());
  328. }
  329. TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesForStream) {
  330. std::unique_ptr<SpdyStream> stream = MakeTestStream(DEFAULT_PRIORITY);
  331. stream->set_stream_id(2);
  332. SpdyWriteQueue queue;
  333. queue.Enqueue(DEFAULT_PRIORITY, spdy::SpdyFrameType::HEADERS,
  334. std::make_unique<RequeingBufferProducer>(&queue),
  335. stream->GetWeakPtr(), TRAFFIC_ANNOTATION_FOR_TESTS);
  336. queue.RemovePendingWritesForStream(stream.get());
  337. EXPECT_FALSE(queue.IsEmpty());
  338. spdy::SpdyFrameType frame_type;
  339. std::unique_ptr<SpdyBufferProducer> producer;
  340. base::WeakPtr<SpdyStream> weak_stream;
  341. MutableNetworkTrafficAnnotationTag traffic_annotation;
  342. EXPECT_TRUE(
  343. queue.Dequeue(&frame_type, &producer, &weak_stream, &traffic_annotation));
  344. EXPECT_EQ(std::string(kRequeued),
  345. producer->ProduceBuffer()->GetRemainingData());
  346. }
  347. TEST_F(SpdyWriteQueueTest, ChangePriority) {
  348. SpdyWriteQueue write_queue;
  349. std::unique_ptr<SpdyBufferProducer> producer1 = IntToProducer(1);
  350. std::unique_ptr<SpdyBufferProducer> producer2 = IntToProducer(2);
  351. std::unique_ptr<SpdyBufferProducer> producer3 = IntToProducer(3);
  352. std::unique_ptr<SpdyStream> stream1 = MakeTestStream(HIGHEST);
  353. std::unique_ptr<SpdyStream> stream2 = MakeTestStream(MEDIUM);
  354. std::unique_ptr<SpdyStream> stream3 = MakeTestStream(LOW);
  355. write_queue.Enqueue(HIGHEST, spdy::SpdyFrameType::HEADERS,
  356. std::move(producer1), stream1->GetWeakPtr(),
  357. TRAFFIC_ANNOTATION_FOR_TESTS);
  358. write_queue.Enqueue(MEDIUM, spdy::SpdyFrameType::DATA, std::move(producer2),
  359. stream2->GetWeakPtr(), TRAFFIC_ANNOTATION_FOR_TESTS);
  360. write_queue.Enqueue(LOW, spdy::SpdyFrameType::RST_STREAM,
  361. std::move(producer3), stream3->GetWeakPtr(),
  362. TRAFFIC_ANNOTATION_FOR_TESTS);
  363. write_queue.ChangePriorityOfWritesForStream(stream3.get(), LOW, HIGHEST);
  364. spdy::SpdyFrameType frame_type = spdy::SpdyFrameType::DATA;
  365. std::unique_ptr<SpdyBufferProducer> frame_producer;
  366. base::WeakPtr<SpdyStream> stream;
  367. MutableNetworkTrafficAnnotationTag traffic_annotation;
  368. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  369. &traffic_annotation));
  370. EXPECT_EQ(spdy::SpdyFrameType::HEADERS, frame_type);
  371. EXPECT_EQ(1, ProducerToInt(std::move(frame_producer)));
  372. EXPECT_EQ(stream1.get(), stream.get());
  373. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  374. &traffic_annotation));
  375. EXPECT_EQ(spdy::SpdyFrameType::RST_STREAM, frame_type);
  376. EXPECT_EQ(3, ProducerToInt(std::move(frame_producer)));
  377. EXPECT_EQ(stream3.get(), stream.get());
  378. ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  379. &traffic_annotation));
  380. EXPECT_EQ(spdy::SpdyFrameType::DATA, frame_type);
  381. EXPECT_EQ(2, ProducerToInt(std::move(frame_producer)));
  382. EXPECT_EQ(stream2.get(), stream.get());
  383. EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream,
  384. &traffic_annotation));
  385. }
  386. } // namespace
  387. } // namespace net