Index: chrome/test/functional/autofill_dataset_generator.py |
=================================================================== |
--- chrome/test/functional/autofill_dataset_generator.py (revision 0) |
+++ chrome/test/functional/autofill_dataset_generator.py (revision 0) |
@@ -0,0 +1,300 @@ |
+#!/usr/bin/python |
+# Copyright (c) 2011 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. |
+ |
+"""Generates profile dictionaries for Autofill. |
+ |
+Used to test autofill.AutoFillTest.FormFillLatencyAfterSubmit. |
+Can be used as a stand alone script with -h to print out help text by running: |
+ python autofill_dataset_generator.py -h |
+""" |
+ |
+import codecs |
+import logging |
+import random |
+import re |
+import sys |
+import os |
+ |
+ |
+class NullHandler(logging.Handler): |
+ def emit(self, record): |
+ pass |
+ |
+ |
+class DatasetGenerator(object): |
+ """Generates a dataset of dictionaries. |
+ |
+ The lists (such as address_construct, city_construct) define the way the |
+ corresponding field is generated. They accomplish this by specifying a |
+ list of function-args lists. |
+ """ |
+ address_construct = [ |
+ [ random.randint, 1, 10000], |
+ [ None, u'foobar'], |
+ [ random.choice, [ u'St', u'Ave', u'Ln', u'Ct', ]], |
+ [ random.choice, [ u'#1', u'#2', u'#3', ]], |
+ ] |
+ |
+ city_construct = [ |
+ [ random.choice, [ u'San Jose', u'San Francisco', u'Sacramento', |
+ u'Los Angeles', ]], |
+ ] |
+ |
+ state_construct = [ |
+ [ None, u'CA'] |
+ ] |
+ |
+ zip_construct = [ |
+ [ None, u'95110'], |
+ ] |
+ |
+ re_single_quote = re.compile("'", re.UNICODE) |
+ logger = logging.getLogger(__name__) |
+ logger.addHandler(NullHandler()) |
+ log_handlers = {'StreamHandler': None} |
+ |
+ def __init__(self, output_filename=None, logging_level=None): |
+ """Constructs dataset generator object. |
+ |
+ Creates 'fields' data member which is a list of pair (two values) lists. |
+ These pairs are comprised of a field key e.g. u'NAME_FIRST' and a |
+ generator method e.g. self.GenerateNameFirst which will generate the value. |
+ If we want the value to always be the same .e.g. u'John' we can use this |
+ instead a a method. We can even use None keyword which will give |
+ a value of u''. |
+ |
+ 'output_pattern' for one field would have been: "{u'NAME_FIRST': u'%s',}" |
+ which is ready to accept a value for the 'NAME_FIRST' field key once |
+ this value is generated. |
+ 'output_pattern' is used in 'GenerateNextDict()' to generate the next |
+ dict line. |
+ |
+ Args: |
+ output_filename: specified filename of generated dataset to be saved. |
+ Default value is None and no saving takes place. |
+ logging_level: set verbosity levels, default is None. |
+ """ |
+ if logging_level: |
+ if not self.log_handlers['StreamHandler']: |
+ console = logging.StreamHandler() |
+ console.setLevel(logging.INFO) |
+ self.log_handlers['StreamHandler'] = console |
+ self.logger.addHandler(console) |
+ self.logger.setLevel(logging_level) |
+ else: |
+ if self.log_handlers['StreamHandler']: |
+ self.logger.removeHandler(self._log_handlers['StreamHandler']) |
+ self.log_handlers['StreamHandler'] = None |
+ |
+ self.output_filename = output_filename |
+ |
+ self.dict_no = 0 |
+ self.fields = [ |
+ [u'NAME_FIRST', self.GenerateNameFirst], |
+ [u'NAME_MIDDLE', None], |
+ [u'NAME_LAST', None], |
+ [u'EMAIL_ADDRESS', self.GenerateEmail], |
+ [u'COMPANY_NAME', None], |
+ [u'ADDRESS_HOME_LINE1', self.GenerateAddress], |
+ [u'ADDRESS_HOME_LINE2', None], |
+ [u'ADDRESS_HOME_CITY', self.GenerateCity], |
+ [u'ADDRESS_HOME_STATE', self.GenerateState], |
+ [u'ADDRESS_HOME_ZIP', self.GenerateZip], |
+ [u'ADDRESS_HOME_COUNTRY', u'United States'], |
+ [u'PHONE_HOME_WHOLE_NUMBER', None], |
+ [u'PHONE_FAX_WHOLE_NUMBER', u'6501234555'], |
+ ] |
+ |
+ self.dict_length = len(self.fields) |
+ self.output_pattern = u"{" |
+ for key_and_method in self.fields: |
+ self.output_pattern += u"u'%s': u'%s', " %(key_and_method[0], "%s") |
+ self.output_pattern = self.output_pattern[:-1] + "}," |
+ |
+ def _GenerateField(self, field_construct): |
+ """Generates each field in each dictionary. |
+ |
+ Args: |
+ field_construct: it is a list of lists. |
+ The first value (index 0) of each containing list is a function or None. |
+ The rest values are the args. If function is None then arg is just |
+ returned. |
+ |
+ Example 1: zip_construct = [[ None, u'95110']]. There is one |
+ containing list only and function here is None and arg is u'95110'. |
+ This just returns u'95110'. |
+ |
+ Example 2: address_construct = [ [ random.randint, 1, 10000], |
+ [ None, u'foobar'] ] This has two containing lists and it will return |
+ the result of: |
+ random.randint(1, 10000) + ' ' + u'foobar' |
+ which could be u'7832 foobar' |
+ """ |
+ parts = [] |
+ for function_and_args in field_construct: |
+ function = function_and_args[0] |
+ args = function_and_args[1:] |
+ if not function: |
+ function = lambda x: x |
+ parts.append(u'%s' %function(*args)) |
+ return (' ').join(parts) |
+ |
+ def GenerateAddress(self): |
+ """Uses _GenerateField() and address_construct to gen a random address. |
+ |
+ Returns random address. |
+ """ |
+ return self._GenerateField(self.address_construct) |
+ |
+ def GenerateCity(self): |
+ """Uses _GenerateField() and city_construct to gen a random city. |
+ |
+ Returns random city. |
+ """ |
+ return self._GenerateField(self.city_construct) |
+ |
+ def GenerateState(self): |
+ """Uses _GenerateField() and state_construct to generate a state. |
+ |
+ Returns random state. |
+ """ |
+ return self._GenerateField(self.state_construct) |
+ |
+ def GenerateZip(self): |
+ """Uses _GenerateField() and zip_construct to generate a zip code. |
+ |
+ Returns random zip code. |
+ """ |
+ return self._GenerateField(self.zip_construct) |
+ |
+ def GenerateCountry(self): |
+ """Uses _GenerateField() and country_construct to generate a country. |
+ |
+ Returns random country. |
+ """ |
+ return self._GenerateField(self.country_construct) |
+ |
+ def GenerateNameFirst(self): |
+ """Generates Numerical First Names. |
+ |
+ Its Name is the number of the current dict. |
+ i.e. u'1', u'2', u'3' |
+ |
+ Returns random first names. |
+ """ |
+ return u'%s' % self.dict_no |
+ |
+ def GenerateEmail(self): |
+ """Generates emails that correspond to the First Name. |
+ |
+ i.e. u'1@example.com', u'2@example.com', u'3@example.com' |
+ |
+ Returns random email addresses. |
+ """ |
+ return u'%s@example.com' % self.dict_no |
+ |
+ |
+ def GenerateNextDict(self): |
+ """Generates next dictionary of the dataset. |
+ |
+ It first increments zero starting dict_no. |
+ |
+ Returns the output dictionary. |
+ """ |
+ self.dict_no += 1 |
+ output_dict = {} |
+ for key, method_or_value in self.fields: |
+ if not method_or_value: |
+ output_dict[key] = '' |
+ elif type(method_or_value) in [str, unicode]: |
+ output_dict[key] = '%s' % method_or_value |
+ else: |
+ output_dict[key] = method_or_value() |
+ output_dict[key] = self.re_single_quote.sub( |
+ r"\'", output_dict[key]) # escaping single quote: "'" -> "\'" |
+ return output_dict |
+ |
+ def GenerateDataset(self, num_of_dict_to_generate=10): |
+ """Generates a list of dictionaries. |
+ |
+ Args: |
+ num_of_dict_to_generate: The number of dictionaries to be generated. |
+ Default value is 10. |
+ |
+ Returns the dictionary list. |
+ """ |
+ if self.output_filename: |
+ output_file = codecs.open( |
+ self.output_filename, mode = 'wb', encoding = 'utf-8-sig') |
+ else: |
+ output_file = None |
+ try: |
+ list_of_dict = [] |
+ if output_file: |
+ output_file.write('[') |
+ output_file.write(os.linesep) |
+ |
+ while self.dict_no < num_of_dict_to_generate: |
+ output_dict = self.GenerateNextDict() |
+ list_of_dict.append(output_dict) |
+ output_line = self.output_pattern %tuple( |
+ [output_dict[key_and_method[0]] for key_and_method in self.fields]) |
+ if output_file: |
+ output_file.write(output_line) |
+ output_file.write(os.linesep) |
+ self.logger.info( |
+ "%d: %s" %(self.dict_no, output_line.encode(sys.stdout.encoding, |
+ 'ignore'))) |
+ |
+ if output_file: |
+ output_file.write(']') |
+ output_file.write(os.linesep) |
+ self.logger.info("%d dictionaries generated SUCCESSFULLY!", self.dict_no) |
+ self.logger.info("--- FINISHED ---") |
+ return list_of_dict |
+ finally: |
+ if output_file: |
+ output_file.close() |
+ |
dennis_jeffrey
2011/03/18 21:44:01
Add one more blank line before the start of the ma
dyu1
2011/03/24 19:46:51
Done.
|
+def main(): |
+ # Command line options. |
+ from optparse import OptionParser |
+ parser = OptionParser() |
+ parser.add_option("-o", "--output", |
+ dest="output_filename", default="", |
+ help="write output to FILE [optional]", metavar="FILE") |
+ parser.add_option("-v", "--verbose", action="store_true", dest="verbose", |
+ default=True, |
+ help="display all [default]") |
+ parser.add_option("-q", "--quiet", action="store_false", dest="verbose", |
+ help="display nothing") |
+ parser.add_option("-l", "--log", dest="logging_level", default = None, |
+ help="LOG_LEVEL: 'debug, 'info', 'warning' or 'error'", |
+ metavar="LOG_LEVEL") |
+ |
+ (options, args) = parser.parse_args() |
+ if args: |
+ parser.print_help() |
+ sys.exit(1) |
+ if not options.verbose: |
+ options.logging_level = None |
+ if options.verbose and not options.logging_level: |
+ options.logging_level = 'info' |
+ if options.logging_level: |
+ if 'debug' in options.logging_level.lower(): |
+ options.logging_level = logging.DEBUG |
+ elif 'info' in options.logging_level.lower(): |
+ options.logging_level = logging.INFO |
+ elif 'warn' in options.logging_level.lower(): |
+ options.logging_level = logging.WARNING |
+ elif 'error' in options.logging_level.lower(): |
+ options.logging_level = logging.ERROR |
+ |
+ gen = DatasetGenerator(options.output_filename, options.logging_level) |
+ gen.GenerateDataset(100) |
+ |
+ |
+if __name__ == '__main__': |
+ main() |