def test_good_configuration(self): self.mox.StubOutWithMock(application_configuration, 'ModuleConfiguration') static_backend_entry = backendinfo.BackendEntry(name='static') dynamic_backend_entry = backendinfo.BackendEntry(name='dynamic') backend_info = backendinfo.BackendInfoExternal( backends=[static_backend_entry, dynamic_backend_entry]) module_config = object() application_configuration.ModuleConfiguration( '/appdir/app.yaml', None).AndReturn(module_config) application_configuration.BackendsConfiguration._parse_configuration( '/appdir/backends.yaml').AndReturn(backend_info) static_configuration = object() dynamic_configuration = object() application_configuration.BackendConfiguration( module_config, mox.IgnoreArg(), static_backend_entry).InAnyOrder().AndReturn(static_configuration) application_configuration.BackendConfiguration( module_config, mox.IgnoreArg(), dynamic_backend_entry).InAnyOrder().AndReturn( dynamic_configuration) self.mox.ReplayAll() config = application_configuration.BackendsConfiguration( '/appdir/app.yaml', '/appdir/backends.yaml') self.assertItemsEqual([static_configuration, dynamic_configuration], config.get_backend_configurations()) self.mox.VerifyAll()
def test_check_for_changes(self): static_backend_entry = backendinfo.BackendEntry(name='static') dynamic_backend_entry = backendinfo.BackendEntry(name='dynamic') backend_info = backendinfo.BackendInfoExternal( backends=[static_backend_entry, dynamic_backend_entry]) module_config = self.mox.CreateMock( application_configuration.ModuleConfiguration) self.mox.StubOutWithMock(application_configuration, 'ModuleConfiguration') application_configuration.ModuleConfiguration( '/appdir/app.yaml', None).AndReturn(module_config) application_configuration.BackendsConfiguration._parse_configuration( '/appdir/backends.yaml').AndReturn(backend_info) module_config.check_for_updates().AndReturn(set()) module_config.check_for_updates().AndReturn(set([1])) module_config.check_for_updates().AndReturn(set([2])) module_config.check_for_updates().AndReturn(set()) self.mox.ReplayAll() config = application_configuration.BackendsConfiguration( '/appdir/app.yaml', '/appdir/backends.yaml') self.assertEqual(set(), config.check_for_updates('dynamic')) self.assertEqual(set([1]), config.check_for_updates('static')) self.assertEqual(set([1, 2]), config.check_for_updates('dynamic')) self.assertEqual(set([2]), config.check_for_updates('static')) self.mox.VerifyAll()
def testCheckInitialized(self): entry = backendinfo.BackendEntry(name='foo') entry.CheckInitialized() entry = backendinfo.BackendEntry() self.assertRaises(validation.ValidationError, backendinfo.BackendEntry.CheckInitialized, entry)
def testClass(self): entry = backendinfo.BackendEntry(name='1') entry.set_class('B1') self.assertEqual('B1', entry.get_class()) entry.set_class('B2') self.assertEqual('B2', entry.get_class()) entry.set_class('B4') self.assertEqual('B4', entry.get_class()) entry.set_class('B8') self.assertEqual('B8', entry.get_class()) entry.set_class('b1') self.assertEqual('b1', entry.get_class()) entry.set_class('b2') self.assertEqual('b2', entry.get_class()) entry.set_class('b4') self.assertEqual('b4', entry.get_class()) entry.set_class('b8') self.assertEqual('b8', entry.get_class()) self.assertRaises(validation.ValidationError, backendinfo.BackendEntry.set_class, entry, 'B0') self.assertRaises(validation.ValidationError, backendinfo.BackendEntry.set_class, entry, 'B3') self.assertRaises(validation.ValidationError, backendinfo.BackendEntry.set_class, entry, 'B5') self.assertRaises(validation.ValidationError, backendinfo.BackendEntry.set_class, entry, 'B7') self.assertRaises(validation.ValidationError, backendinfo.BackendEntry.set_class, entry, 'B9')
def testOptions(self): entry = backendinfo.BackendEntry(name='foo') self.assertFalse(entry.public) self.assertFalse(entry.dynamic) self.assertFalse(entry.failfast) self.assertEqual(None, entry.options) entry = backendinfo.BackendEntry(name='foo', options='public') self.assertTrue(entry.public) self.assertFalse(entry.failfast) self.assertEqual('public', entry.options) entry = backendinfo.BackendEntry(name='foo', options='dynamic') self.assertFalse(entry.public) self.assertTrue(entry.dynamic) self.assertFalse(entry.failfast) self.assertEqual('dynamic', entry.options) entry = backendinfo.BackendEntry(name='foo', options='failfast') self.assertFalse(entry.public) self.assertFalse(entry.dynamic) self.assertTrue(entry.failfast) self.assertEqual('failfast', entry.options) entry = backendinfo.BackendEntry(name='foo', options='public, dynamic, failfast') self.assertTrue(entry.public) self.assertTrue(entry.dynamic) self.assertTrue(entry.failfast) self.assertEqual('public, dynamic, failfast', entry.options) try: backendinfo.BackendEntry(name='foo', public=True) fail() except backendinfo.BadConfig: pass try: backendinfo.BackendEntry(name='foo', dynamic=True) fail() except backendinfo.BadConfig: pass try: backendinfo.BackendEntry(name='foo', failfast=True) fail() except backendinfo.BadConfig: pass try: backendinfo.BackendEntry(name='foo', options='hello') fail() except backendinfo.BadConfig: pass
def test_good_configuration_dynamic_scaling(self): automatic_scaling = appinfo.AutomaticScaling( min_pending_latency='1.0s', max_pending_latency='2.0s', min_idle_instances=1, max_idle_instances=2) error_handlers = [appinfo.ErrorHandlers(file='error.html')] handlers = [appinfo.URLMap()] env_variables = appinfo.EnvironmentVariables() info = appinfo.AppInfoExternal( application='app', module='module1', version='1', runtime='python27', threadsafe=False, automatic_scaling=automatic_scaling, skip_files=r'\*.gif', error_handlers=error_handlers, handlers=handlers, inbound_services=['warmup'], env_variables=env_variables, ) backend_entry = backendinfo.BackendEntry(name='dynamic', instances='3', options='public, dynamic', start='handler') application_configuration.ModuleConfiguration._parse_configuration( '/appdir/app.yaml').AndReturn((info, [])) os.path.getmtime('/appdir/app.yaml').AndReturn(10) self.mox.ReplayAll() module_config = application_configuration.ModuleConfiguration( '/appdir/app.yaml') config = application_configuration.BackendConfiguration( module_config, None, backend_entry) self.mox.VerifyAll() self.assertEqual(os.path.realpath('/appdir'), config.application_root) self.assertEqual('app', config.application) self.assertEqual('dynamic', config.module_name) self.assertEqual('1', config.major_version) self.assertRegexpMatches(config.version_id, r'dynamic:1\.\d+') self.assertEqual('python27', config.runtime) self.assertFalse(config.threadsafe) self.assertEqual(None, config.automatic_scaling) self.assertEqual(None, config.manual_scaling) self.assertEqual(appinfo.BasicScaling(max_instances='3'), config.basic_scaling) self.assertEqual(info.GetNormalizedLibraries(), config.normalized_libraries) self.assertEqual(r'\*.gif', config.skip_files) self.assertEqual(error_handlers, config.error_handlers) start_handler = appinfo.URLMap(url='/_ah/start', script=backend_entry.start, login='******') self.assertEqual([start_handler] + handlers, config.handlers) self.assertEqual(['warmup'], config.inbound_services) self.assertEqual(env_variables, config.env_variables)
def testStart(self): entry = backendinfo.BackendEntry(name='1', start='bar/foo.py') self.assertEqual('bar/foo.py', entry.start) entry.start = 'a' * 256 self.assertEqual('a' * 256, entry.start) try: entry.name = 'a' * 257 self.fail() except validation.ValidationError: pass
def testName(self): entry = backendinfo.BackendEntry(name='1') self.assertEqual('1', entry.name) entry.name = '1' * 100 self.assertEqual('1' * 100, entry.name) try: entry.name = '1' * 101 self.fail() except validation.ValidationError: pass
def testToYAML(self): backend = backendinfo.BackendEntry( name='s1', instances=2, start='test/foo.py', options='public, dynamic, failfast', max_concurrent_requests=5, state='START', ) backend.set_class('B2') self.assertEqual( 'name: s1\n' 'class: B2\n' 'instances: 2\n' 'start: test/foo.py\n' 'options: public, dynamic, failfast\n' 'max_concurrent_requests: 5\n' 'state: START\n', backend.ToYAML()) backend.set_class(None) self.assertEqual( 'name: s1\n' 'instances: 2\n' 'start: test/foo.py\n' 'options: public, dynamic, failfast\n' 'max_concurrent_requests: 5\n' 'state: START\n', backend.ToYAML()) backend.instances = None self.assertEqual( 'name: s1\n' 'start: test/foo.py\n' 'options: public, dynamic, failfast\n' 'max_concurrent_requests: 5\n' 'state: START\n', backend.ToYAML()) backend.start = None self.assertEqual( 'name: s1\n' 'options: public, dynamic, failfast\n' 'max_concurrent_requests: 5\n' 'state: START\n', backend.ToYAML()) backend.options = None self.assertEqual( 'name: s1\n' 'max_concurrent_requests: 5\n' 'state: START\n', backend.ToYAML()) backend.max_concurrent_requests = None self.assertEqual('name: s1\n' 'state: START\n', backend.ToYAML()) backend.state = None self.assertEqual('name: s1\n', backend.ToYAML())
def test_check_for_changes(self): backends_config = self.mox.CreateMock( application_configuration.BackendsConfiguration) config = application_configuration.BackendConfiguration( None, backends_config, backendinfo.BackendEntry(name='backend')) changes = object() backends_config.check_for_updates('backend').AndReturn([]) backends_config.check_for_updates('backend').AndReturn(changes) minor_version = config._minor_version_id self.mox.ReplayAll() self.assertEqual([], config.check_for_updates()) self.assertEqual(minor_version, config._minor_version_id) self.assertEqual(changes, config.check_for_updates()) self.assertNotEqual(minor_version, config._minor_version_id) self.mox.VerifyAll()
def test_vm_app_yaml_configuration(self): automatic_scaling = appinfo.AutomaticScaling(min_pending_latency='1.0s', max_pending_latency='2.0s', min_idle_instances=1, max_idle_instances=2) vm_settings = appinfo.VmSettings() vm_settings['vm_runtime'] = 'myawesomeruntime' info = appinfo.AppInfoExternal( application='app', module='module1', version='1', runtime='vm', vm_settings=vm_settings, threadsafe=False, automatic_scaling=automatic_scaling, ) backend_entry = backendinfo.BackendEntry( name='static', instances='3', options='public') application_configuration.ModuleConfiguration._parse_configuration( '/appdir/app.yaml').AndReturn((info, ['/appdir/app.yaml'])) os.path.getmtime('/appdir/app.yaml').AndReturn(10) self.mox.ReplayAll() module_config = application_configuration.ModuleConfiguration( '/appdir/app.yaml') config = application_configuration.BackendConfiguration( module_config, None, backend_entry) self.mox.VerifyAll() self.assertEqual(os.path.realpath('/appdir'), config.application_root) self.assertEqual('dev~app', config.application) self.assertEqual('app', config.application_external_name) self.assertEqual('dev', config.partition) self.assertEqual('static', config.module_name) self.assertEqual('1', config.major_version) self.assertRegexpMatches(config.version_id, r'static:1\.\d+') self.assertEqual('vm', config.runtime) self.assertEqual(vm_settings['vm_runtime'], config.effective_runtime) self.assertFalse(config.threadsafe) # Resident backends are assigned manual scaling. self.assertEqual(None, config.automatic_scaling) self.assertEqual(None, config.basic_scaling) self.assertEqual(appinfo.ManualScaling(instances='3'), config.manual_scaling)
def test_good_configuration(self): automatic_scaling = appinfo.AutomaticScaling( min_pending_latency='1.0s', max_pending_latency='2.0s', min_idle_instances=1, max_idle_instances=2) error_handlers = [appinfo.ErrorHandlers(file='error.html')] handlers = [appinfo.URLMap()] env_variables = appinfo.EnvironmentVariables() info = appinfo.AppInfoExternal( application='app', module='module1', version='1', runtime='python27', threadsafe=False, automatic_scaling=automatic_scaling, skip_files=r'\*.gif', error_handlers=error_handlers, handlers=handlers, inbound_services=['warmup'], env_variables=env_variables, ) backend_entry = backendinfo.BackendEntry(name='static', instances='3', options='public') application_configuration.ModuleConfiguration._parse_configuration( '/appdir/app.yaml').AndReturn((info, [])) os.path.getmtime('/appdir/app.yaml').AndReturn(10) self.mox.ReplayAll() module_config = application_configuration.ModuleConfiguration( '/appdir/app.yaml') config = application_configuration.BackendConfiguration( module_config, None, backend_entry) self.mox.VerifyAll() self.assertEqual(os.path.realpath('/appdir'), config.application_root) self.assertEqual('app', config.application) self.assertEqual('static', config.module_name) self.assertEqual('1', config.major_version) self.assertRegexpMatches(config.version_id, r'static:1\.\d+') self.assertEqual('python27', config.runtime) self.assertFalse(config.threadsafe) self.assertEqual(None, config.automatic_scaling) self.assertEqual(None, config.basic_scaling) self.assertEqual(appinfo.ManualScaling(instances='3'), config.manual_scaling) self.assertEqual(info.GetNormalizedLibraries(), config.normalized_libraries) self.assertEqual(r'\*.gif', config.skip_files) self.assertEqual(error_handlers, config.error_handlers) self.assertEqual(handlers, config.handlers) self.assertEqual(['warmup'], config.inbound_services) self.assertEqual(env_variables, config.env_variables) whitelist_fields = [ 'module_name', 'version_id', 'automatic_scaling', 'manual_scaling', 'basic_scaling', 'is_backend' ] # Check that all public attributes and methods in a ModuleConfiguration # exist in a BackendConfiguration. for field in dir(module_config): if not field.startswith('_'): self.assertTrue(hasattr(config, field), 'Missing field: %s' % field) value = getattr(module_config, field) if field not in whitelist_fields and not callable(value): # Check that the attributes other than those in the whitelist have # equal values in the BackendConfiguration to the ModuleConfiguration # from which it inherits. self.assertEqual(value, getattr(config, field))