First piece of process swapping on navigation.
[WebKit-https.git] / Tools / TestWebKitAPI / Tests / WebKitCocoa / ProcessSwapOnNavigation.mm
1 /*
2  * Copyright (C) 2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #import "config.h"
27
28 #import "PlatformUtilities.h"
29 #import "Test.h"
30 #import <WebKit/WKNavigationDelegate.h>
31 #import <WebKit/WKPreferencesPrivate.h>
32 #import <WebKit/WKProcessPoolPrivate.h>
33 #import <WebKit/WKURLSchemeHandler.h>
34 #import <WebKit/WKURLSchemeTaskPrivate.h>
35 #import <WebKit/WKWebViewConfigurationPrivate.h>
36 #import <WebKit/WKWebViewPrivate.h>
37 #import <WebKit/WKWebsiteDataStorePrivate.h>
38 #import <WebKit/WKWebsiteDataStoreRef.h>
39 #import <WebKit/WebKit.h>
40 #import <WebKit/_WKExperimentalFeature.h>
41 #import <WebKit/_WKProcessPoolConfiguration.h>
42 #import <WebKit/_WKWebsiteDataStoreConfiguration.h>
43 #import <wtf/Deque.h>
44 #import <wtf/HashMap.h>
45 #import <wtf/RetainPtr.h>
46 #import <wtf/Vector.h>
47 #import <wtf/text/StringHash.h>
48 #import <wtf/text/WTFString.h>
49
50 #if WK_API_ENABLED
51
52 static bool done;
53 static int numberOfDecidePolicyCalls;
54
55 @interface PSONNavigationDelegate : NSObject <WKNavigationDelegate>
56 @end
57
58 @implementation PSONNavigationDelegate
59
60 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation
61 {
62     done = true;
63 }
64
65 - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
66 {
67     ++numberOfDecidePolicyCalls;
68     decisionHandler(WKNavigationActionPolicyAllow);
69 }
70
71 @end
72
73 @interface PSONScheme : NSObject <WKURLSchemeHandler> {
74 }
75 @end
76
77 @implementation PSONScheme
78
79 - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task
80 {
81     RetainPtr<NSURLResponse> response = adoptNS([[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html" expectedContentLength:1 textEncodingName:nil]);
82     [task didReceiveResponse:response.get()];
83     [task didReceiveData:[@"Hello" dataUsingEncoding:NSUTF8StringEncoding]];
84     [task didFinish];
85 }
86
87 - (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)task
88 {
89 }
90
91 @end
92
93 TEST(ProcessSwap, Basic)
94 {
95     auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
96     processPoolConfiguration.get().processSwapsOnNavigation = YES;
97     auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
98
99     auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
100     [webViewConfiguration setProcessPool:processPool.get()];
101     RetainPtr<PSONScheme> handler = adoptNS([[PSONScheme alloc] init]);
102     [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON1"];
103     [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON2"];
104
105     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
106     auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
107     [webView setNavigationDelegate:delegate.get()];
108
109     NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson1://host/main1.html"]];
110     [webView loadRequest:request];
111
112     TestWebKitAPI::Util::run(&done);
113     done = false;
114
115     auto pid1 = [webView _webProcessIdentifier];
116
117     request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson1://host/main2.html"]];
118     [webView loadRequest:request];
119
120     TestWebKitAPI::Util::run(&done);
121     done = false;
122
123     auto pid2 = [webView _webProcessIdentifier];
124
125     request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson2://host/main2.html"]];
126     [webView loadRequest:request];
127
128     TestWebKitAPI::Util::run(&done);
129     done = false;
130
131     auto pid3 = [webView _webProcessIdentifier];
132
133     EXPECT_EQ(pid1, pid2);
134     EXPECT_FALSE(pid2 == pid3);
135
136     // 3 loads, 3 decidePolicy calls (e.g. the load that did perform a process swap should not have generated an additional decidePolicy call)
137     EXPECT_EQ(numberOfDecidePolicyCalls, 3);
138 }
139
140 #endif // WK_API_ENABLED