From ad35d11fa8e27e5d0f882a56725c6950d248be15 Mon Sep 17 00:00:00 2001
From: "nirnimesh@chromium.org"
 <nirnimesh@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Fri, 17 Apr 2009 18:14:38 +0000
Subject: [PATCH] Port page_cycler_http to Mac Accompanying buildbot changes @
 http://codereview.chromium.org/67234 Review URL:
 http://codereview.chromium.org/79017

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@13950 0039d316-1c4b-4281-b951-d872f2087c98
---
 chrome/test/page_cycler/page_cycler_test.cc   |  13 +-
 .../google/httpd_config/httpd2_mac.conf       | 229 ++++++++++++++++++
 tools/python/google/httpd_utils.py            |   5 +-
 tools/python/google/platform_utils.py         |   2 +
 tools/python/google/platform_utils_mac.py     | 135 +++++++++++
 5 files changed, 379 insertions(+), 5 deletions(-)
 create mode 100644 tools/python/google/httpd_config/httpd2_mac.conf
 create mode 100644 tools/python/google/platform_utils_mac.py

diff --git a/chrome/test/page_cycler/page_cycler_test.cc b/chrome/test/page_cycler/page_cycler_test.cc
index 5d204576005a8..a8826ee0e0315 100644
--- a/chrome/test/page_cycler/page_cycler_test.cc
+++ b/chrome/test/page_cycler/page_cycler_test.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
@@ -263,11 +263,12 @@ TEST_F(PageCyclerReferenceTest, MozFile) {
   RunTest("moz", false);
 }
 
+// TODO(nirnimesh): Intl1File, Intl2File, Intl1Http, Intl2Http crash Chromium
+// on Mac. Revisit later.
 TEST_F(PageCyclerTest, Intl1File) {
   RunTest("intl1", false);
 }
 
-// TODO(nirnimesh): Intl1File, Intl2File crash Chromium on Mac. Revisit later.
 TEST_F(PageCyclerReferenceTest, Intl1File) {
   RunTest("intl1", false);
 }
@@ -299,12 +300,14 @@ TEST_F(PageCyclerTest, DhtmlFile) {
 TEST_F(PageCyclerReferenceTest, DhtmlFile) {
   RunTest("dhtml", false);
 }
+#endif
 
 // http (localhost) tests
 TEST_F(PageCyclerTest, MozHttp) {
   RunTest("moz", true);
 }
 
+#if !defined(OS_MACOSX)
 TEST_F(PageCyclerReferenceTest, MozHttp) {
   RunTest("moz", true);
 }
@@ -324,22 +327,26 @@ TEST_F(PageCyclerTest, Intl2Http) {
 TEST_F(PageCyclerReferenceTest, Intl2Http) {
   RunTest("intl2", true);
 }
+#endif  // !defined(OS_MACOSX)
 
 TEST_F(PageCyclerTest, DomHttp) {
   RunTest("dom", true);
 }
 
+#if !defined(OS_MACOSX)
 TEST_F(PageCyclerReferenceTest, DomHttp) {
   RunTest("dom", true);
 }
+#endif
 
 TEST_F(PageCyclerTest, BloatHttp) {
   RunTest("bloat", true);
 }
 
+#if !defined(OS_MACOSX)
 TEST_F(PageCyclerReferenceTest, BloatHttp) {
   RunTest("bloat", true);
 }
-#endif  // !defined(OS_MACOSX)
+#endif
 
 }  // namespace
diff --git a/tools/python/google/httpd_config/httpd2_mac.conf b/tools/python/google/httpd_config/httpd2_mac.conf
new file mode 100644
index 0000000000000..07f88999b851f
--- /dev/null
+++ b/tools/python/google/httpd_config/httpd2_mac.conf
@@ -0,0 +1,229 @@
+## httpd2.conf -- Apache 2.x HTTP server configuration file
+
+#
+# Listen: Allows you to bind Apache to specific IP addresses and/or
+# ports, instead of the default. See also the <VirtualHost>
+# directive.
+#
+Listen 127.0.0.1:8000
+
+#
+# Dynamic Shared Object (DSO) Support
+#
+# To be able to use the functionality of a module which was built as a DSO you
+# have to place corresponding `LoadModule' lines at this location so the
+# directives contained in it are actually available _before_ they are used.
+# Please read the file http://httpd.apache.org/docs/dso.html for more
+# details about the DSO mechanism and run `httpd -l' for the list of already
+# built-in (statically linked and thus always available) modules in your httpd
+# binary.
+#
+# Note: The order in which modules are loaded is important.  Don't change
+# the order below without expert advice.
+#
+# NOTE: This is not the same set of modules that gets loaded on win.
+LoadModule authz_host_module libexec/apache2/mod_authz_host.so
+LoadModule mime_module libexec/apache2/mod_mime.so
+LoadModule ssl_module libexec/apache2/mod_ssl.so
+LoadModule autoindex_module libexec/apache2/mod_autoindex.so
+LoadModule alias_module libexec/apache2/mod_alias.so
+LoadModule log_config_module libexec/apache2/mod_log_config.so
+
+#LoadModule include_module libexec/apache2/mod_include.so
+#LoadModule headers_module libexec/apache2/mod_headers.so
+#LoadModule asis_module libexec/apache2/mod_asis.so
+#LoadModule cgi_module libexec/apache2/mod_cgi.so
+#LoadModule negotiation_module libexec/apache2/mod_negotiation.so
+#LoadModule imagemap_module libexec/apache2/mod_imagemap.so
+#LoadModule actions_module libexec/apache2/mod_actions.so
+#LoadModule rewrite_module libexec/apache2/mod_rewrite.so
+
+
+#
+# Each directory to which Apache has access, can be configured with respect
+# to which services and features are allowed and/or disabled in that
+# directory (and its subdirectories).
+#
+<Directory />
+    Options Indexes FollowSymLinks MultiViews ExecCGI Includes
+    AllowOverride All
+    Order allow,deny
+    Allow from all
+</Directory>
+
+
+#
+# Apple specific filesystem protection.
+
+<Files "rsrc">
+    Order allow,deny
+    Deny from all
+    Satisfy All
+</Files>
+<Directory  ~ ".*\.\.namedfork">
+    Order allow,deny
+    Deny from all
+    Satisfy All
+</Directory>
+
+
+#
+# UseCanonicalName:  (new for 1.3)  With this setting turned on, whenever
+# Apache needs to construct a self-referencing URL (a URL that refers back
+# to the server the response is coming from) it will use ServerName and
+# Port to form a "canonical" name.  With this setting off, Apache will
+# use the hostname:port that the client supplied, when possible.  This
+# also affects SERVER_NAME and SERVER_PORT in CGI scripts.
+#
+UseCanonicalName On
+
+
+#
+# The following directives define some format nicknames for use with
+# a CustomLog directive (see below).
+#
+LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
+LogFormat "%h %l %u %t \"%r\" %>s %b" common
+LogFormat "%{Referer}i -> %U" referer
+LogFormat "%{User-agent}i" agent
+
+
+#
+# Optionally add a line containing the server version and virtual host
+# name to server-generated pages (error documents, FTP directory listings,
+# mod_status and mod_info output etc., but not CGI generated documents).
+# Set to "EMail" to also include a mailto: link to the ServerAdmin.
+# Set to one of:  On | Off | EMail
+#
+ServerSignature On
+
+
+#
+# Document types.
+#
+<IfModule mime_module>
+
+    #
+    # AddLanguage allows you to specify the language of a document. You can
+    # then use content negotiation to give a browser a file in a language
+    # it can understand.  
+    #
+    # Note 1: The suffix does not have to be the same as the language 
+    # keyword --- those with documents in Polish (whose net-standard 
+    # language code is pl) may wish to use "AddLanguage pl .po" to 
+    # avoid the ambiguity with the common suffix for perl scripts.
+    #
+    # Note 2: The example entries below illustrate that in quite
+    # some cases the two character 'Language' abbreviation is not
+    # identical to the two character 'Country' code for its country,
+    # E.g. 'Danmark/dk' versus 'Danish/da'.
+    #
+    # Note 3: In the case of 'ltz' we violate the RFC by using a three char 
+    # specifier. But there is 'work in progress' to fix this and get 
+    # the reference data for rfc1766 cleaned up.
+    #
+    # Danish (da) - Dutch (nl) - English (en) - Estonian (ee)
+    # French (fr) - German (de) - Greek-Modern (el)
+    # Italian (it) - Korean (kr) - Norwegian (no) - Norwegian Nynorsk (nn)
+    # Portugese (pt) - Luxembourgeois* (ltz)
+    # Spanish (es) - Swedish (sv) - Catalan (ca) - Czech(cs)
+    # Polish (pl) - Brazilian Portuguese (pt-br) - Japanese (ja)
+    # Russian (ru)
+    #
+    AddLanguage da .dk
+    AddLanguage nl .nl
+    AddLanguage en .en
+    AddLanguage et .ee
+    AddLanguage fr .fr
+    AddLanguage de .de
+    AddLanguage el .el
+    AddLanguage he .he
+    AddCharset ISO-8859-8 .iso8859-8
+    AddLanguage it .it
+    AddLanguage ja .ja
+    AddCharset ISO-2022-JP .jis
+    AddLanguage kr .kr
+    AddCharset ISO-2022-KR .iso-kr
+    AddLanguage nn .nn
+    AddLanguage no .no
+    AddLanguage pl .po
+    AddCharset ISO-8859-2 .iso-pl
+    AddLanguage pt .pt
+    AddLanguage pt-br .pt-br
+    AddLanguage ltz .lu
+    AddLanguage ca .ca
+    AddLanguage es .es
+    AddLanguage sv .sv
+    AddLanguage cs .cz .cs
+    AddLanguage ru .ru
+    AddLanguage zh-TW .zh-tw
+    AddCharset Big5         .Big5    .big5
+    AddCharset WINDOWS-1251 .cp-1251
+    AddCharset CP866        .cp866
+    AddCharset ISO-8859-5   .iso-ru
+    AddCharset KOI8-R       .koi8-r
+    AddCharset UCS-2        .ucs2
+    AddCharset UCS-4        .ucs4
+    AddCharset UTF-8        .utf8
+
+    # LanguagePriority allows you to give precedence to some languages
+    # in case of a tie during content negotiation.
+    #
+    # Just list the languages in decreasing order of preference. We have
+    # more or less alphabetized them here. You probably want to change this.
+    #
+    <IfModule negotiation_module>
+        LanguagePriority en da nl et fr de el it ja kr no pl pt pt-br ru ltz ca es sv tw
+    </IfModule>
+
+    #
+    # AddType allows you to tweak mime.types without actually editing it, or to
+    # make certain files to be certain types.
+    #
+    AddType application/x-tar .tgz
+
+    #
+    # AddEncoding allows you to have certain browsers uncompress
+    # information on the fly. Note: Not all browsers support this.
+    # Despite the name similarity, the following Add* directives have nothing
+    # to do with the FancyIndexing customization directives above.
+    #
+    AddEncoding x-compress .Z
+    AddEncoding x-gzip .gz .tgz
+
+    #
+    # AddHandler allows you to map certain file extensions to "handlers",
+    # actions unrelated to filetype. These can be either built into the server
+    # or added with the Action command (see below)
+    #
+    # If you want to use server side includes, or CGI outside
+    # ScriptAliased directories, uncomment the following lines.
+    #
+    # To use CGI scripts:
+    #
+    AddHandler cgi-script .cgi .pl
+
+    #
+    # To use server-parsed HTML files
+    #
+    AddType text/html .shtml
+    AddHandler server-parsed .shtml
+
+    #
+    # Uncomment the following line to enable Apache's send-asis HTTP file
+    # feature
+    #
+    AddHandler send-as-is asis
+</IfModule>
+
+
+<IfModule php5_module>
+    AddType application/x-httpd-php .php
+    AddType application/x-httpd-php-source .phps
+</IfModule>
+
+<IfModule rewrite_module>
+    RewriteEngine On
+    RewriteCond %{REQUEST_METHOD} ^TRACE
+    RewriteRule .* - [F]
+</IfModule>
diff --git a/tools/python/google/httpd_utils.py b/tools/python/google/httpd_utils.py
index 28952ede5dd4a..309c924472b3c 100644
--- a/tools/python/google/httpd_utils.py
+++ b/tools/python/google/httpd_utils.py
@@ -1,5 +1,5 @@
 #!/bin/env python
-# Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
+# Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
@@ -176,7 +176,8 @@ if '__main__' == __name__:
   option_parser.add_option('-k', '--server', help='Server action (start|stop)')
   option_parser.add_option('-r', '--root', help='Document root (optional)')
   option_parser.add_option('-a', '--apache2', action='store_true',
-      default=False, help='Starts Apache 2 instead of Apache 1.3 (default).')
+      default=False, help='Starts Apache 2 instead of Apache 1.3 (default). '
+                          'Ignored on Mac (apache2 is used always)')
   options, args = option_parser.parse_args()
 
   if not options.server:
diff --git a/tools/python/google/platform_utils.py b/tools/python/google/platform_utils.py
index a48a506a434f5..5bbcdf800ec45 100644
--- a/tools/python/google/platform_utils.py
+++ b/tools/python/google/platform_utils.py
@@ -18,5 +18,7 @@ import sys
 # included in any case so we don't get an import error.
 if sys.platform in ('cygwin', 'win32'):
   from platform_utils_win import *
+elif sys.platform == 'darwin':
+  from platform_utils_mac import *
 
 
diff --git a/tools/python/google/platform_utils_mac.py b/tools/python/google/platform_utils_mac.py
new file mode 100644
index 0000000000000..c4399b3bf8361
--- /dev/null
+++ b/tools/python/google/platform_utils_mac.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python
+# Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Platform-specific utility methods shared by several scripts."""
+
+import os
+import subprocess
+
+import google.path_utils
+
+
+class PlatformUtility(object):
+  def __init__(self, base_dir):
+    """Args:
+         base_dir: the base dir for running tests.
+    """
+    self._base_dir = base_dir
+    self._httpd_cmd_string = None  # used for starting/stopping httpd
+    self._bash = "/bin/bash"
+
+  def _UnixRoot(self):
+    """Returns the path to root."""
+    return "/"
+
+  def GetFilesystemRoot(self):
+    """Returns the root directory of the file system."""
+    return self._UnixRoot()
+
+  def GetTempDirectory(self):
+    """Returns the file system temp directory
+
+    Note that this does not use a random subdirectory, so it's not
+    intrinsically secure.  If you need a secure subdir, use the tempfile
+    package.
+    """
+    return os.getenv("TMPDIR", "/tmp")
+
+  def FilenameToUri(self, path, use_http=False, use_ssl=False, port=8000):
+    """Convert a filesystem path to a URI.
+
+    Args:
+      path: For an http URI, the path relative to the httpd server's
+          DocumentRoot; for a file URI, the full path to the file.
+      use_http: if True, returns a URI of the form http://127.0.0.1:8000/.
+          If False, returns a file:/// URI.
+      use_ssl: if True, returns HTTPS URL (https://127.0.0.1:8000/).
+          This parameter is ignored if use_http=False.
+      port: The port number to append when returning an HTTP URI
+    """
+    if use_http:
+      protocol = 'http'
+      if use_ssl:
+        protocol = 'https'
+      return "%s://127.0.0.1:%d/%s" % (protocol, port, path)
+    return "file://" + path
+
+  def GetStartHttpdCommand(self, output_dir,
+                           httpd_conf_path, mime_types_path,
+                           document_root=None, apache2=False):
+    """Prepares the config file and output directory to start an httpd server.
+    Returns a list of strings containing the server's command line+args.
+
+    Args:
+      output_dir: the path to the server's output directory, for log files.
+          It will be created if necessary.
+      httpd_conf_path: full path to the httpd.conf file to be used.
+      mime_types_path: full path to the mime.types file to be used.
+      document_root: full path to the DocumentRoot.  If None, the DocumentRoot
+          from the httpd.conf file will be used.  Note that the httpd.conf
+          file alongside this script does not specify any DocumentRoot, so if
+          you're using that one, be sure to specify a document_root here.
+      apache2: boolean if true will cause this function to return start
+               command for Apache 2.x as opposed to Apache 1.3.x. This flag
+               is ignored on Mac (but preserved here for compatibility in
+               function signature with win), where httpd2 is used always
+    """
+
+    exe_name = "httpd"
+    cert_file = google.path_utils.FindUpward(self._base_dir, 'tools',
+                                             'python', 'google',
+                                             'httpd_config', 'httpd2.pem')
+    httpd_vars = {
+      "httpd_executable_path":
+          os.path.join(self._UnixRoot(), "usr", "sbin", exe_name),
+      "httpd_conf_path": httpd_conf_path,
+      "ssl_certificate_file": cert_file,
+      "document_root" : document_root,
+      "server_root": os.path.join(self._UnixRoot(), "usr"),
+      "mime_types_path": mime_types_path,
+      "output_dir": output_dir,
+      "user": os.environ.get("USER", "#%d" % os.geteuid()),
+      "lock_file": os.path.join(output_dir, "accept.lock"),
+    }
+
+    google.path_utils.MaybeMakeDirectory(output_dir)
+
+    # We have to wrap the command in bash
+    # -C: process directive before reading config files
+    # -c: process directive after reading config files
+    # Apache wouldn't run CGIs with permissions==700 unless we add
+    # -c User "<username>"
+    httpd_cmd_string = (
+      '%(httpd_executable_path)s'
+      ' -f %(httpd_conf_path)s'
+      ' -c \'TypesConfig "%(mime_types_path)s"\''
+      ' -c \'CustomLog "%(output_dir)s/access_log.txt" common\''
+      ' -c \'ErrorLog "%(output_dir)s/error_log.txt"\''
+      ' -c \'PidFile "%(output_dir)s/httpd.pid"\''
+      ' -C \'User "%(user)s"\''
+      ' -C \'ServerRoot "%(server_root)s"\''
+      ' -c \'LockFile "%(lock_file)s"\''
+      ' -c \'SSLCertificateFile "%(ssl_certificate_file)s"\''
+    )
+
+    if document_root:
+      httpd_cmd_string += ' -C \'DocumentRoot "%(document_root)s"\''
+    # Save a copy of httpd_cmd_string to use for stopping httpd
+    self._httpd_cmd_string = httpd_cmd_string % httpd_vars
+
+    httpd_cmd = [self._bash, "-c", self._httpd_cmd_string]
+    return httpd_cmd
+
+  def GetStopHttpdCommand(self):
+    """Returns a list of strings that contains the command line+args needed to
+    stop the http server used in the http tests.
+
+    This tries to fetch the pid of httpd (if available) and returns the
+    command to kill it. If pid is not available, kill all httpd processes
+    """
+
+    if not self._httpd_cmd_string:
+      return ["true"]   # Haven't been asked for the start cmd yet. Just pass.
+    return [self._bash, "-c", self._httpd_cmd_string + ' -k stop']
-- 
GitLab