OLD | NEW |
(Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. |
| 4 |
| 5 import json |
| 6 import logging |
| 7 import os |
| 8 import webtest |
| 9 |
| 10 import oauth2client.client |
| 11 import googleapiclient.http |
| 12 from google.appengine.api import app_identity |
| 13 from testing_utils import testing |
| 14 |
| 15 import common |
| 16 import vm_module |
| 17 |
| 18 |
| 19 class VMModuleTest(testing.AppengineTestCase): |
| 20 def test_get_config_data(self): |
| 21 self.assertIsNone(vm_module._get_config_data()) |
| 22 |
| 23 data = common.MonAcqData() |
| 24 class MonAcqMock(object): |
| 25 @classmethod |
| 26 def get_by_id(cls, _key): |
| 27 return data |
| 28 |
| 29 self.mock(common, 'MonAcqData', MonAcqMock) |
| 30 self.assertIsInstance(vm_module._get_config_data(), dict) |
| 31 |
| 32 def test_get_credentials(self): |
| 33 class CredentialsMock(object): |
| 34 def __init__(self, **kwargs): |
| 35 pass |
| 36 self.mock(oauth2client.client, 'SignedJwtAssertionCredentials', |
| 37 CredentialsMock) |
| 38 creds = { |
| 39 'client_email': 'we@you.me', |
| 40 'client_id': 'agent007', |
| 41 'private_key': 'deadbeafyoudneverguess', |
| 42 'private_key_id': '!@#$%', |
| 43 } |
| 44 scopes = ['this', 'that'] |
| 45 self.assertIsInstance(vm_module._get_credentials(creds, scopes), object) |
| 46 |
| 47 |
| 48 class VMHandlerTest(testing.AppengineTestCase): |
| 49 |
| 50 @property |
| 51 def app_module(self): |
| 52 return vm_module.app |
| 53 |
| 54 def test_get(self): |
| 55 with self.assertRaises(webtest.AppError) as cm: |
| 56 self.test_app.get('/vm1') |
| 57 logging.info('exception = %s', cm.exception) |
| 58 self.assertIn('405', str(cm.exception)) |
| 59 |
| 60 def test_post(self): |
| 61 # Authenticated production server. |
| 62 self.mock(os, 'environ', {'SERVER_SOFTWARE': 'GAE production server'}) |
| 63 headers = {'X-Appengine-Inbound-Appid': 'my-app-id'} |
| 64 |
| 65 # Authentication fails. |
| 66 self.mock(app_identity, 'get_application_id', lambda: 'bad-app-id') |
| 67 with self.assertRaises(webtest.AppError) as cm: |
| 68 self.test_app.post('/vm1', '', headers=headers) |
| 69 logging.info('exception = %s', cm.exception) |
| 70 self.assertIn('403', str(cm.exception)) |
| 71 |
| 72 # Authentication succeeds. |
| 73 self.mock(app_identity, 'get_application_id', lambda: 'my-app-id') |
| 74 |
| 75 # No data is configured. |
| 76 self.mock(vm_module, '_get_config_data', lambda: None) |
| 77 with self.assertRaises(webtest.AppError) as cm: |
| 78 self.test_app.post('/vm1', '', headers=headers) |
| 79 logging.info('exception = %s', cm.exception) |
| 80 self.assertIn('500', str(cm.exception)) |
| 81 |
| 82 # Not all required data is present. |
| 83 self.mock(vm_module, '_get_config_data', |
| 84 lambda: {'url': 'foo://', 'bad': 'data'}) |
| 85 with self.assertRaises(webtest.AppError) as cm: |
| 86 self.test_app.post('/vm1', '', headers=headers) |
| 87 logging.info('exception = %s', cm.exception) |
| 88 self.assertIn('500', str(cm.exception)) |
| 89 |
| 90 # Credentials are malformed. |
| 91 self.mock(vm_module, '_get_config_data', lambda: { |
| 92 'url': 'foo://', 'scopes': ['this', 'that'], |
| 93 'credentials': {'bad': 'value'}}) |
| 94 with self.assertRaises(webtest.AppError) as cm: |
| 95 self.test_app.post('/vm1', '', headers=headers) |
| 96 logging.info('exception = %s', cm.exception) |
| 97 self.assertIn('500', str(cm.exception)) |
| 98 |
| 99 # Data is correct. |
| 100 creds = { |
| 101 'client_email': 'we@you.me', |
| 102 'client_id': 'agent007', |
| 103 'private_key': 'deadbeafyoudneverguess', |
| 104 'private_key_id': '!@#$%', |
| 105 } |
| 106 class CredentialsMock(object): |
| 107 def __init__(self, **kwargs): |
| 108 pass |
| 109 |
| 110 def authorize(self, x): |
| 111 return x |
| 112 |
| 113 self.mock(oauth2client.client, 'SignedJwtAssertionCredentials', |
| 114 CredentialsMock) |
| 115 self.mock(vm_module, '_get_config_data', lambda: { |
| 116 'url': 'foo://', 'scopes': ['this', 'that'], |
| 117 'credentials': creds}) |
| 118 |
| 119 class ResponseMock(dict): |
| 120 def __init__(self, status, reason): |
| 121 self.status = status |
| 122 self.reason = reason |
| 123 |
| 124 # Production server, unsuccessful request. |
| 125 def execute_mock_bad(self): |
| 126 self.postproc(ResponseMock(404, 'Not OK'), 'content') |
| 127 self.mock(googleapiclient.http.HttpRequest, 'execute', execute_mock_bad) |
| 128 |
| 129 response = self.test_app.post('/vm1', '', headers=headers) |
| 130 logging.info('response = %s', response) |
| 131 self.assertEquals(200, response.status_int) |
| 132 |
| 133 # Production server, successful request. |
| 134 def execute_mock_good(self): |
| 135 self.postproc(ResponseMock(200, 'OK'), 'content') |
| 136 self.mock(googleapiclient.http.HttpRequest, 'execute', execute_mock_good) |
| 137 |
| 138 response = self.test_app.post('/vm1', '', headers=headers) |
| 139 logging.info('response = %s', response) |
| 140 self.assertEquals(200, response.status_int) |
| 141 |
| 142 # Dev appserver (for branch coverage). |
| 143 self.mock(os, 'environ', {'SERVER_SOFTWARE': 'Development server'}) |
| 144 response = self.test_app.post('/vm1', '', headers=headers) |
| 145 logging.info('response = %s', response) |
| 146 self.assertEquals(200, response.status_int) |
OLD | NEW |