blob: d836c3821de1cdd9545c951a6352d34fc37db8e1 [file] [log] [blame]
#!/usr/bin/python
# Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
import os
import json
def _TestDictOfStrings(key, value):
if not isinstance(value, dict):
raise Exception('Wrong type for key "%s", expecting dict, got %s.' %
(key, type(value)))
for k, v in value.iteritems():
if not isinstance(k, basestring):
raise Exception("In %s the decription %s was not a string but %s" %
(key, k, type(k)))
if not isinstance(v, basestring):
raise Exception("In %s the command %s was not a string but %s" %
(key, v, type(v)))
def _TestListOfStrings(key, value):
if not isinstance(value, list):
raise Exception('Wrong type for key "%s", expecting list, got %s.' %
(key, type(value)))
for element in value:
if not isinstance(element, basestring):
raise Exception("In %s, %s was not a string but %s" %
(key, k, type(k)))
def _TestString(key, value):
if not isinstance(value, basestring):
raise Exception('Wrong type for key "%s", expecting string, got %s.' %
(key, type(value)))
def _TestBoolean(key, value):
if not isinstance(value, bool):
raise Exception('Wrong type for key "%s", expecting boolean, got %s.' %
(key, type(value)))
def _TestPackageConfig(key, value):
if isinstance(value, bool): return True
if not isinstance(value, dict):
raise Exception('Wrong type for key "%s", expecting bool or dict, got %s.' %
(key, type(value)))
keys = value.keys()
if 'platforms' in keys:
_TestListOfStrings('%s.platforms' % key, value['platforms'])
keys.remove('platforms')
if 'barback' in keys:
_TestBoolean('%s.barback' % key, value['barback'])
keys.remove('barback')
if keys:
raise Exception('In %s, unexpected key %s' %
(key, keys[0]))
VALID_TYPES = {
# Hooks mapping names (as displayed by the buildbot) to commands to execute.
'pre_pub_upgrade_hooks' : _TestDictOfStrings,
'pre_pub_build_hooks' : _TestDictOfStrings,
'post_pub_build_hooks' : _TestDictOfStrings,
'pre_test_hooks' : _TestDictOfStrings,
'post_test_hooks' : _TestDictOfStrings,
# Using a custom script to run steps.
'use_custom_script' : _TestString,
# Using or configuring the test package
'test_package' : _TestPackageConfig,
}
"""
Example config:
{
"pre_pub_build_hooks" : {
"Fixing up something": "$dart $project_root/test.dart first"
},
"post_pub_build_hooks" : {
"Fixing up something": "$dart $project_root/test.dart first"
},
"pre_pub_upgrade_hooks" : {
"Mess up": "$dart $project_root -la"
},
"pre_test_hooks" : {
"Fix tests": "$dart $project_root/test.dart foo",
"Fix tests some more": "$dart $project_root/test.dart bar"
},
"post_test_hooks" : {
"Code coverage": "$dart $project_root/test.dart coverage"
}
}
Alternatively you can give a custom script to run:
{
"use_custom_script" : "$python tools/annotated_scripts.py"
}
"""
class ConfigParser(object):
"""
Encapsulation of package testing config.
Hooks, which are lists of commands, are read from a JSON file.
The objects are simply instantiated with a file parameter.
- file: The file to get the config from
There are a number of magic markers that can be used in the config:
$dart: the full path to the Dart vm
$project_root: path to the package being tested
$python: path to a python executable
"""
def __init__(self, file):
self.config = self._get_config(file)
self._validate_config_file()
def _validate_config_file(self):
for (key, value) in self.config.iteritems():
if not (key in VALID_TYPES):
raise Exception("Unknown configuration key %s" % key)
type_test = VALID_TYPES[key]
type_test(key, value)
if "use_custom_script" in self.config and len(self.config) > 1:
raise Exception("Cannot use 'use_custom_script' combined with hooks.")
def _get_hooks(self, hook_kind):
return self.config.get(hook_kind) or {}
def get_pre_pub_upgrade_hooks(self):
return self._get_hooks('pre_pub_upgrade_hooks')
def get_pre_pub_build_hooks(self):
return self._get_hooks('pre_pub_build_hooks')
def get_post_pub_build_hooks(self):
return self._get_hooks('post_pub_build_hooks')
def get_pre_test_hooks(self):
return self._get_hooks('pre_test_hooks')
def get_post_test_hooks(self):
return self._get_hooks('post_test_hooks')
def get_custom_script(self):
return self.config.get('use_custom_script') or None
# TODO(nweiz): Use the test package by default once all packages use it. Use
# its configuration file once that exists (test#46) rather than doing
# bot-specific configuration.
def get_test_package(self):
value = self.config.get('test_package')
print("test package config: %s" % value)
if isinstance(value, bool): return {} if value else None
return value
def _get_config(self, file):
if os.path.isfile(file):
return json.loads(open(file).read())
else:
print("No config test file in package")
return {}
def __str__(self):
config_string = json.dumps(self.config, indent=2)
return 'dart: %s\nproject_root: %s\nconfig: \n%s' % (self.dart_binary,
self.project_root,
config_string)
if __name__ == '__main__':
parser = ConfigParser('.test_config', 'daaaaaart', 'foobar')
parser.get_pre_pub_build_hooks()
parser.get_pre_pub_upgrade_hooks()
parser.get_pre_test_hooks()
parser.get_post_test_hooks()
print parser