def test_some_values_are_required(self): properties = property_dict([ Property('thing', required=True), Property('entity'), ]) data = { 'thing': 'ding', 'entity': 'dong', } configuration = Configuration(properties, data) configuration.validate()
def test_values_are_checked_against_their_type(self): properties = property_dict([ Property('thing', type=int), Property('entity', type=bool), ]) data = { 'thing': 3, 'entity': False, } configuration = Configuration(properties, data) configuration.validate()
def test_missing_required_values_cause_a_validation_exception(self): properties = property_dict([ Property('thing', required=True), Property('entity'), ]) data = { 'entity': 'dong', } configuration = Configuration(properties, data) with self.assertRaises(ValidationException) as raises_context: configuration.validate() self.assertEqual( raises_context.exception.errors, [ValidationError('The property "thing" is required.')])
def test_overriding_configuration_favours_the_latter(self): properties = property_dict([ Property('thing'), Property('entity'), ]) configuration_a = Configuration(properties, { 'thing': 'foo', 'entity': 'bar', }) configuration_b = Configuration(properties, { 'thing': 'baz', }) configuration = configuration_a.override_with(configuration_b) self.assertEqual(configuration.thing, 'baz') self.assertEqual(configuration.entity, 'bar')
def create_context_for_example( example_type: str, example_name: str) -> TestingContext: example_dir = os.path.join( dir_of_this_script, '..', '..', 'end-to-end', example_type, example_name) configuration = Configuration.load(example_dir) configuration.context_path = example_dir server = Server.from_configuration(configuration) controller = ControllerProxy(server) with capture_build_context( image=configuration.image, image_extensions=configuration.image_extensions, command=configuration.command, context_path=configuration.context_path, excluded_paths=configuration.excluded_paths, included_paths=configuration.included_paths, exclude_gitignored_files=configuration.exclude_gitignored_files, ) as build_context: snapshot_id = submit_context_for_building( user=configuration.user, project=configuration.project, controller=controller, build_context=build_context, quiet_build=True) return TestingContext( configuration=configuration, controller=ControllerProxy(server), snapshot_id=snapshot_id)
def test_invalid_values_cause_a_validation_exception(self): properties = property_dict([ Property('thing', type=int), Property('entity', type=bool), ]) data = { 'thing': 'three', 'entity': False, } configuration = Configuration(properties, data) with self.assertRaises(ValidationException) as raises_context: configuration.validate() self.assertEqual(raises_context.exception.errors, [ ValidationError('The property "thing" must be an integer.\n' 'Invalid value: \'three\'') ])
def harvest(): # The environment should have everything we need to create a controller # during a testing run: host and port for the controller configuration = Configuration.from_env(Configuration.PROPERTIES) server = Server.from_configuration(configuration) controller = ControllerProxy(server) controller.harvest()
def test_non_existent_properties_raise_errors(self): properties = property_dict([ Property('thing'), ]) data = {} configuration = Configuration(properties, data) with self.assertRaises(KeyError): # noinspection PyStatementEffect configuration.entity
def test_missing_values_have_defaults(self): properties = property_dict([ Property('thing'), Property('entity', default='object'), ]) data = {} configuration = Configuration(properties, data) self.assertEqual(configuration.thing, None) self.assertEqual(configuration.entity, 'object')
def test_exposes_properties(self): properties = property_dict([ Property('thing'), Property('entity'), ]) data = { 'thing': 'foo', 'entity': 'bar', } configuration = Configuration(properties, data) self.assertEqual(configuration.thing, 'foo') self.assertEqual(configuration.entity, 'bar')
def create_context_for_example(example_type: str, example_name: str, is_end_to_end_path: bool) -> TestingContext: if is_end_to_end_path: path_to_example = ['..', '..', 'end-to-end'] else: path_to_example = ['..', 'contexts'] example_dir = os.path.join(dir_of_this_script, *path_to_example, example_type, example_name) configuration = Configuration.load(example_dir) configuration.context_path = example_dir configuration.instance_market_type = 'spot' # The default is None (by design, so that the user needs to specify it), # and it will break when running tests against a controller starting # AWS instances configuration.max_bid_price_in_dollars_per_hour = 0.1 # The default in a configuration is 0. With that value, tests take ages to # run as instances are stopped and started again configuration.instance_max_idle_time_in_minutes = 3 server = Server.from_configuration(configuration) controller = ControllerProxy(server) with capture_build_context( image=configuration.image, image_extensions=configuration.image_extensions, command=configuration.command, context_path=configuration.context_path, excluded_paths=configuration.excluded_paths, included_paths=configuration.included_paths, exclude_gitignored_files=configuration.exclude_gitignored_files, ) as build_context: snapshot_id = submit_context_for_building( user=configuration.user, project=configuration.project, controller=controller, build_context=build_context, quiet_build=True) return TestingContext(configuration=configuration, controller=ControllerProxy(server), snapshot_id=snapshot_id)
def main(args=sys.argv[1:]): parser = argparse.ArgumentParser() parser.add_argument('-t', '--ping-timeout', type=int, default=5) parser.add_argument('-c', '--configuration-path', type=str, default=None) subparsers = parser.add_subparsers(title='operations', dest='operation_name') for operation in OPERATIONS: subparser = subparsers.add_parser(operation.name(), help=operation.__doc__) operation.prepare_argument_parser(subparser, args) options = parser.parse_args(args) operation_name = options.operation_name if operation_name is None: parser.print_help() sys.exit(2) try: configuration_path = options.configuration_path \ or os.environ.get('PLZ_CONFIGURATION_PATH', None) configuration = Configuration.load(configuration_path, operation_name) except ValidationException as e: e.print() sys.exit(2) setup_logger(configuration) option_dict = options.__dict__ del option_dict['operation_name'] ping_timeout = options.ping_timeout if operation_name != 'ping-backend': del option_dict['ping_timeout'] else: option_dict['build_timestamp'] = _build_timestamp del option_dict['configuration_path'] operation_classes = [o for o in OPERATIONS if o.name() == operation_name] if len(operation_classes) == 0: log_error('Internal error: couldn\'t find operation: ' f'{operation_name}') sys.exit(os.EX_SOFTWARE) if len(operation_classes) > 1: log_error('Internal error: more than one operation with name: ' f'{operation_name}') sys.exit(os.EX_SOFTWARE) operation = operation_classes[0](configuration=configuration, **option_dict) try: if operation_name != 'ping-backend': # Ping the backend anyway as to avoid wasting user's time when the # backend is down PingBackendOperation(configuration, silent_on_success=True, ping_timeout=ping_timeout, build_timestamp=_build_timestamp).run() operation.run() except KeyboardInterrupt: log_error('Interrupted by the user.') sys.exit(1) except CLIException as e: e.print(configuration) sys.exit(e.exit_code) except ExitWithStatusCodeException as e: sys.exit(e.exit_code)
def create_controller(): configuration = Configuration.from_env(Configuration.PROPERTIES) return ControllerProxy(Server.from_configuration(configuration))