def setUp(self): self.mox = mox.Mox() self.tmpdir = tempfile.mkdtemp() module_configuration = ModuleConfigurationStub( application_root=self.tmpdir, error_handlers=[ appinfo.ErrorHandlers(error_code='over_quota', file='foo.html'), appinfo.ErrorHandlers(error_code='default', file='error.html'), ]) self.runtime_config = runtime_config_pb2.Config() self.runtime_config.app_id = 'app' self.runtime_config.version_id = 'version' self.runtime_config.api_port = 12345 self.runtime_config.application_root = self.tmpdir self.runtime_config.datacenter = 'us1' self.runtime_config.instance_id = 'abc3dzac4' self.runtime_config.auth_domain = 'gmail.com' self.runtime_config_getter = lambda: self.runtime_config self.proxy = http_runtime.HttpRuntimeProxy(['/runtime'], self.runtime_config_getter, module_configuration, env={'foo': 'bar'}) self.process = self.mox.CreateMock(subprocess.Popen) self.process.stdin = self.mox.CreateMockAnything() self.process.stdout = self.mox.CreateMockAnything() self.mox.StubOutWithMock(safe_subprocess, 'start_process') self.mox.StubOutWithMock(httplib.HTTPConnection, 'connect') self.mox.StubOutWithMock(httplib.HTTPConnection, 'request') self.mox.StubOutWithMock(httplib.HTTPConnection, 'getresponse') self.mox.StubOutWithMock(httplib.HTTPConnection, 'close') self.mox.StubOutWithMock(login, 'get_user_info') self.mox.StubOutWithMock(shutdown, 'async_quit') self.url_map = appinfo.URLMap(url=r'/(get|post).*', script=r'\1.py')
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 test_check_for_mutable_changes(self): info1 = appinfo.AppInfoExternal( application='app', module='default', version='version', runtime='python27', threadsafe=False, libraries=[appinfo.Library(name='django', version='latest')], skip_files='.*', handlers=[], inbound_services=['warmup'], env_variables=appinfo.EnvironmentVariables(), error_handlers=[appinfo.ErrorHandlers(file='error.html')], ) info2 = appinfo.AppInfoExternal( application='app', module='default', version='version', runtime='python27', threadsafe=False, libraries=[appinfo.Library(name='jinja2', version='latest')], skip_files=r'.*\.py', handlers=[appinfo.URLMap()], inbound_services=[], ) application_configuration.ModuleConfiguration._parse_configuration( '/appdir/app.yaml').AndReturn((info1, [])) os.path.getmtime('/appdir/app.yaml').AndReturn(10) os.path.getmtime('/appdir/app.yaml').AndReturn(11) application_configuration.ModuleConfiguration._parse_configuration( '/appdir/app.yaml').AndReturn((info2, [])) os.path.getmtime('/appdir/app.yaml').AndReturn(11) self.mox.ReplayAll() config = application_configuration.ModuleConfiguration( '/appdir/app.yaml') self.assertSequenceEqual( set([ application_configuration.NORMALIZED_LIBRARIES_CHANGED, application_configuration.SKIP_FILES_CHANGED, application_configuration.HANDLERS_CHANGED, application_configuration.INBOUND_SERVICES_CHANGED, application_configuration.ENV_VARIABLES_CHANGED, application_configuration.ERROR_HANDLERS_CHANGED ]), config.check_for_updates()) self.mox.VerifyAll() self.assertEqual(info2.GetNormalizedLibraries(), config.normalized_libraries) self.assertEqual(info2.skip_files, config.skip_files) self.assertEqual(info2.error_handlers, config.error_handlers) self.assertEqual(info2.handlers, config.handlers) self.assertEqual(info2.inbound_services, config.inbound_services) self.assertEqual(info2.env_variables, config.env_variables)
def test_good_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) 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, ) appinfo_includes.ParseAndReturnIncludePaths(mox.IgnoreArg()).AndReturn( (info, [])) os.path.getmtime('/appdir/app.yaml').AndReturn(10) self.mox.ReplayAll() config = application_configuration.ModuleConfiguration( '/appdir/app.yaml') self.mox.VerifyAll() self.assertEqual(os.path.realpath('/appdir'), config.application_root) self.assertEqual(os.path.realpath('/appdir/app.yaml'), config.config_path) self.assertEqual('dev~app', config.application) self.assertEqual('app', config.application_external_name) self.assertEqual('dev', config.partition) self.assertEqual('module1', config.module_name) self.assertEqual('1', config.major_version) self.assertRegexpMatches(config.version_id, r'module1:1\.\d+') self.assertEqual('python27', config.runtime) self.assertFalse(config.threadsafe) self.assertEqual(automatic_scaling, config.automatic_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) self.assertEqual({'/appdir/app.yaml': 10}, config._mtimes)
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))