File: search_preload_test_response_utils.h

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 (151 lines) | stat: -rw-r--r-- 6,373 bytes parent folder | download | duplicates (3)
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
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_PRELOADING_PREFETCH_SEARCH_PREFETCH_SEARCH_PRELOAD_TEST_RESPONSE_UTILS_H_
#define CHROME_BROWSER_PRELOADING_PREFETCH_SEARCH_PREFETCH_SEARCH_PRELOAD_TEST_RESPONSE_UTILS_H_

#include <queue>

#include "base/functional/callback_forward.h"
#include "base/memory/raw_ptr.h"
#include "base/thread_annotations.h"
#include "net/test/embedded_test_server/embedded_test_server.h"

// Used by SearchPreloadDeferrableResponse and related testing code, to indicate
// whether and what to defer during testing.
enum class SearchPreloadTestResponseDeferralType {
  // Do not defer HTTP responses.
  kNoDeferral = 0,
  // Ddefer the response header only.
  kDeferHeader = 1,
  // Only defer the response body.
  kDeferBody = 2,
  // Defer dispatching response head until a explicit signal, and then block
  // the response until receiving the next signal.
  kDeferHeaderThenBody = 3,
  // Send headers immediately, but defer dispatching the first part of response
  // body and then the remaining part with the complete signal. Note: Callers
  // should guarantee it has provided a valid response content whose size is
  // greater than 1, so that server can split the body.
  kDeferChunkedResponseBody = 4
};

// A test base that allows test fixtures to control when and what to respond.
// For a test class that wants to defer response, it can derive this class, and
// implement its method to utilize the delayed response.
// Sample Usage:
// Define test fixtures:
// Class FooBrowserTest: public SearchPreloadResponseController {
//   ...
//     std::unique_ptr<net::test_server::HttpResponse>
//     HandleSearchRequest(const net::test_server::HttpRequest& request) {
//       // Construct a delayed response.
// ..... Figure out headers, response code, response body, etc.
//       return CreateDeferrableResponse(args);
//     }
//
// };
// For tests:
//  step 1: sets deferral type:
//  set_deferral_type();
//  step 2: make chrome send a request to the server, so then
//  HandleSearchRequest would be executed.
//  step 3: do something
//  step 4: dispatch the delayed part of response by calling
//  DispatchDelayedResponseTask.
// TODO(crbug.com/40219294): This class should be a part of
// SearchPrefetchBaseBrowserTest. Eliminate the differences between
// SearchPreloadUnifiedBrowserTest and SearchPrefetchBaseBrowserTest, such as
// removing duplicated methods from SearchPreloadUnifiedBrowserTest and making
// search prefetch tests run on Android (blocked by Android UI support), so as
// to get rid of this workaround.
class SearchPreloadResponseController {
 public:
  SearchPreloadResponseController();
  virtual ~SearchPreloadResponseController();

  // Called on the thread the server is running. The custom defined responses
  // should call this method if they want to defer the network response.
  void AddDelayedResponseTask(
      const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
      base::OnceClosure response_closure);

 protected:
  // Called on the main thread. This will resume one delayed response.
  void DispatchDelayedResponseTask();

  // Called on the thread that server is running on. The server could create a
  // SearchPreloadDeferrableResponse so that then can control when to dispatch
  // the task that would update the response.
  std::unique_ptr<net::test_server::HttpResponse> CreateDeferrableResponse(
      net::HttpStatusCode code,
      const base::StringPairs& headers,
      const std::string& response_body);

  // Instructs the search service whether to delay the response until
  // receiving a specific signal (From callers' prospective, calling
  // `DispatchDelayedResponseTask`). See comment of
  // `SearchPreloadTestResponseDeferralType` for more information.
  void set_service_deferral_type(
      SearchPreloadTestResponseDeferralType service_deferral_type) {
    service_deferral_type_ = service_deferral_type;
  }

 private:
  // A DelayedResponseTask instance is created on the thread that server is
  // running on, and be destroyed on the main thread. A lock is guarding the
  // access to created instances.
  class DelayedResponseTask;

  SearchPreloadTestResponseDeferralType service_deferral_type_ =
      SearchPreloadTestResponseDeferralType::kNoDeferral;

  std::queue<DelayedResponseTask> delayed_response_tasks_
      GUARDED_BY(response_queue_lock_);
  base::OnceClosure monitor_callback_ GUARDED_BY(response_queue_lock_);
  base::Lock response_queue_lock_;
};

class SearchPreloadDeferrableResponse final
    : public net::test_server::BasicHttpResponse {
 public:
  // Build a custom defined response that might be deferred based on
  // `deferral_type`. See the comment of `SearchPreloadTestResponseDeferralType`
  // for more information about the deferral type. Pass an empty string to
  // `response_body` if the response (note, not the header) should fail.
  SearchPreloadDeferrableResponse(
      SearchPreloadResponseController* test_harness,
      SearchPreloadTestResponseDeferralType deferral_type,
      net::HttpStatusCode code,
      base::StringPairs headers,
      const std::string& response_body);
  ~SearchPreloadDeferrableResponse() override;

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

  // net::test_server::BasicHttpResponse implementation.
  void SendResponse(
      base::WeakPtr<net::test_server::HttpResponseDelegate> delegate) override;

 private:
  // The test fixture that can manipulate the response.
  raw_ptr<SearchPreloadResponseController> test_harness_;

  // The deferral mode. See comment of `SearchPreloadTestResponseDeferralType`
  // for more information.
  const SearchPreloadTestResponseDeferralType service_deferral_type_ =
      SearchPreloadTestResponseDeferralType::kNoDeferral;

  // Predefined response headers.
  const base::StringPairs headers_;

  // Predefined response body. The response body will fail due to the
  // CONTENT_LENGTH_MISMATCH error if it is set to an empty string.
  const std::string body_ = "";
};

#endif  // CHROME_BROWSER_PRELOADING_PREFETCH_SEARCH_PREFETCH_SEARCH_PRELOAD_TEST_RESPONSE_UTILS_H_