worker_watcher_unittest.cc 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636
  1. // Copyright 2019 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 "components/performance_manager/worker_watcher.h"
  5. #include <memory>
  6. #include <utility>
  7. #include <vector>
  8. #include "base/callback_helpers.h"
  9. #include "base/containers/contains.h"
  10. #include "base/guid.h"
  11. #include "base/observer_list.h"
  12. #include "base/run_loop.h"
  13. #include "base/strings/stringprintf.h"
  14. #include "base/test/bind.h"
  15. #include "base/test/scoped_feature_list.h"
  16. #include "components/performance_manager/frame_node_source.h"
  17. #include "components/performance_manager/graph/frame_node_impl.h"
  18. #include "components/performance_manager/graph/page_node_impl.h"
  19. #include "components/performance_manager/graph/process_node_impl.h"
  20. #include "components/performance_manager/graph/worker_node_impl.h"
  21. #include "components/performance_manager/performance_manager_impl.h"
  22. #include "components/performance_manager/process_node_source.h"
  23. #include "components/performance_manager/public/features.h"
  24. #include "content/public/browser/render_frame_host.h"
  25. #include "content/public/browser/shared_worker_service.h"
  26. #include "content/public/test/browser_task_environment.h"
  27. #include "content/public/test/fake_service_worker_context.h"
  28. #include "testing/gtest/include/gtest/gtest.h"
  29. #include "third_party/blink/public/common/storage_key/storage_key.h"
  30. #include "url/origin.h"
  31. namespace performance_manager {
  32. namespace {
  33. // Generates a new sequential int ID. Used for things that need a unique ID.
  34. int GenerateNextId() {
  35. static int next_id = 0;
  36. return next_id++;
  37. }
  38. // Generates a unique URL for a fake worker node.
  39. GURL GenerateWorkerUrl() {
  40. return GURL(base::StringPrintf("https://www.foo.org/worker_script_%d.js",
  41. GenerateNextId()));
  42. }
  43. // Helper function to check that |worker_node| and |client_frame_node| are
  44. // correctly hooked up together.
  45. bool IsWorkerClient(WorkerNodeImpl* worker_node,
  46. FrameNodeImpl* client_frame_node) {
  47. return base::Contains(worker_node->client_frames(), client_frame_node) &&
  48. base::Contains(client_frame_node->child_worker_nodes(), worker_node);
  49. }
  50. // Helper function to check that |worker_node| and |client_worker_node| are
  51. // correctly hooked up together.
  52. bool IsWorkerClient(WorkerNodeImpl* worker_node,
  53. WorkerNodeImpl* client_worker_node) {
  54. return base::Contains(worker_node->client_workers(), client_worker_node) &&
  55. base::Contains(client_worker_node->child_workers(), worker_node);
  56. }
  57. // TestDedicatedWorkerService --------------------------------------------------
  58. // A test DedicatedWorkerService that allows to simulate creating and destroying
  59. // dedicated workers.
  60. class TestDedicatedWorkerService : public content::DedicatedWorkerService {
  61. public:
  62. TestDedicatedWorkerService();
  63. TestDedicatedWorkerService(const TestDedicatedWorkerService&) = delete;
  64. TestDedicatedWorkerService& operator=(const TestDedicatedWorkerService&) =
  65. delete;
  66. ~TestDedicatedWorkerService() override;
  67. // content::DedicatedWorkerService
  68. void AddObserver(Observer* observer) override;
  69. void RemoveObserver(Observer* observer) override;
  70. void EnumerateDedicatedWorkers(Observer* observer) override;
  71. // Creates a new dedicated worker and returns its ID.
  72. const blink::DedicatedWorkerToken& CreateDedicatedWorker(
  73. int worker_process_id,
  74. content::GlobalRenderFrameHostId client_render_frame_host_id);
  75. // Destroys an existing dedicated worker.
  76. void DestroyDedicatedWorker(const blink::DedicatedWorkerToken& token);
  77. private:
  78. base::ObserverList<Observer> observer_list_;
  79. // Maps each running worker to its client RenderFrameHost ID.
  80. base::flat_map<blink::DedicatedWorkerToken, content::GlobalRenderFrameHostId>
  81. dedicated_worker_client_frame_;
  82. };
  83. TestDedicatedWorkerService::TestDedicatedWorkerService() = default;
  84. TestDedicatedWorkerService::~TestDedicatedWorkerService() = default;
  85. void TestDedicatedWorkerService::AddObserver(Observer* observer) {
  86. observer_list_.AddObserver(observer);
  87. }
  88. void TestDedicatedWorkerService::RemoveObserver(Observer* observer) {
  89. observer_list_.RemoveObserver(observer);
  90. }
  91. void TestDedicatedWorkerService::EnumerateDedicatedWorkers(Observer* observer) {
  92. // Not implemented.
  93. ADD_FAILURE();
  94. }
  95. const blink::DedicatedWorkerToken&
  96. TestDedicatedWorkerService::CreateDedicatedWorker(
  97. int worker_process_id,
  98. content::GlobalRenderFrameHostId client_render_frame_host_id) {
  99. // Create a new token for the worker and add it to the map, along with its
  100. // client ID.
  101. const blink::DedicatedWorkerToken token;
  102. auto result = dedicated_worker_client_frame_.emplace(
  103. token, client_render_frame_host_id);
  104. DCHECK(result.second); // Check inserted.
  105. // Notify observers.
  106. for (auto& observer : observer_list_) {
  107. observer.OnWorkerCreated(token, worker_process_id,
  108. client_render_frame_host_id);
  109. }
  110. return result.first->first;
  111. }
  112. void TestDedicatedWorkerService::DestroyDedicatedWorker(
  113. const blink::DedicatedWorkerToken& token) {
  114. auto it = dedicated_worker_client_frame_.find(token);
  115. DCHECK(it != dedicated_worker_client_frame_.end());
  116. // Notify observers that the worker is being destroyed.
  117. for (auto& observer : observer_list_)
  118. observer.OnBeforeWorkerDestroyed(token, it->second);
  119. // Remove the worker ID from the map.
  120. dedicated_worker_client_frame_.erase(it);
  121. }
  122. // TestSharedWorkerService -----------------------------------------------------
  123. // A test SharedWorkerService that allows to simulate creating and destroying
  124. // shared workers and adding clients to existing workers.
  125. class TestSharedWorkerService : public content::SharedWorkerService {
  126. public:
  127. TestSharedWorkerService();
  128. TestSharedWorkerService(const TestSharedWorkerService&) = delete;
  129. TestSharedWorkerService& operator=(const TestSharedWorkerService&) = delete;
  130. ~TestSharedWorkerService() override;
  131. // content::SharedWorkerService
  132. void AddObserver(Observer* observer) override;
  133. void RemoveObserver(Observer* observer) override;
  134. void EnumerateSharedWorkers(Observer* observer) override;
  135. bool TerminateWorker(const GURL& url,
  136. const std::string& name,
  137. const blink::StorageKey& storage_key) override;
  138. void Shutdown() override;
  139. // Creates a new shared worker and returns its token.
  140. blink::SharedWorkerToken CreateSharedWorker(int worker_process_id);
  141. // Destroys a running shared worker.
  142. void DestroySharedWorker(const blink::SharedWorkerToken& shared_worker_token);
  143. // Adds a new frame client to an existing worker.
  144. void AddClient(const blink::SharedWorkerToken& shared_worker_token,
  145. content::GlobalRenderFrameHostId client_render_frame_host_id);
  146. // Removes an existing frame client from a worker.
  147. void RemoveClient(
  148. const blink::SharedWorkerToken& shared_worker_token,
  149. content::GlobalRenderFrameHostId client_render_frame_host_id);
  150. private:
  151. base::ObserverList<Observer> observer_list_;
  152. // Contains the set of clients for each running workers.
  153. base::flat_map<blink::SharedWorkerToken,
  154. base::flat_set<content::GlobalRenderFrameHostId>>
  155. shared_worker_client_frames_;
  156. };
  157. TestSharedWorkerService::TestSharedWorkerService() = default;
  158. TestSharedWorkerService::~TestSharedWorkerService() = default;
  159. void TestSharedWorkerService::AddObserver(Observer* observer) {
  160. observer_list_.AddObserver(observer);
  161. }
  162. void TestSharedWorkerService::RemoveObserver(Observer* observer) {
  163. observer_list_.RemoveObserver(observer);
  164. }
  165. void TestSharedWorkerService::EnumerateSharedWorkers(Observer* observer) {
  166. // Not implemented.
  167. ADD_FAILURE();
  168. }
  169. bool TestSharedWorkerService::TerminateWorker(
  170. const GURL& url,
  171. const std::string& name,
  172. const blink::StorageKey& storage_key) {
  173. // Not implemented.
  174. ADD_FAILURE();
  175. return false;
  176. }
  177. void TestSharedWorkerService::Shutdown() {
  178. // Not implemented.
  179. ADD_FAILURE();
  180. }
  181. blink::SharedWorkerToken TestSharedWorkerService::CreateSharedWorker(
  182. int worker_process_id) {
  183. // Create a new SharedWorkerToken for the worker and add it to the map.
  184. const blink::SharedWorkerToken shared_worker_token;
  185. bool inserted =
  186. shared_worker_client_frames_.insert({shared_worker_token, {}}).second;
  187. DCHECK(inserted);
  188. // Notify observers.
  189. for (auto& observer : observer_list_) {
  190. observer.OnWorkerCreated(shared_worker_token, worker_process_id,
  191. base::UnguessableToken::Create());
  192. }
  193. return shared_worker_token;
  194. }
  195. void TestSharedWorkerService::DestroySharedWorker(
  196. const blink::SharedWorkerToken& shared_worker_token) {
  197. auto it = shared_worker_client_frames_.find(shared_worker_token);
  198. DCHECK(it != shared_worker_client_frames_.end());
  199. // The worker should no longer have any clients.
  200. DCHECK(it->second.empty());
  201. // Notify observers that the worker is being destroyed.
  202. for (auto& observer : observer_list_)
  203. observer.OnBeforeWorkerDestroyed(shared_worker_token);
  204. // Remove the worker ID from the map.
  205. shared_worker_client_frames_.erase(it);
  206. }
  207. void TestSharedWorkerService::AddClient(
  208. const blink::SharedWorkerToken& shared_worker_token,
  209. content::GlobalRenderFrameHostId client_render_frame_host_id) {
  210. // Add the frame to the set of clients for this worker.
  211. auto it = shared_worker_client_frames_.find(shared_worker_token);
  212. DCHECK(it != shared_worker_client_frames_.end());
  213. base::flat_set<content::GlobalRenderFrameHostId>& client_frames = it->second;
  214. bool inserted = client_frames.insert(client_render_frame_host_id).second;
  215. DCHECK(inserted);
  216. // Then notify observers.
  217. for (auto& observer : observer_list_)
  218. observer.OnClientAdded(shared_worker_token, client_render_frame_host_id);
  219. }
  220. void TestSharedWorkerService::RemoveClient(
  221. const blink::SharedWorkerToken& shared_worker_token,
  222. content::GlobalRenderFrameHostId client_render_frame_host_id) {
  223. // Notify observers.
  224. for (auto& observer : observer_list_)
  225. observer.OnClientRemoved(shared_worker_token, client_render_frame_host_id);
  226. // Then remove the frame from the set of clients of this worker.
  227. auto it = shared_worker_client_frames_.find(shared_worker_token);
  228. DCHECK(it != shared_worker_client_frames_.end());
  229. base::flat_set<content::GlobalRenderFrameHostId>& client_frames = it->second;
  230. size_t removed = client_frames.erase(client_render_frame_host_id);
  231. DCHECK_EQ(removed, 1u);
  232. }
  233. // TestServiceWorkerContext ----------------------------------------------------
  234. // A test ServiceWorkerContext that allows to simulate a worker starting and
  235. // stopping and adding clients to running workers.
  236. //
  237. // Extends content::FakeServiceWorkerContext to avoid reimplementing all the
  238. // unused virtual functions.
  239. class TestServiceWorkerContext : public content::FakeServiceWorkerContext {
  240. public:
  241. TestServiceWorkerContext();
  242. ~TestServiceWorkerContext() override;
  243. TestServiceWorkerContext(const TestServiceWorkerContext&) = delete;
  244. TestServiceWorkerContext& operator=(const TestServiceWorkerContext&) = delete;
  245. // content::FakeServiceWorkerContext:
  246. void AddObserver(content::ServiceWorkerContextObserver* observer) override;
  247. void RemoveObserver(content::ServiceWorkerContextObserver* observer) override;
  248. // Creates a new service worker and returns its version ID.
  249. int64_t CreateServiceWorker();
  250. // Deletes an existing service worker.
  251. void DestroyServiceWorker(int64_t version_id);
  252. // Starts an existing service worker.
  253. void StartServiceWorker(int64_t version_id, int worker_process_id);
  254. // Stops a service shared worker.
  255. void StopServiceWorker(int64_t version_id);
  256. // Adds a new client to an existing service worker and returns its generated
  257. // client UUID.
  258. std::string AddClient(int64_t version_id,
  259. const content::ServiceWorkerClientInfo& client_info);
  260. // Adds a new client to an existing service worker with the provided
  261. // client UUID. Returns |client_uuid| for convenience.
  262. std::string AddClientWithClientID(
  263. int64_t version_id,
  264. std::string client_uuid,
  265. const content::ServiceWorkerClientInfo& client_info);
  266. // Removes an existing client from a worker.
  267. void RemoveClient(int64_t version_id, const std::string& client_uuid);
  268. // Simulates when the navigation commits, meaning that the RenderFrameHost is
  269. // now available for a window client. Not valid for worker clients.
  270. void OnControlleeNavigationCommitted(
  271. int64_t version_id,
  272. const std::string& client_uuid,
  273. content::GlobalRenderFrameHostId render_frame_host_id);
  274. private:
  275. base::ObserverList<content::ServiceWorkerContextObserver>::Unchecked
  276. observer_list_;
  277. // The ID that the next service worker will be assigned.
  278. int64_t next_service_worker_instance_id_ = 0;
  279. struct ServiceWorkerInfo {
  280. bool is_running = false;
  281. // Contains all the clients
  282. base::flat_set<std::string /*client_uuid*/> clients;
  283. };
  284. base::flat_map<int64_t /*version_id*/, ServiceWorkerInfo>
  285. service_worker_infos_;
  286. };
  287. TestServiceWorkerContext::TestServiceWorkerContext() = default;
  288. TestServiceWorkerContext::~TestServiceWorkerContext() = default;
  289. void TestServiceWorkerContext::AddObserver(
  290. content::ServiceWorkerContextObserver* observer) {
  291. observer_list_.AddObserver(observer);
  292. }
  293. void TestServiceWorkerContext::RemoveObserver(
  294. content::ServiceWorkerContextObserver* observer) {
  295. observer_list_.RemoveObserver(observer);
  296. }
  297. int64_t TestServiceWorkerContext::CreateServiceWorker() {
  298. // Create a new version ID and add it to the map.
  299. int64_t version_id = next_service_worker_instance_id_++;
  300. bool inserted = service_worker_infos_.insert({version_id, {}}).second;
  301. DCHECK(inserted);
  302. return version_id;
  303. }
  304. void TestServiceWorkerContext::DestroyServiceWorker(int64_t version_id) {
  305. auto it = service_worker_infos_.find(version_id);
  306. DCHECK(it != service_worker_infos_.end());
  307. const ServiceWorkerInfo& info = it->second;
  308. // Can only delete a service worker that isn't running and has no clients.
  309. DCHECK(!info.is_running);
  310. DCHECK(info.clients.empty());
  311. // Remove the worker instance from the map.
  312. service_worker_infos_.erase(it);
  313. }
  314. void TestServiceWorkerContext::StartServiceWorker(int64_t version_id,
  315. int worker_process_id) {
  316. auto it = service_worker_infos_.find(version_id);
  317. DCHECK(it != service_worker_infos_.end());
  318. ServiceWorkerInfo& info = it->second;
  319. DCHECK(!info.is_running);
  320. info.is_running = true;
  321. // Notify observers.
  322. GURL worker_url = GenerateWorkerUrl();
  323. GURL scope_url;
  324. for (auto& observer : observer_list_) {
  325. observer.OnVersionStartedRunning(
  326. version_id, content::ServiceWorkerRunningInfo(
  327. worker_url, scope_url,
  328. blink::StorageKey(url::Origin::Create(scope_url)),
  329. worker_process_id, blink::ServiceWorkerToken()));
  330. }
  331. }
  332. void TestServiceWorkerContext::StopServiceWorker(int64_t version_id) {
  333. auto it = service_worker_infos_.find(version_id);
  334. DCHECK(it != service_worker_infos_.end());
  335. ServiceWorkerInfo& info = it->second;
  336. DCHECK(info.is_running);
  337. info.is_running = false;
  338. // Notify observers that the worker is terminating.
  339. for (auto& observer : observer_list_)
  340. observer.OnVersionStoppedRunning(version_id);
  341. }
  342. std::string TestServiceWorkerContext::AddClient(
  343. int64_t version_id,
  344. const content::ServiceWorkerClientInfo& client_info) {
  345. return AddClientWithClientID(version_id, base::GenerateGUID(), client_info);
  346. }
  347. std::string TestServiceWorkerContext::AddClientWithClientID(
  348. int64_t version_id,
  349. std::string client_uuid,
  350. const content::ServiceWorkerClientInfo& client_info) {
  351. auto it = service_worker_infos_.find(version_id);
  352. DCHECK(it != service_worker_infos_.end());
  353. ServiceWorkerInfo& info = it->second;
  354. bool inserted = info.clients.insert(client_uuid).second;
  355. DCHECK(inserted);
  356. for (auto& observer : observer_list_)
  357. observer.OnControlleeAdded(version_id, client_uuid, client_info);
  358. return client_uuid;
  359. }
  360. void TestServiceWorkerContext::RemoveClient(int64_t version_id,
  361. const std::string& client_uuid) {
  362. auto it = service_worker_infos_.find(version_id);
  363. DCHECK(it != service_worker_infos_.end());
  364. ServiceWorkerInfo& info = it->second;
  365. size_t removed = info.clients.erase(client_uuid);
  366. DCHECK_EQ(removed, 1u);
  367. for (auto& observer : observer_list_)
  368. observer.OnControlleeRemoved(version_id, client_uuid);
  369. }
  370. void TestServiceWorkerContext::OnControlleeNavigationCommitted(
  371. int64_t version_id,
  372. const std::string& client_uuid,
  373. content::GlobalRenderFrameHostId render_frame_host_id) {
  374. auto it = service_worker_infos_.find(version_id);
  375. DCHECK(it != service_worker_infos_.end());
  376. ServiceWorkerInfo& info = it->second;
  377. DCHECK(base::Contains(info.clients, client_uuid));
  378. for (auto& observer : observer_list_) {
  379. observer.OnControlleeNavigationCommitted(version_id, client_uuid,
  380. render_frame_host_id);
  381. }
  382. }
  383. // TestProcessNodeSource -------------------------------------------------------
  384. // A test ProcessNodeSource that allows creating process nodes on demand to
  385. // "host" frames and workers.
  386. class TestProcessNodeSource : public ProcessNodeSource {
  387. public:
  388. TestProcessNodeSource();
  389. TestProcessNodeSource(const TestProcessNodeSource&) = delete;
  390. TestProcessNodeSource& operator=(const TestProcessNodeSource&) = delete;
  391. ~TestProcessNodeSource() override;
  392. // ProcessNodeSource:
  393. ProcessNodeImpl* GetProcessNode(int render_process_id) override;
  394. // Creates a process node and returns its generated render process ID.
  395. int CreateProcessNode();
  396. private:
  397. // Maps render process IDs with their associated process node.
  398. base::flat_map<int, std::unique_ptr<ProcessNodeImpl>> process_node_map_;
  399. };
  400. TestProcessNodeSource::TestProcessNodeSource() = default;
  401. TestProcessNodeSource::~TestProcessNodeSource() {
  402. std::vector<std::unique_ptr<NodeBase>> nodes;
  403. nodes.reserve(process_node_map_.size());
  404. for (auto& kv : process_node_map_) {
  405. std::unique_ptr<ProcessNodeImpl> process_node = std::move(kv.second);
  406. nodes.push_back(std::move(process_node));
  407. }
  408. PerformanceManagerImpl::BatchDeleteNodes(std::move(nodes));
  409. process_node_map_.clear();
  410. }
  411. ProcessNodeImpl* TestProcessNodeSource::GetProcessNode(int render_process_id) {
  412. auto it = process_node_map_.find(render_process_id);
  413. DCHECK(it != process_node_map_.end());
  414. return it->second.get();
  415. }
  416. int TestProcessNodeSource::CreateProcessNode() {
  417. // Generate a render process ID for this process node.
  418. int render_process_id = GenerateNextId();
  419. // Create the process node and insert it into the map.
  420. auto process_node = PerformanceManagerImpl::CreateProcessNode(
  421. content::PROCESS_TYPE_RENDERER, RenderProcessHostProxy());
  422. bool inserted =
  423. process_node_map_.insert({render_process_id, std::move(process_node)})
  424. .second;
  425. DCHECK(inserted);
  426. return render_process_id;
  427. }
  428. // TestFrameNodeSource ---------------------------------------------------------
  429. class TestFrameNodeSource : public FrameNodeSource {
  430. public:
  431. TestFrameNodeSource();
  432. TestFrameNodeSource(const TestFrameNodeSource&) = delete;
  433. TestFrameNodeSource& operator=(const TestFrameNodeSource&) = delete;
  434. ~TestFrameNodeSource() override;
  435. // FrameNodeSource:
  436. FrameNodeImpl* GetFrameNode(
  437. content::GlobalRenderFrameHostId render_frame_host_id) override;
  438. void SubscribeToFrameNode(
  439. content::GlobalRenderFrameHostId render_frame_host_id,
  440. OnbeforeFrameNodeRemovedCallback on_before_frame_node_removed_callback)
  441. override;
  442. void UnsubscribeFromFrameNode(
  443. content::GlobalRenderFrameHostId render_frame_host_id) override;
  444. // Creates a frame node and returns its generated render frame host id.
  445. content::GlobalRenderFrameHostId CreateFrameNode(
  446. int render_process_id,
  447. ProcessNodeImpl* process_node);
  448. // Deletes an existing frame node and notify subscribers.
  449. void DeleteFrameNode(content::GlobalRenderFrameHostId render_frame_host_id);
  450. private:
  451. // Helper function that invokes the OnBeforeFrameNodeRemovedCallback
  452. // associated with |frame_node| and removes it from the map.
  453. void InvokeAndRemoveCallback(FrameNodeImpl* frame_node);
  454. // The page node that hosts all frames.
  455. std::unique_ptr<PageNodeImpl> page_node_;
  456. // Maps each frame's render frame host id with their associated frame node.
  457. base::flat_map<content::GlobalRenderFrameHostId,
  458. std::unique_ptr<FrameNodeImpl>>
  459. frame_node_map_;
  460. // Maps each observed frame node to their callback.
  461. base::flat_map<FrameNodeImpl*, OnbeforeFrameNodeRemovedCallback>
  462. frame_node_callbacks_;
  463. };
  464. TestFrameNodeSource::TestFrameNodeSource()
  465. : page_node_(PerformanceManagerImpl::CreatePageNode(
  466. WebContentsProxy(),
  467. "page_node_context_id",
  468. GURL(),
  469. false,
  470. false,
  471. base::TimeTicks::Now(),
  472. PageNode::PageState::kActive)) {}
  473. TestFrameNodeSource::~TestFrameNodeSource() {
  474. std::vector<std::unique_ptr<NodeBase>> nodes;
  475. nodes.push_back(std::move(page_node_));
  476. nodes.reserve(frame_node_map_.size());
  477. for (auto& kv : frame_node_map_)
  478. nodes.push_back(std::move(kv.second));
  479. PerformanceManagerImpl::BatchDeleteNodes(std::move(nodes));
  480. frame_node_map_.clear();
  481. }
  482. FrameNodeImpl* TestFrameNodeSource::GetFrameNode(
  483. content::GlobalRenderFrameHostId render_frame_host_id) {
  484. auto it = frame_node_map_.find(render_frame_host_id);
  485. return it != frame_node_map_.end() ? it->second.get() : nullptr;
  486. }
  487. void TestFrameNodeSource::SubscribeToFrameNode(
  488. content::GlobalRenderFrameHostId render_frame_host_id,
  489. OnbeforeFrameNodeRemovedCallback on_before_frame_node_removed_callback) {
  490. FrameNodeImpl* frame_node = GetFrameNode(render_frame_host_id);
  491. DCHECK(frame_node);
  492. bool inserted =
  493. frame_node_callbacks_
  494. .emplace(frame_node, std::move(on_before_frame_node_removed_callback))
  495. .second;
  496. DCHECK(inserted);
  497. }
  498. void TestFrameNodeSource::UnsubscribeFromFrameNode(
  499. content::GlobalRenderFrameHostId render_frame_host_id) {
  500. FrameNodeImpl* frame_node = GetFrameNode(render_frame_host_id);
  501. DCHECK(frame_node);
  502. size_t removed = frame_node_callbacks_.erase(frame_node);
  503. DCHECK_EQ(removed, 1u);
  504. }
  505. content::GlobalRenderFrameHostId TestFrameNodeSource::CreateFrameNode(
  506. int render_process_id,
  507. ProcessNodeImpl* process_node) {
  508. int frame_id = GenerateNextId();
  509. content::GlobalRenderFrameHostId render_frame_host_id(render_process_id,
  510. frame_id);
  511. auto frame_node = PerformanceManagerImpl::CreateFrameNode(
  512. process_node, page_node_.get(), nullptr, frame_id,
  513. blink::LocalFrameToken(), content::BrowsingInstanceId(0),
  514. content::SiteInstanceId(0));
  515. bool inserted =
  516. frame_node_map_.insert({render_frame_host_id, std::move(frame_node)})
  517. .second;
  518. DCHECK(inserted);
  519. return render_frame_host_id;
  520. }
  521. void TestFrameNodeSource::DeleteFrameNode(
  522. content::GlobalRenderFrameHostId render_frame_host_id) {
  523. auto it = frame_node_map_.find(render_frame_host_id);
  524. DCHECK(it != frame_node_map_.end());
  525. FrameNodeImpl* frame_node = it->second.get();
  526. // Notify the subscriber then delete the node.
  527. InvokeAndRemoveCallback(frame_node);
  528. PerformanceManagerImpl::DeleteNode(std::move(it->second));
  529. frame_node_map_.erase(it);
  530. }
  531. void TestFrameNodeSource::InvokeAndRemoveCallback(FrameNodeImpl* frame_node) {
  532. auto it = frame_node_callbacks_.find(frame_node);
  533. DCHECK(it != frame_node_callbacks_.end());
  534. std::move(it->second).Run(frame_node);
  535. frame_node_callbacks_.erase(it);
  536. }
  537. } // namespace
  538. class WorkerWatcherTest : public testing::Test {
  539. public:
  540. WorkerWatcherTest();
  541. WorkerWatcherTest(const WorkerWatcherTest&) = delete;
  542. WorkerWatcherTest& operator=(const WorkerWatcherTest&) = delete;
  543. ~WorkerWatcherTest() override;
  544. // testing::Test:
  545. void SetUp() override;
  546. void TearDown() override;
  547. // Wraps a |graph_callback| and ensures the task completes before returning.
  548. void CallOnGraphAndWait(
  549. PerformanceManagerImpl::GraphImplCallback graph_callback);
  550. // Retrieves an existing worker node.
  551. WorkerNodeImpl* GetDedicatedWorkerNode(
  552. const blink::DedicatedWorkerToken& token);
  553. WorkerNodeImpl* GetSharedWorkerNode(
  554. const blink::SharedWorkerToken& shared_worker_token);
  555. WorkerNodeImpl* GetServiceWorkerNode(int64_t version_id);
  556. TestDedicatedWorkerService* dedicated_worker_service() {
  557. return &dedicated_worker_service_;
  558. }
  559. TestSharedWorkerService* shared_worker_service() {
  560. return &shared_worker_service_;
  561. }
  562. TestServiceWorkerContext* service_worker_context() {
  563. return &service_worker_context_;
  564. }
  565. TestProcessNodeSource* process_node_source() {
  566. return process_node_source_.get();
  567. }
  568. TestFrameNodeSource* frame_node_source() { return frame_node_source_.get(); }
  569. protected:
  570. // Test the frame destroyed case with or without service worker relationship
  571. void TestFrameDestroyed(bool enable_service_worker_relationships);
  572. private:
  573. content::BrowserTaskEnvironment task_environment_;
  574. TestDedicatedWorkerService dedicated_worker_service_;
  575. TestSharedWorkerService shared_worker_service_;
  576. TestServiceWorkerContext service_worker_context_;
  577. std::unique_ptr<PerformanceManagerImpl> performance_manager_;
  578. std::unique_ptr<TestProcessNodeSource> process_node_source_;
  579. std::unique_ptr<TestFrameNodeSource> frame_node_source_;
  580. // The WorkerWatcher that's being tested.
  581. std::unique_ptr<WorkerWatcher> worker_watcher_;
  582. };
  583. WorkerWatcherTest::WorkerWatcherTest() = default;
  584. WorkerWatcherTest::~WorkerWatcherTest() = default;
  585. void WorkerWatcherTest::SetUp() {
  586. performance_manager_ = PerformanceManagerImpl::Create(base::DoNothing());
  587. process_node_source_ = std::make_unique<TestProcessNodeSource>();
  588. frame_node_source_ = std::make_unique<TestFrameNodeSource>();
  589. worker_watcher_ = std::make_unique<WorkerWatcher>(
  590. "browser_context_id", &dedicated_worker_service_, &shared_worker_service_,
  591. &service_worker_context_, process_node_source_.get(),
  592. frame_node_source_.get());
  593. }
  594. void WorkerWatcherTest::TearDown() {
  595. // Clean up the performance manager correctly.
  596. worker_watcher_->TearDown();
  597. worker_watcher_ = nullptr;
  598. // Delete the TestFrameNodeSource and the TestProcessNodeSource in
  599. // that order since they own graph nodes.
  600. frame_node_source_ = nullptr;
  601. process_node_source_ = nullptr;
  602. PerformanceManagerImpl::Destroy(std::move(performance_manager_));
  603. }
  604. void WorkerWatcherTest::CallOnGraphAndWait(
  605. PerformanceManagerImpl::GraphImplCallback graph_callback) {
  606. base::RunLoop run_loop;
  607. PerformanceManagerImpl::CallOnGraphImpl(
  608. FROM_HERE,
  609. base::BindLambdaForTesting(
  610. [graph_callback = std::move(graph_callback),
  611. quit_closure = run_loop.QuitClosure()](GraphImpl* graph) mutable {
  612. std::move(graph_callback).Run(graph);
  613. quit_closure.Run();
  614. }));
  615. run_loop.Run();
  616. }
  617. WorkerNodeImpl* WorkerWatcherTest::GetDedicatedWorkerNode(
  618. const blink::DedicatedWorkerToken& token) {
  619. return worker_watcher_->GetDedicatedWorkerNode(token);
  620. }
  621. WorkerNodeImpl* WorkerWatcherTest::GetSharedWorkerNode(
  622. const blink::SharedWorkerToken& shared_worker_token) {
  623. return worker_watcher_->GetSharedWorkerNode(shared_worker_token);
  624. }
  625. WorkerNodeImpl* WorkerWatcherTest::GetServiceWorkerNode(int64_t version_id) {
  626. return worker_watcher_->GetServiceWorkerNode(version_id);
  627. }
  628. // This test creates one dedicated worker.
  629. TEST_F(WorkerWatcherTest, SimpleDedicatedWorker) {
  630. int render_process_id = process_node_source()->CreateProcessNode();
  631. // Create the frame node.
  632. content::GlobalRenderFrameHostId render_frame_host_id =
  633. frame_node_source()->CreateFrameNode(
  634. render_process_id,
  635. process_node_source()->GetProcessNode(render_process_id));
  636. // Create the worker.
  637. const blink::DedicatedWorkerToken token =
  638. dedicated_worker_service()->CreateDedicatedWorker(render_process_id,
  639. render_frame_host_id);
  640. // Check expectations on the graph.
  641. CallOnGraphAndWait(base::BindLambdaForTesting(
  642. [process_node = process_node_source()->GetProcessNode(render_process_id),
  643. worker_node = GetDedicatedWorkerNode(token),
  644. client_frame_node = frame_node_source()->GetFrameNode(
  645. render_frame_host_id)](GraphImpl* graph) {
  646. EXPECT_TRUE(graph->NodeInGraph(worker_node));
  647. EXPECT_EQ(worker_node->worker_type(),
  648. WorkerNode::WorkerType::kDedicated);
  649. EXPECT_EQ(worker_node->process_node(), process_node);
  650. EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node));
  651. }));
  652. // Disconnect and clean up the dedicated worker.
  653. dedicated_worker_service()->DestroyDedicatedWorker(token);
  654. }
  655. // This test creates one shared worker with one client frame.
  656. TEST_F(WorkerWatcherTest, SimpleSharedWorker) {
  657. int render_process_id = process_node_source()->CreateProcessNode();
  658. // Create the frame node.
  659. content::GlobalRenderFrameHostId render_frame_host_id =
  660. frame_node_source()->CreateFrameNode(
  661. render_process_id,
  662. process_node_source()->GetProcessNode(render_process_id));
  663. // Create the worker.
  664. const blink::SharedWorkerToken shared_worker_token =
  665. shared_worker_service()->CreateSharedWorker(render_process_id);
  666. // Connect the frame to the worker.
  667. shared_worker_service()->AddClient(shared_worker_token, render_frame_host_id);
  668. // Check expectations on the graph.
  669. CallOnGraphAndWait(base::BindLambdaForTesting(
  670. [process_node = process_node_source()->GetProcessNode(render_process_id),
  671. worker_node = GetSharedWorkerNode(shared_worker_token),
  672. client_frame_node = frame_node_source()->GetFrameNode(
  673. render_frame_host_id)](GraphImpl* graph) {
  674. EXPECT_TRUE(graph->NodeInGraph(worker_node));
  675. EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kShared);
  676. EXPECT_EQ(worker_node->process_node(), process_node);
  677. EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node));
  678. }));
  679. // Disconnect and clean up the shared worker.
  680. shared_worker_service()->RemoveClient(shared_worker_token,
  681. render_frame_host_id);
  682. shared_worker_service()->DestroySharedWorker(shared_worker_token);
  683. }
  684. // This test creates one service worker with one client frame.
  685. TEST_F(WorkerWatcherTest, ServiceWorkerFrameClient) {
  686. int render_process_id = process_node_source()->CreateProcessNode();
  687. // Create and start the service worker.
  688. int64_t service_worker_version_id =
  689. service_worker_context()->CreateServiceWorker();
  690. service_worker_context()->StartServiceWorker(service_worker_version_id,
  691. render_process_id);
  692. // Add a window client of the service worker.
  693. std::string service_worker_client_uuid = service_worker_context()->AddClient(
  694. service_worker_version_id, content::ServiceWorkerClientInfo());
  695. // Check expectations on the graph.
  696. CallOnGraphAndWait(base::BindLambdaForTesting(
  697. [process_node = process_node_source()->GetProcessNode(render_process_id),
  698. worker_node =
  699. GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) {
  700. EXPECT_TRUE(graph->NodeInGraph(worker_node));
  701. EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kService);
  702. EXPECT_EQ(worker_node->process_node(), process_node);
  703. // The frame can not be connected to the service worker until its
  704. // render frame host is available, which happens when the navigation
  705. // commits.
  706. EXPECT_TRUE(worker_node->client_frames().empty());
  707. }));
  708. // Now simulate the navigation commit.
  709. content::GlobalRenderFrameHostId render_frame_host_id =
  710. frame_node_source()->CreateFrameNode(
  711. render_process_id,
  712. process_node_source()->GetProcessNode(render_process_id));
  713. service_worker_context()->OnControlleeNavigationCommitted(
  714. service_worker_version_id, service_worker_client_uuid,
  715. render_frame_host_id);
  716. // Check expectations on the graph.
  717. CallOnGraphAndWait(base::BindLambdaForTesting(
  718. [process_node = process_node_source()->GetProcessNode(render_process_id),
  719. worker_node = GetServiceWorkerNode(service_worker_version_id),
  720. client_frame_node = frame_node_source()->GetFrameNode(
  721. render_frame_host_id)](GraphImpl* graph) {
  722. EXPECT_TRUE(graph->NodeInGraph(worker_node));
  723. EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kService);
  724. EXPECT_EQ(worker_node->process_node(), process_node);
  725. EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node));
  726. }));
  727. // Disconnect and clean up the service worker.
  728. service_worker_context()->RemoveClient(service_worker_version_id,
  729. service_worker_client_uuid);
  730. service_worker_context()->StopServiceWorker(service_worker_version_id);
  731. service_worker_context()->DestroyServiceWorker(service_worker_version_id);
  732. }
  733. // Ensures that the WorkerWatcher handles the case where a frame with a service
  734. // worker is (briefly?) an uncommitted client of two versions. This presumably
  735. // happens on version update or some such, or perhaps when a frame is a
  736. // bona-fide client of two service workers. Apparently this happens quite
  737. // rarely in the field.
  738. TEST_F(WorkerWatcherTest, ServiceWorkerFrameClientOfTwoWorkers) {
  739. int render_process_id = process_node_source()->CreateProcessNode();
  740. // Create and start both service workers.
  741. int64_t first_service_worker_version_id =
  742. service_worker_context()->CreateServiceWorker();
  743. service_worker_context()->StartServiceWorker(first_service_worker_version_id,
  744. render_process_id);
  745. int64_t second_service_worker_version_id =
  746. service_worker_context()->CreateServiceWorker();
  747. service_worker_context()->StartServiceWorker(second_service_worker_version_id,
  748. render_process_id);
  749. // Add a window client of the service worker.
  750. std::string service_worker_client_uuid = service_worker_context()->AddClient(
  751. first_service_worker_version_id, content::ServiceWorkerClientInfo());
  752. service_worker_context()->AddClientWithClientID(
  753. second_service_worker_version_id, service_worker_client_uuid,
  754. content::ServiceWorkerClientInfo());
  755. // Check expectations on the graph.
  756. CallOnGraphAndWait(base::BindLambdaForTesting(
  757. [process_node = process_node_source()->GetProcessNode(render_process_id),
  758. first_worker_node =
  759. GetServiceWorkerNode(first_service_worker_version_id),
  760. second_worker_node = GetServiceWorkerNode(
  761. second_service_worker_version_id)](GraphImpl* graph) {
  762. EXPECT_TRUE(graph->NodeInGraph(first_worker_node));
  763. EXPECT_EQ(first_worker_node->worker_type(),
  764. WorkerNode::WorkerType::kService);
  765. EXPECT_EQ(first_worker_node->process_node(), process_node);
  766. // The frame was never added as a client of the service worker.
  767. EXPECT_TRUE(first_worker_node->client_frames().empty());
  768. EXPECT_TRUE(graph->NodeInGraph(second_worker_node));
  769. EXPECT_EQ(second_worker_node->worker_type(),
  770. WorkerNode::WorkerType::kService);
  771. EXPECT_EQ(second_worker_node->process_node(), process_node);
  772. // The frame was never added as a client of the service worker.
  773. EXPECT_TRUE(second_worker_node->client_frames().empty());
  774. }));
  775. // Disconnect and clean up the service worker.
  776. service_worker_context()->RemoveClient(first_service_worker_version_id,
  777. service_worker_client_uuid);
  778. service_worker_context()->StopServiceWorker(first_service_worker_version_id);
  779. service_worker_context()->DestroyServiceWorker(
  780. first_service_worker_version_id);
  781. service_worker_context()->RemoveClient(second_service_worker_version_id,
  782. service_worker_client_uuid);
  783. service_worker_context()->StopServiceWorker(second_service_worker_version_id);
  784. service_worker_context()->DestroyServiceWorker(
  785. second_service_worker_version_id);
  786. }
  787. // Ensures that the WorkerWatcher handles the case where a frame with a service
  788. // worker has a double client relationship with a service worker.
  789. // This appears to be happening out in the real world, if quite rarely.
  790. // See https://crbug.com/1143281#c33.
  791. TEST_F(WorkerWatcherTest, ServiceWorkerTwoFrameClientRelationships) {
  792. int render_process_id = process_node_source()->CreateProcessNode();
  793. // Create and start a service worker.
  794. int64_t service_worker_version_id =
  795. service_worker_context()->CreateServiceWorker();
  796. service_worker_context()->StartServiceWorker(service_worker_version_id,
  797. render_process_id);
  798. // Add a window client of the service worker.
  799. std::string first_client_uuid = service_worker_context()->AddClient(
  800. service_worker_version_id, content::ServiceWorkerClientInfo());
  801. // Check expectations on the graph.
  802. CallOnGraphAndWait(base::BindLambdaForTesting(
  803. [process_node = process_node_source()->GetProcessNode(render_process_id),
  804. worker_node =
  805. GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) {
  806. EXPECT_TRUE(graph->NodeInGraph(worker_node));
  807. EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kService);
  808. // The frame was not yet added as a client.
  809. EXPECT_TRUE(worker_node->client_frames().empty());
  810. }));
  811. // Add a second client relationship between the same two entities.
  812. std::string second_client_uuid = service_worker_context()->AddClient(
  813. service_worker_version_id, content::ServiceWorkerClientInfo());
  814. // Now simulate the navigation commit.
  815. content::GlobalRenderFrameHostId render_frame_host_id =
  816. frame_node_source()->CreateFrameNode(
  817. render_process_id,
  818. process_node_source()->GetProcessNode(render_process_id));
  819. service_worker_context()->OnControlleeNavigationCommitted(
  820. service_worker_version_id, first_client_uuid, render_frame_host_id);
  821. CallOnGraphAndWait(base::BindLambdaForTesting(
  822. [process_node = process_node_source()->GetProcessNode(render_process_id),
  823. service_worker_node = GetServiceWorkerNode(service_worker_version_id),
  824. client_frame_node = frame_node_source()->GetFrameNode(
  825. render_frame_host_id)](GraphImpl* graph) {
  826. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  827. EXPECT_EQ(service_worker_node->worker_type(),
  828. WorkerNode::WorkerType::kService);
  829. EXPECT_EQ(1u, service_worker_node->client_frames().size());
  830. EXPECT_TRUE(IsWorkerClient(service_worker_node, client_frame_node));
  831. }));
  832. // Commit the second controllee navigation.
  833. service_worker_context()->OnControlleeNavigationCommitted(
  834. service_worker_version_id, second_client_uuid, render_frame_host_id);
  835. // Verify that the graph is still the same.
  836. CallOnGraphAndWait(base::BindLambdaForTesting(
  837. [process_node = process_node_source()->GetProcessNode(render_process_id),
  838. service_worker_node = GetServiceWorkerNode(service_worker_version_id),
  839. client_frame_node = frame_node_source()->GetFrameNode(
  840. render_frame_host_id)](GraphImpl* graph) {
  841. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  842. EXPECT_EQ(service_worker_node->worker_type(),
  843. WorkerNode::WorkerType::kService);
  844. EXPECT_EQ(1u, service_worker_node->client_frames().size());
  845. EXPECT_TRUE(IsWorkerClient(service_worker_node, client_frame_node));
  846. }));
  847. // Remove the first client relationship.
  848. service_worker_context()->RemoveClient(service_worker_version_id,
  849. first_client_uuid);
  850. // Verify that the graph is still the same.
  851. CallOnGraphAndWait(base::BindLambdaForTesting(
  852. [process_node = process_node_source()->GetProcessNode(render_process_id),
  853. service_worker_node = GetServiceWorkerNode(service_worker_version_id),
  854. client_frame_node = frame_node_source()->GetFrameNode(
  855. render_frame_host_id)](GraphImpl* graph) {
  856. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  857. EXPECT_EQ(service_worker_node->worker_type(),
  858. WorkerNode::WorkerType::kService);
  859. EXPECT_EQ(1u, service_worker_node->client_frames().size());
  860. EXPECT_TRUE(IsWorkerClient(service_worker_node, client_frame_node));
  861. }));
  862. // Teardown.
  863. service_worker_context()->RemoveClient(service_worker_version_id,
  864. second_client_uuid);
  865. service_worker_context()->StopServiceWorker(service_worker_version_id);
  866. service_worker_context()->DestroyServiceWorker(service_worker_version_id);
  867. }
  868. // Ensures that the WorkerWatcher handles the case where a frame with a service
  869. // worker is created but it's navigation is never committed before the
  870. // FrameTreeNode is destroyed.
  871. TEST_F(WorkerWatcherTest, ServiceWorkerFrameClientDestroyedBeforeCommit) {
  872. int render_process_id = process_node_source()->CreateProcessNode();
  873. // Create and start the service worker.
  874. int64_t service_worker_version_id =
  875. service_worker_context()->CreateServiceWorker();
  876. service_worker_context()->StartServiceWorker(service_worker_version_id,
  877. render_process_id);
  878. // Add a window client of the service worker.
  879. std::string service_worker_client_uuid = service_worker_context()->AddClient(
  880. service_worker_version_id, content::ServiceWorkerClientInfo());
  881. // Check expectations on the graph.
  882. CallOnGraphAndWait(base::BindLambdaForTesting(
  883. [process_node = process_node_source()->GetProcessNode(render_process_id),
  884. worker_node =
  885. GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) {
  886. EXPECT_TRUE(graph->NodeInGraph(worker_node));
  887. EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kService);
  888. EXPECT_EQ(worker_node->process_node(), process_node);
  889. // The frame was never added as a client of the service worker.
  890. EXPECT_TRUE(worker_node->client_frames().empty());
  891. }));
  892. // Disconnect and clean up the service worker.
  893. service_worker_context()->RemoveClient(service_worker_version_id,
  894. service_worker_client_uuid);
  895. service_worker_context()->StopServiceWorker(service_worker_version_id);
  896. service_worker_context()->DestroyServiceWorker(service_worker_version_id);
  897. }
  898. TEST_F(WorkerWatcherTest, AllTypesOfServiceWorkerClients) {
  899. int render_process_id = process_node_source()->CreateProcessNode();
  900. // Create and start the service worker.
  901. int64_t service_worker_version_id =
  902. service_worker_context()->CreateServiceWorker();
  903. service_worker_context()->StartServiceWorker(service_worker_version_id,
  904. render_process_id);
  905. // Create a client of each type and connect them to the service worker.
  906. // Frame client.
  907. std::string frame_client_uuid = service_worker_context()->AddClient(
  908. service_worker_version_id, content::ServiceWorkerClientInfo());
  909. content::GlobalRenderFrameHostId render_frame_host_id =
  910. frame_node_source()->CreateFrameNode(
  911. render_process_id,
  912. process_node_source()->GetProcessNode(render_process_id));
  913. service_worker_context()->OnControlleeNavigationCommitted(
  914. service_worker_version_id, frame_client_uuid, render_frame_host_id);
  915. // Dedicated worker client.
  916. blink::DedicatedWorkerToken dedicated_worker_token =
  917. dedicated_worker_service()->CreateDedicatedWorker(render_process_id,
  918. render_frame_host_id);
  919. std::string dedicated_worker_client_uuid =
  920. service_worker_context()->AddClient(
  921. service_worker_version_id,
  922. content::ServiceWorkerClientInfo(dedicated_worker_token));
  923. // Shared worker client.
  924. blink::SharedWorkerToken shared_worker_token =
  925. shared_worker_service()->CreateSharedWorker(render_process_id);
  926. std::string shared_worker_client_uuid = service_worker_context()->AddClient(
  927. service_worker_version_id,
  928. content::ServiceWorkerClientInfo(shared_worker_token));
  929. // Check expectations on the graph.
  930. CallOnGraphAndWait(base::BindLambdaForTesting(
  931. [process_node = process_node_source()->GetProcessNode(render_process_id),
  932. service_worker_node = GetServiceWorkerNode(service_worker_version_id),
  933. client_frame_node =
  934. frame_node_source()->GetFrameNode(render_frame_host_id),
  935. dedicated_worker_node = GetDedicatedWorkerNode(dedicated_worker_token),
  936. shared_worker_node =
  937. GetSharedWorkerNode(shared_worker_token)](GraphImpl* graph) {
  938. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  939. EXPECT_TRUE(IsWorkerClient(service_worker_node, client_frame_node));
  940. EXPECT_TRUE(IsWorkerClient(service_worker_node, dedicated_worker_node));
  941. EXPECT_TRUE(IsWorkerClient(service_worker_node, shared_worker_node));
  942. }));
  943. // Disconnect and clean up the service worker and its clients.
  944. service_worker_context()->RemoveClient(service_worker_version_id,
  945. shared_worker_client_uuid);
  946. shared_worker_service()->DestroySharedWorker(shared_worker_token);
  947. service_worker_context()->RemoveClient(service_worker_version_id,
  948. dedicated_worker_client_uuid);
  949. dedicated_worker_service()->DestroyDedicatedWorker(dedicated_worker_token);
  950. service_worker_context()->RemoveClient(service_worker_version_id,
  951. frame_client_uuid);
  952. service_worker_context()->StopServiceWorker(service_worker_version_id);
  953. service_worker_context()->DestroyServiceWorker(service_worker_version_id);
  954. }
  955. // Tests that the WorkerWatcher can handle the case where the service worker
  956. // starts after it has been assigned a client. In this case, the clients are not
  957. // connected to the service worker until it starts. It also tests that when the
  958. // service worker stops, its existing clients are also disconnected.
  959. TEST_F(WorkerWatcherTest, ServiceWorkerStartsAndStopsWithExistingClients) {
  960. int render_process_id = process_node_source()->CreateProcessNode();
  961. // Create the worker.
  962. int64_t service_worker_version_id =
  963. service_worker_context()->CreateServiceWorker();
  964. // Create a client of each type and connect them to the service worker.
  965. // Frame client.
  966. std::string frame_client_uuid = service_worker_context()->AddClient(
  967. service_worker_version_id, content::ServiceWorkerClientInfo());
  968. content::GlobalRenderFrameHostId render_frame_host_id =
  969. frame_node_source()->CreateFrameNode(
  970. render_process_id,
  971. process_node_source()->GetProcessNode(render_process_id));
  972. service_worker_context()->OnControlleeNavigationCommitted(
  973. service_worker_version_id, frame_client_uuid, render_frame_host_id);
  974. // Dedicated worker client.
  975. blink::DedicatedWorkerToken dedicated_worker_token =
  976. dedicated_worker_service()->CreateDedicatedWorker(render_process_id,
  977. render_frame_host_id);
  978. std::string dedicated_worker_client_uuid =
  979. service_worker_context()->AddClient(
  980. service_worker_version_id,
  981. content::ServiceWorkerClientInfo(dedicated_worker_token));
  982. // Shared worker client.
  983. blink::SharedWorkerToken shared_worker_token =
  984. shared_worker_service()->CreateSharedWorker(render_process_id);
  985. std::string shared_worker_client_uuid = service_worker_context()->AddClient(
  986. service_worker_version_id,
  987. content::ServiceWorkerClientInfo(shared_worker_token));
  988. // The service worker node doesn't even exist yet.
  989. EXPECT_FALSE(GetServiceWorkerNode(service_worker_version_id));
  990. // Check expectations on the graph.
  991. CallOnGraphAndWait(base::BindLambdaForTesting(
  992. [process_node = process_node_source()->GetProcessNode(render_process_id),
  993. frame_node = frame_node_source()->GetFrameNode(render_frame_host_id),
  994. dedicated_worker_node = GetDedicatedWorkerNode(dedicated_worker_token),
  995. shared_worker_node =
  996. GetSharedWorkerNode(shared_worker_token)](GraphImpl* graph) {
  997. // The clients exists in the graph but they are not connected to the
  998. // service worker.
  999. EXPECT_TRUE(graph->NodeInGraph(frame_node));
  1000. EXPECT_TRUE(graph->NodeInGraph(dedicated_worker_node));
  1001. EXPECT_TRUE(graph->NodeInGraph(shared_worker_node));
  1002. // Note: Because a dedicated worker is always connected to a frame, this
  1003. // frame node actually has |dedicated_worker_node| as its sole client.
  1004. ASSERT_EQ(frame_node->child_worker_nodes().size(), 1u);
  1005. EXPECT_TRUE(base::Contains(frame_node->child_worker_nodes(),
  1006. dedicated_worker_node));
  1007. EXPECT_TRUE(dedicated_worker_node->child_workers().empty());
  1008. EXPECT_TRUE(shared_worker_node->child_workers().empty());
  1009. }));
  1010. // Now start the service worker.
  1011. service_worker_context()->StartServiceWorker(service_worker_version_id,
  1012. render_process_id);
  1013. // Check expectations on the graph.
  1014. CallOnGraphAndWait(base::BindLambdaForTesting(
  1015. [process_node = process_node_source()->GetProcessNode(render_process_id),
  1016. service_worker_node = GetServiceWorkerNode(service_worker_version_id),
  1017. frame_node = frame_node_source()->GetFrameNode(render_frame_host_id),
  1018. dedicated_worker_node = GetDedicatedWorkerNode(dedicated_worker_token),
  1019. shared_worker_node =
  1020. GetSharedWorkerNode(shared_worker_token)](GraphImpl* graph) {
  1021. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  1022. EXPECT_EQ(service_worker_node->worker_type(),
  1023. WorkerNode::WorkerType::kService);
  1024. EXPECT_EQ(service_worker_node->process_node(), process_node);
  1025. EXPECT_TRUE(graph->NodeInGraph(frame_node));
  1026. EXPECT_TRUE(graph->NodeInGraph(dedicated_worker_node));
  1027. EXPECT_TRUE(graph->NodeInGraph(shared_worker_node));
  1028. // Now is it correctly hooked up.
  1029. EXPECT_TRUE(IsWorkerClient(service_worker_node, frame_node));
  1030. EXPECT_TRUE(IsWorkerClient(service_worker_node, dedicated_worker_node));
  1031. EXPECT_TRUE(IsWorkerClient(service_worker_node, shared_worker_node));
  1032. }));
  1033. // Stop the service worker. All the clients will be disconnected.
  1034. service_worker_context()->StopServiceWorker(service_worker_version_id);
  1035. // Check expectations on the graph.
  1036. CallOnGraphAndWait(base::BindLambdaForTesting(
  1037. [process_node = process_node_source()->GetProcessNode(render_process_id),
  1038. frame_node = frame_node_source()->GetFrameNode(render_frame_host_id),
  1039. dedicated_worker_node = GetDedicatedWorkerNode(dedicated_worker_token),
  1040. shared_worker_node =
  1041. GetSharedWorkerNode(shared_worker_token)](GraphImpl* graph) {
  1042. // The clients exists in the graph but they are not connected to the
  1043. // service worker.
  1044. EXPECT_TRUE(graph->NodeInGraph(frame_node));
  1045. EXPECT_TRUE(graph->NodeInGraph(dedicated_worker_node));
  1046. EXPECT_TRUE(graph->NodeInGraph(shared_worker_node));
  1047. // Note: Because a dedicated worker is always connected to a frame, this
  1048. // frame node actually has |dedicated_worker_node| as its sole client.
  1049. ASSERT_EQ(frame_node->child_worker_nodes().size(), 1u);
  1050. EXPECT_TRUE(base::Contains(frame_node->child_worker_nodes(),
  1051. dedicated_worker_node));
  1052. EXPECT_TRUE(dedicated_worker_node->child_workers().empty());
  1053. EXPECT_TRUE(shared_worker_node->child_workers().empty());
  1054. }));
  1055. // Disconnect and clean up the service worker and its clients
  1056. service_worker_context()->RemoveClient(service_worker_version_id,
  1057. shared_worker_client_uuid);
  1058. shared_worker_service()->DestroySharedWorker(shared_worker_token);
  1059. service_worker_context()->RemoveClient(service_worker_version_id,
  1060. dedicated_worker_client_uuid);
  1061. dedicated_worker_service()->DestroyDedicatedWorker(dedicated_worker_token);
  1062. service_worker_context()->RemoveClient(service_worker_version_id,
  1063. frame_client_uuid);
  1064. service_worker_context()->DestroyServiceWorker(service_worker_version_id);
  1065. }
  1066. TEST_F(WorkerWatcherTest, SharedWorkerCrossProcessClient) {
  1067. // Create the frame node.
  1068. int frame_process_id = process_node_source()->CreateProcessNode();
  1069. content::GlobalRenderFrameHostId render_frame_host_id =
  1070. frame_node_source()->CreateFrameNode(
  1071. frame_process_id,
  1072. process_node_source()->GetProcessNode(frame_process_id));
  1073. // Create the worker in a different process.
  1074. int worker_process_id = process_node_source()->CreateProcessNode();
  1075. const blink::SharedWorkerToken& shared_worker_token =
  1076. shared_worker_service()->CreateSharedWorker(worker_process_id);
  1077. // Connect the frame to the worker.
  1078. shared_worker_service()->AddClient(shared_worker_token, render_frame_host_id);
  1079. // Check expectations on the graph.
  1080. CallOnGraphAndWait(base::BindLambdaForTesting(
  1081. [worker_process_node =
  1082. process_node_source()->GetProcessNode(worker_process_id),
  1083. worker_node = GetSharedWorkerNode(shared_worker_token),
  1084. client_process_node =
  1085. process_node_source()->GetProcessNode(frame_process_id),
  1086. client_frame_node = frame_node_source()->GetFrameNode(
  1087. render_frame_host_id)](GraphImpl* graph) {
  1088. EXPECT_TRUE(graph->NodeInGraph(worker_node));
  1089. EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kShared);
  1090. EXPECT_EQ(worker_node->process_node(), worker_process_node);
  1091. EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node));
  1092. }));
  1093. // Disconnect and clean up the shared worker.
  1094. shared_worker_service()->RemoveClient(shared_worker_token,
  1095. render_frame_host_id);
  1096. shared_worker_service()->DestroySharedWorker(shared_worker_token);
  1097. }
  1098. // Tests that the WorkerWatcher can handle the case where the service worker
  1099. // starts after it has been assigned a worker client, but the client has
  1100. // already died by the time the service worker starts.
  1101. TEST_F(WorkerWatcherTest, SharedWorkerStartsWithDeadWorkerClients) {
  1102. int render_process_id = process_node_source()->CreateProcessNode();
  1103. content::GlobalRenderFrameHostId render_frame_host_id =
  1104. frame_node_source()->CreateFrameNode(
  1105. render_process_id,
  1106. process_node_source()->GetProcessNode(render_process_id));
  1107. // Create the worker.
  1108. int64_t service_worker_version_id =
  1109. service_worker_context()->CreateServiceWorker();
  1110. // Create a worker client of each type and connect them to the service worker.
  1111. // Dedicated worker client.
  1112. blink::DedicatedWorkerToken dedicated_worker_token =
  1113. dedicated_worker_service()->CreateDedicatedWorker(render_process_id,
  1114. render_frame_host_id);
  1115. std::string dedicated_worker_client_uuid =
  1116. service_worker_context()->AddClient(
  1117. service_worker_version_id,
  1118. content::ServiceWorkerClientInfo(dedicated_worker_token));
  1119. // Shared worker client.
  1120. blink::SharedWorkerToken shared_worker_token =
  1121. shared_worker_service()->CreateSharedWorker(render_process_id);
  1122. std::string shared_worker_client_uuid = service_worker_context()->AddClient(
  1123. service_worker_version_id,
  1124. content::ServiceWorkerClientInfo(shared_worker_token));
  1125. // Destroy the workers before the service worker starts.
  1126. shared_worker_service()->DestroySharedWorker(shared_worker_token);
  1127. dedicated_worker_service()->DestroyDedicatedWorker(dedicated_worker_token);
  1128. // Now start the service worker.
  1129. service_worker_context()->StartServiceWorker(service_worker_version_id,
  1130. render_process_id);
  1131. // Check expectations on the graph.
  1132. CallOnGraphAndWait(base::BindLambdaForTesting(
  1133. [process_node = process_node_source()->GetProcessNode(render_process_id),
  1134. service_worker_node =
  1135. GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) {
  1136. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  1137. EXPECT_EQ(service_worker_node->worker_type(),
  1138. WorkerNode::WorkerType::kService);
  1139. EXPECT_EQ(service_worker_node->process_node(), process_node);
  1140. EXPECT_TRUE(service_worker_node->child_workers().empty());
  1141. }));
  1142. // Disconnect the non-existent clients.
  1143. service_worker_context()->RemoveClient(service_worker_version_id,
  1144. shared_worker_client_uuid);
  1145. service_worker_context()->RemoveClient(service_worker_version_id,
  1146. dedicated_worker_client_uuid);
  1147. // No changes in the graph.
  1148. CallOnGraphAndWait(base::BindLambdaForTesting(
  1149. [process_node = process_node_source()->GetProcessNode(render_process_id),
  1150. service_worker_node =
  1151. GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) {
  1152. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  1153. EXPECT_EQ(service_worker_node->worker_type(),
  1154. WorkerNode::WorkerType::kService);
  1155. EXPECT_EQ(service_worker_node->process_node(), process_node);
  1156. EXPECT_TRUE(service_worker_node->child_workers().empty());
  1157. }));
  1158. // Stop and destroy the service worker.
  1159. service_worker_context()->StopServiceWorker(service_worker_version_id);
  1160. service_worker_context()->DestroyServiceWorker(service_worker_version_id);
  1161. }
  1162. TEST_F(WorkerWatcherTest, SharedWorkerDiesAsServiceWorkerClient) {
  1163. // Create the shared and service workers.
  1164. int render_process_id = process_node_source()->CreateProcessNode();
  1165. const blink::SharedWorkerToken& shared_worker_token =
  1166. shared_worker_service()->CreateSharedWorker(render_process_id);
  1167. int64_t service_worker_version_id =
  1168. service_worker_context()->CreateServiceWorker();
  1169. std::string service_worker_client_uuid = service_worker_context()->AddClient(
  1170. service_worker_version_id,
  1171. content::ServiceWorkerClientInfo(shared_worker_token));
  1172. service_worker_context()->StartServiceWorker(service_worker_version_id,
  1173. render_process_id);
  1174. // Check expectations on the graph.
  1175. CallOnGraphAndWait(base::BindLambdaForTesting(
  1176. [service_worker_node = GetServiceWorkerNode(service_worker_version_id),
  1177. shared_worker_node =
  1178. GetSharedWorkerNode(shared_worker_token)](GraphImpl* graph) {
  1179. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  1180. EXPECT_EQ(service_worker_node->worker_type(),
  1181. WorkerNode::WorkerType::kService);
  1182. EXPECT_TRUE(graph->NodeInGraph(shared_worker_node));
  1183. EXPECT_EQ(shared_worker_node->worker_type(),
  1184. WorkerNode::WorkerType::kShared);
  1185. EXPECT_TRUE(IsWorkerClient(service_worker_node, shared_worker_node));
  1186. }));
  1187. // Destroy the shared worker while it still has a client registration
  1188. // against the service worker.
  1189. shared_worker_service()->DestroySharedWorker(shared_worker_token);
  1190. // Check expectations on the graph again.
  1191. CallOnGraphAndWait(base::BindLambdaForTesting(
  1192. [service_worker_node =
  1193. GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) {
  1194. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  1195. EXPECT_EQ(service_worker_node->worker_type(),
  1196. WorkerNode::WorkerType::kService);
  1197. EXPECT_TRUE(service_worker_node->client_workers().empty());
  1198. }));
  1199. // Issue the trailing service worker client removal.
  1200. service_worker_context()->RemoveClient(service_worker_version_id,
  1201. service_worker_client_uuid);
  1202. }
  1203. TEST_F(WorkerWatcherTest, OneSharedWorkerTwoClients) {
  1204. int render_process_id = process_node_source()->CreateProcessNode();
  1205. // Create the worker.
  1206. const blink::SharedWorkerToken& shared_worker_token =
  1207. shared_worker_service()->CreateSharedWorker(render_process_id);
  1208. // Create 2 client frame nodes and connect them to the worker.
  1209. content::GlobalRenderFrameHostId render_frame_host_id_1 =
  1210. frame_node_source()->CreateFrameNode(
  1211. render_process_id,
  1212. process_node_source()->GetProcessNode(render_process_id));
  1213. shared_worker_service()->AddClient(shared_worker_token,
  1214. render_frame_host_id_1);
  1215. content::GlobalRenderFrameHostId render_frame_host_id_2 =
  1216. frame_node_source()->CreateFrameNode(
  1217. render_process_id,
  1218. process_node_source()->GetProcessNode(render_process_id));
  1219. shared_worker_service()->AddClient(shared_worker_token,
  1220. render_frame_host_id_2);
  1221. // Check expectations on the graph.
  1222. CallOnGraphAndWait(base::BindLambdaForTesting(
  1223. [worker_node = GetSharedWorkerNode(shared_worker_token),
  1224. client_frame_node_1 =
  1225. frame_node_source()->GetFrameNode(render_frame_host_id_1),
  1226. client_frame_node_2 = frame_node_source()->GetFrameNode(
  1227. render_frame_host_id_2)](GraphImpl* graph) {
  1228. EXPECT_TRUE(graph->NodeInGraph(worker_node));
  1229. EXPECT_EQ(worker_node->worker_type(), WorkerNode::WorkerType::kShared);
  1230. // Check frame 1.
  1231. EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node_1));
  1232. // Check frame 2.
  1233. EXPECT_TRUE(IsWorkerClient(worker_node, client_frame_node_2));
  1234. }));
  1235. // Disconnect and clean up the shared worker.
  1236. shared_worker_service()->RemoveClient(shared_worker_token,
  1237. render_frame_host_id_1);
  1238. shared_worker_service()->RemoveClient(shared_worker_token,
  1239. render_frame_host_id_2);
  1240. shared_worker_service()->DestroySharedWorker(shared_worker_token);
  1241. }
  1242. TEST_F(WorkerWatcherTest, OneClientTwoSharedWorkers) {
  1243. int render_process_id = process_node_source()->CreateProcessNode();
  1244. // Create the frame node.
  1245. content::GlobalRenderFrameHostId render_frame_host_id =
  1246. frame_node_source()->CreateFrameNode(
  1247. render_process_id,
  1248. process_node_source()->GetProcessNode(render_process_id));
  1249. // Create the 2 workers and connect them to the frame.
  1250. const blink::SharedWorkerToken& shared_worker_token_1 =
  1251. shared_worker_service()->CreateSharedWorker(render_process_id);
  1252. shared_worker_service()->AddClient(shared_worker_token_1,
  1253. render_frame_host_id);
  1254. const blink::SharedWorkerToken& shared_worker_token_2 =
  1255. shared_worker_service()->CreateSharedWorker(render_process_id);
  1256. shared_worker_service()->AddClient(shared_worker_token_2,
  1257. render_frame_host_id);
  1258. // Check expectations on the graph.
  1259. CallOnGraphAndWait(base::BindLambdaForTesting(
  1260. [worker_node_1 = GetSharedWorkerNode(shared_worker_token_1),
  1261. worker_node_2 = GetSharedWorkerNode(shared_worker_token_2),
  1262. client_frame_node = frame_node_source()->GetFrameNode(
  1263. render_frame_host_id)](GraphImpl* graph) {
  1264. // Check worker 1.
  1265. EXPECT_TRUE(graph->NodeInGraph(worker_node_1));
  1266. EXPECT_EQ(worker_node_1->worker_type(),
  1267. WorkerNode::WorkerType::kShared);
  1268. EXPECT_TRUE(IsWorkerClient(worker_node_1, client_frame_node));
  1269. // Check worker 2.
  1270. EXPECT_TRUE(graph->NodeInGraph(worker_node_2));
  1271. EXPECT_EQ(worker_node_2->worker_type(),
  1272. WorkerNode::WorkerType::kShared);
  1273. EXPECT_TRUE(IsWorkerClient(worker_node_2, client_frame_node));
  1274. }));
  1275. // Disconnect and clean up the shared workers.
  1276. shared_worker_service()->RemoveClient(shared_worker_token_1,
  1277. render_frame_host_id);
  1278. shared_worker_service()->DestroySharedWorker(shared_worker_token_1);
  1279. shared_worker_service()->RemoveClient(shared_worker_token_2,
  1280. render_frame_host_id);
  1281. shared_worker_service()->DestroySharedWorker(shared_worker_token_2);
  1282. }
  1283. TEST_F(WorkerWatcherTest, FrameDestroyed) {
  1284. int render_process_id = process_node_source()->CreateProcessNode();
  1285. // Create the frame node.
  1286. content::GlobalRenderFrameHostId render_frame_host_id =
  1287. frame_node_source()->CreateFrameNode(
  1288. render_process_id,
  1289. process_node_source()->GetProcessNode(render_process_id));
  1290. // Create a worker of each type.
  1291. const blink::DedicatedWorkerToken& dedicated_worker_token =
  1292. dedicated_worker_service()->CreateDedicatedWorker(render_process_id,
  1293. render_frame_host_id);
  1294. const blink::SharedWorkerToken& shared_worker_token =
  1295. shared_worker_service()->CreateSharedWorker(render_process_id);
  1296. int64_t service_worker_version_id =
  1297. service_worker_context()->CreateServiceWorker();
  1298. service_worker_context()->StartServiceWorker(service_worker_version_id,
  1299. render_process_id);
  1300. // Connect the frame to the shared worker and the service worker. Note that it
  1301. // is already connected to the dedicated worker.
  1302. shared_worker_service()->AddClient(shared_worker_token, render_frame_host_id);
  1303. std::string service_worker_client_uuid = service_worker_context()->AddClient(
  1304. service_worker_version_id, content::ServiceWorkerClientInfo());
  1305. service_worker_context()->OnControlleeNavigationCommitted(
  1306. service_worker_version_id, service_worker_client_uuid,
  1307. render_frame_host_id);
  1308. // Check that everything is wired up correctly.
  1309. CallOnGraphAndWait(base::BindLambdaForTesting(
  1310. [dedicated_worker_node = GetDedicatedWorkerNode(dedicated_worker_token),
  1311. shared_worker_node = GetSharedWorkerNode(shared_worker_token),
  1312. service_worker_node = GetServiceWorkerNode(service_worker_version_id),
  1313. client_frame_node = frame_node_source()->GetFrameNode(
  1314. render_frame_host_id)](GraphImpl* graph) {
  1315. EXPECT_TRUE(graph->NodeInGraph(dedicated_worker_node));
  1316. EXPECT_TRUE(graph->NodeInGraph(shared_worker_node));
  1317. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  1318. EXPECT_TRUE(IsWorkerClient(dedicated_worker_node, client_frame_node));
  1319. EXPECT_TRUE(IsWorkerClient(shared_worker_node, client_frame_node));
  1320. EXPECT_TRUE(IsWorkerClient(service_worker_node, client_frame_node));
  1321. }));
  1322. frame_node_source()->DeleteFrameNode(render_frame_host_id);
  1323. // Check that the workers are no longer connected to the deleted frame.
  1324. CallOnGraphAndWait(base::BindLambdaForTesting(
  1325. [dedicated_worker_node = GetDedicatedWorkerNode(dedicated_worker_token),
  1326. shared_worker_node = GetSharedWorkerNode(shared_worker_token),
  1327. service_worker_node =
  1328. GetServiceWorkerNode(service_worker_version_id)](GraphImpl* graph) {
  1329. EXPECT_TRUE(graph->NodeInGraph(dedicated_worker_node));
  1330. EXPECT_TRUE(graph->NodeInGraph(shared_worker_node));
  1331. EXPECT_TRUE(graph->NodeInGraph(service_worker_node));
  1332. EXPECT_TRUE(dedicated_worker_node->client_frames().empty());
  1333. EXPECT_TRUE(shared_worker_node->client_frames().empty());
  1334. EXPECT_TRUE(service_worker_node->client_frames().empty());
  1335. }));
  1336. // Clean up. The watcher is still expecting a worker removed notification.
  1337. service_worker_context()->RemoveClient(service_worker_version_id,
  1338. service_worker_client_uuid);
  1339. service_worker_context()->StopServiceWorker(service_worker_version_id);
  1340. service_worker_context()->DestroyServiceWorker(service_worker_version_id);
  1341. shared_worker_service()->RemoveClient(shared_worker_token,
  1342. render_frame_host_id);
  1343. shared_worker_service()->DestroySharedWorker(shared_worker_token);
  1344. dedicated_worker_service()->DestroyDedicatedWorker(dedicated_worker_token);
  1345. }
  1346. } // namespace performance_manager