Changeset 286777 in webkit for trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm
- Timestamp:
- Dec 9, 2021, 6:46:27 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/WebPushDaemon.mm
r286764 r286777 27 27 28 28 #import "DaemonTestUtilities.h" 29 #import "HTTPServer.h"30 29 #import "Test.h" 31 30 #import "TestURLSchemeHandler.h" … … 37 36 #import <WebKit/_WKExperimentalFeature.h> 38 37 #import <WebKit/_WKWebsiteDataStoreConfiguration.h> 38 39 39 #import <mach/mach_init.h> 40 40 #import <mach/task.h> … … 163 163 } 164 164 165 static RetainPtr<xpc_object_t> createMessageDictionary(uint8_t messageType, const Vector<uint8_t>& message)166 {167 auto dictionary = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0));168 xpc_dictionary_set_uint64(dictionary.get(), "protocol version", 1);169 xpc_dictionary_set_uint64(dictionary.get(), "message type", messageType);170 xpc_dictionary_set_data(dictionary.get(), "encoded message", message.data(), message.size());171 return WTFMove(dictionary);172 }173 174 // Uses an existing connection to the daemon for a one-off message175 void sendMessageToDaemon(xpc_connection_t connection, uint8_t messageType, const Vector<uint8_t>& message)176 {177 auto dictionary = createMessageDictionary(messageType, message);178 xpc_connection_send_message(connection, dictionary.get());179 }180 181 // Uses an existing connection to the daemon for a one-off message, waiting for the reply182 void sendMessageToDaemonWaitingForReply(xpc_connection_t connection, uint8_t messageType, const Vector<uint8_t>& message)183 {184 auto dictionary = createMessageDictionary(messageType, message);185 186 __block bool done = false;187 xpc_connection_send_message_with_reply(connection, dictionary.get(), dispatch_get_main_queue(), ^(xpc_object_t request) {188 done = true;189 });190 191 TestWebKitAPI::Util::run(&done);192 }193 194 static void sendConfigurationWithAuditToken(xpc_connection_t connection)195 {196 audit_token_t token = { 0, 0, 0, 0, 0, 0, 0, 0 };197 mach_msg_type_number_t auditTokenCount = TASK_AUDIT_TOKEN_COUNT;198 kern_return_t result = task_info(mach_task_self(), TASK_AUDIT_TOKEN, (task_info_t)(&token), &auditTokenCount);199 if (result != KERN_SUCCESS) {200 EXPECT_TRUE(false);201 return;202 }203 204 // Send configuration with audit token205 {206 Vector<uint8_t> encodedMessage(42);207 encodedMessage.fill(0);208 encodedMessage[1] = 1;209 encodedMessage[2] = 32;210 memcpy(&encodedMessage[10], &token, sizeof(token));211 sendMessageToDaemon(connection, 6, encodedMessage);212 }213 }214 215 RetainPtr<xpc_connection_t> createAndConfigureConnectionToService(const char* serviceName)216 {217 auto connection = adoptNS(xpc_connection_create_mach_service(serviceName, dispatch_get_main_queue(), 0));218 xpc_connection_set_event_handler(connection.get(), ^(xpc_object_t) { });219 xpc_connection_activate(connection.get());220 sendConfigurationWithAuditToken(connection.get());221 222 return WTFMove(connection);223 }224 225 static Vector<uint8_t> encodeString(const String& message)226 {227 ASSERT(message.is8Bit());228 auto utf8 = message.utf8();229 230 Vector<uint8_t> result(utf8.length() + 5);231 result[0] = static_cast<uint8_t>(utf8.length());232 result[1] = static_cast<uint8_t>(utf8.length() >> 8);233 result[2] = static_cast<uint8_t>(utf8.length() >> 16);234 result[3] = static_cast<uint8_t>(utf8.length() >> 24);235 result[4] = 0x01;236 237 auto data = utf8.data();238 for (size_t i = 0; i < utf8.length(); ++i)239 result[5 + i] = data[i];240 241 return result;242 }243 244 165 // FIXME: Re-enable this test on Mac once webkit.org/232857 is resolved. 245 166 #if PLATFORM(MAC) … … 276 197 277 198 xpc_connection_activate(connection.get()); 278 sendConfigurationWithAuditToken(connection.get()); 199 200 audit_token_t token = { 0, 0, 0, 0, 0, 0, 0, 0 }; 201 mach_msg_type_number_t auditTokenCount = TASK_AUDIT_TOKEN_COUNT; 202 kern_return_t result = task_info(mach_task_self(), TASK_AUDIT_TOKEN, (task_info_t)(&token), &auditTokenCount); 203 if (result != KERN_SUCCESS) { 204 EXPECT_TRUE(false); 205 return; 206 } 207 208 // Send configuration with audit token 209 { 210 std::array<uint8_t, 42> encodedMessage; 211 encodedMessage.fill(0); 212 encodedMessage[1] = 1; 213 encodedMessage[2] = 32; 214 memcpy(&encodedMessage[10], &token, sizeof(token)); 215 auto dictionary = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0)); 216 xpc_dictionary_set_uint64(dictionary.get(), "protocol version", 1); 217 xpc_dictionary_set_uint64(dictionary.get(), "message type", 6); 218 xpc_dictionary_set_data(dictionary.get(), "encoded message", encodedMessage.data(), encodedMessage.size()); 219 xpc_connection_send_message(connection.get(), dictionary.get()); 220 } 279 221 280 222 // Enable debug messages, and wait for the resulting debug message 281 223 { 282 224 auto dictionary = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0)); 283 Vector<uint8_t> encodedMessage(1); 284 encodedMessage[0] = 1; 285 sendMessageToDaemon(connection.get(), 5, encodedMessage); 225 std::array<uint8_t, 1> encodedMessage { 1 }; 226 xpc_dictionary_set_uint64(dictionary.get(), "protocol version", 1); 227 xpc_dictionary_set_uint64(dictionary.get(), "message type", 5); 228 xpc_dictionary_set_data(dictionary.get(), "encoded message", encodedMessage.data(), encodedMessage.size()); 229 230 xpc_connection_send_message(connection.get(), dictionary.get()); 286 231 TestWebKitAPI::Util::run(&done); 287 232 } … … 289 234 // Echo and wait for a reply 290 235 auto dictionary = adoptNS(xpc_dictionary_create(nullptr, nullptr, 0)); 291 auto encodedString = encodeString("hello");236 ; 292 237 xpc_dictionary_set_uint64(dictionary.get(), "protocol version", 1); 293 238 xpc_dictionary_set_uint64(dictionary.get(), "message type", 1); … … 397 342 } 398 343 399 static const char* mainSWBytes = R"SWRESOURCE(400 <script>401 function log(msg)402 {403 window.webkit.messageHandlers.sw.postMessage(msg);404 }405 406 const channel = new MessageChannel();407 channel.port1.onmessage = (event) => log(event.data);408 409 navigator.serviceWorker.register('/sw.js').then((registration) => {410 if (registration.active) {411 registration.active.postMessage({port: channel.port2}, [channel.port2]);412 return;413 }414 worker = registration.installing;415 worker.addEventListener('statechange', function() {416 if (worker.state == 'activated')417 worker.postMessage({port: channel.port2}, [channel.port2]);418 });419 }).catch(function(error) {420 log("Registration failed with: " + error);421 });422 </script>423 )SWRESOURCE";424 425 static const char* scriptBytes = R"SWRESOURCE(426 let port;427 self.addEventListener("message", (event) => {428 port = event.data.port;429 port.postMessage("Ready");430 });431 self.addEventListener("push", (event) => {432 try {433 if (!event.data) {434 port.postMessage("Received: null data");435 return;436 }437 const value = event.data.text();438 port.postMessage("Received: " + value);439 if (value != 'Sweet Potatoes')440 event.waitUntil(Promise.reject('I want sweet potatoes'));441 } catch (e) {442 port.postMessage("Got exception " + e);443 }444 });445 )SWRESOURCE";446 447 static void clearWebsiteDataStore(WKWebsiteDataStore *store)448 {449 __block bool clearedStore = false;450 [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {451 clearedStore = true;452 }];453 TestWebKitAPI::Util::run(&clearedStore);454 }455 456 // FIXME: Re-enable this test on Mac once webkit.org/232857 is resolved.457 #if PLATFORM(MAC)458 TEST(WebPushD, DISABLED_HandleInjectedPush)459 #else460 TEST(WebPushD, HandleInjectedPush)461 #endif462 {463 [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];464 465 NSURL *tempDirectory = setUpTestWebPushD();466 467 auto dataStoreConfiguration = adoptNS([_WKWebsiteDataStoreConfiguration new]);468 dataStoreConfiguration.get().webPushMachServiceName = @"org.webkit.webpushtestdaemon.service";469 dataStoreConfiguration.get().webPushDaemonUsesMockBundlesForTesting = YES;470 auto dataStore = adoptNS([[WKWebsiteDataStore alloc] _initWithConfiguration:dataStoreConfiguration.get()]);471 472 auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);473 configuration.get().websiteDataStore = dataStore.get();474 clearWebsiteDataStore([configuration websiteDataStore]);475 476 [configuration.get().preferences _setNotificationsEnabled:YES];477 for (_WKExperimentalFeature *feature in [WKPreferences _experimentalFeatures]) {478 if ([feature.key isEqualToString:@"BuiltInNotificationsEnabled"])479 [[configuration preferences] _setEnabled:YES forFeature:feature];480 }481 482 auto messageHandler = adoptNS([[TestMessageHandler alloc] init]);483 [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];484 __block bool done = false;485 [messageHandler addMessage:@"Ready" withHandler:^{486 done = true;487 }];488 [messageHandler addMessage:@"Received: Hello World" withHandler:^{489 done = true;490 }];491 492 TestWebKitAPI::HTTPServer server({493 { "/", { mainSWBytes } },494 { "/sw.js", { { { "Content-Type", "application/javascript" } }, scriptBytes } }495 }, TestWebKitAPI::HTTPServer::Protocol::Http);496 497 auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);498 [webView loadRequest:server.request()];499 500 TestWebKitAPI::Util::run(&done);501 done = false;502 503 // Inject push message504 auto encodedMessage = encodeString("com.apple.WebKit.TestWebKitAPI");505 encodedMessage.appendVector(encodeString(server.request().URL.absoluteString));506 encodedMessage.appendVector(encodeString("Hello World"));507 508 auto utilityConnection = createAndConfigureConnectionToService("org.webkit.webpushtestdaemon.service");509 sendMessageToDaemonWaitingForReply(utilityConnection.get(), 7, encodedMessage);510 511 // Fetch push messages512 __block RetainPtr<NSArray<NSDictionary *>> messages;513 [dataStore _getPendingPushMessages:^(NSArray<NSDictionary *> *rawMessages) {514 messages = rawMessages;515 done = true;516 }];517 TestWebKitAPI::Util::run(&done);518 done = false;519 520 EXPECT_EQ([messages count], 1u);521 522 // Handle push message523 __block bool pushMessageProcessed = false;524 [dataStore _processPushMessage:[messages firstObject] completionHandler:^(bool result) {525 pushMessageProcessed = true;526 }];527 TestWebKitAPI::Util::run(&done);528 TestWebKitAPI::Util::run(&pushMessageProcessed);529 530 cleanUpTestWebPushD(tempDirectory);531 }532 533 344 } // namespace TestWebKitAPI 534 345
Note:
See TracChangeset
for help on using the changeset viewer.