#include "testlib.h" RENDER(Request& context) { if(!test_demo_request_allowed(context)) { site_tests_restricted(context, "Sockets And Services", "connect to local listeners and optional infrastructure services"); return; } u64 passed = 0; u64 failed = 0; u64 skipped = 0; site_tests_page_start("Sockets And Services", "Local-only probes for sockets and optional infrastructure integrations."); auto mark = [&](String name, String status, String detail) { site_tests_case(name, status, detail); if(status == "pass") passed++; else if(status == "skip") skipped++; else failed++; }; u64 sockfd = socket_connect("127.0.0.1", 80); if(sockfd != 0) { bool write_ok = socket_write(sockfd, "GET /tests/index.uce HTTP/1.0\r\nHost: uce.openfu.com\r\n\r\n"); String response = socket_read(sockfd, 4096, 2); socket_close(sockfd); bool has_nul = response.find(String("\0", 1)) != String::npos; mark( "socket_connect() / socket_write() / socket_read()", (write_ok && response.find("200 OK") != String::npos && !has_nul) ? "pass" : "fail", response.substr(0, response.length() > 220 ? 220 : response.length()) + (has_nul ? " [unexpected NUL]" : "") ); } else { mark("socket_connect() / socket_write() / socket_read()", "fail", "socket_connect(127.0.0.1, 80) returned 0"); } pid_t custom_http_pid = server_start_http("site-tests-http", "19091", "servers/http.uce", "named"); usleep(500000); u64 custom_http_sockfd = socket_connect("127.0.0.1", 19091); if(custom_http_sockfd != 0) { bool write_ok = socket_write(custom_http_sockfd, "GET /custom-test?alpha=1 HTTP/1.0\r\nHost: localhost\r\n\r\n"); String response = socket_read(custom_http_sockfd, 4096, 2); for(u64 i = 0; i < 3 && response.find("custom-http-named") == String::npos; i++) { String chunk = socket_read(custom_http_sockfd, 4096, 1); if(chunk == "") break; response += chunk; } socket_close(custom_http_sockfd); bool stopped = server_stop("site-tests-http"); usleep(200000); u64 stopped_sockfd = socket_connect("127.0.0.1", 19091); bool listener_closed = stopped_sockfd == 0; if(stopped_sockfd != 0) socket_close(stopped_sockfd); mark( "server_start_http() / SERVE_HTTP:named / server_stop()", (custom_http_pid != 0 && write_ok && response.find("custom-http-named") != String::npos && response.find("query=alpha=1") != String::npos && stopped && listener_closed) ? "pass" : "fail", response.substr(0, response.length() > 260 ? 260 : response.length()) + " stopped=" + (stopped ? "true" : "false") + " listener_closed=" + (listener_closed ? "true" : "false") ); } else { bool stopped = server_stop("site-tests-http"); mark("server_start_http() / SERVE_HTTP:named / server_stop()", "fail", "socket_connect(127.0.0.1, 19091) returned 0; pid=" + std::to_string(custom_http_pid) + " stopped=" + (stopped ? "true" : "false")); } u64 memfd = memcache_connect(); if(memfd == 0) { mark("memcache_*", "skip", "memcache_connect() returned 0"); } else { memcache_set(memfd, "site-tests-key", "value-1"); memcache_set(memfd, "site-tests-key2", "value-2"); String raw_mem = memcache_command(memfd, "get site-tests-key"); String mem_value = memcache_get(memfd, "site-tests-key"); StringMap mem_multi = memcache_get_multiple(memfd, {"site-tests-key", "site-tests-key2"}); memcache_delete(memfd, "site-tests-key"); memcache_delete(memfd, "site-tests-key2"); mark( "memcache_connect() / memcache_command() / memcache_get_multiple()", mem_value == "value-1" && contains(raw_mem, "VALUE site-tests-key") && mem_multi["site-tests-key"] == "value-1" && mem_multi["site-tests-key2"] == "value-2" ? "pass" : "fail", "memcache value=" + mem_value + " raw=" + raw_mem + " multi=" + var_dump(mem_multi) ); } MySQL placeholder_guard; StringMap mysql_params; mysql_params["id"] = "1"; placeholder_guard.query("select ?", mysql_params); String mysql_placeholder_error = placeholder_guard.error(); mark( "mysql_query() rejects positional placeholders", mysql_placeholder_error.find("positional ? placeholders are not supported") != String::npos ? "pass" : "fail", mysql_placeholder_error ); MySQL mysql; mysql.connect("127.0.0.1", "root", ""); String mysql_error_text = trim(mysql.error()); if(mysql_error_text != "") { mark("mysql connect/query", "skip", mysql_error_text); } else { String dbs = var_dump(mysql.query("SHOW DATABASES")); mark( "mysql connect/query", (dbs.find("information_schema") != String::npos || dbs.find("mysql") != String::npos) ? "pass" : "fail", dbs.substr(0, dbs.length() > 220 ? 220 : dbs.length()) ); } site_tests_summary(passed, failed, skipped, "Memcache or MySQL checks are allowed to skip cleanly when the corresponding service is not available on the development host."); site_tests_page_end(); }