blob: 0a1253ceab9e103550f1189c75d1a0367c037aab [file] [log] [blame]
xixuan82753172017-08-07 09:22:50 -07001# Copyright 2017 The Chromium OS 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"""Module for unittest framework.
6
7This program handles properly importing the App Engine SDK so that test modules
8can use google.appengine.* APIs and the Google App Engine testbed.
9
10Example invocation:
11 $ python runner.py ~/google-cloud-sdk [your sdk path]
12"""
13
14import argparse
15import os
16import sys
17import unittest
18
Xixuan Wu3dd37482017-08-21 14:18:36 -070019# Set GOOGLE_CLOUD_SDK_PATH in user's home directory ~/.
20GOOGLE_CLOUD_SDK_PATH = os.path.join(
21 os.path.expanduser('~'), 'google-cloud-sdk')
22
xixuan82753172017-08-07 09:22:50 -070023
24def fixup_paths(path):
Xixuan Wu3dd37482017-08-21 14:18:36 -070025 """Adds GAE SDK path to system path and appends it to the google path.
xixuan82753172017-08-07 09:22:50 -070026
Xixuan Wu3dd37482017-08-21 14:18:36 -070027 Not all Google packages are inside namespace packages, which means
28 there might be another non-namespace package named `google` already on
29 the path and simply appending the App Engine SDK to the path will not
30 work since the other package will get discovered and used first.
31 This emulates namespace packages by first searching if a `google` package
32 exists by importing it, and if so appending to its module search path.
33
34 Args:
35 path: the path of GAE SDK.
36 """
37 try:
38 # pylint: disable=g-import-not-at-top
39 import google
40 google.__path__.append('{0}/google'.format(path))
41 except ImportError:
42 pass
43
44 sys.path.insert(0, path)
xixuan82753172017-08-07 09:22:50 -070045
46
47def main(sdk_path, test_path, test_pattern):
Xixuan Wu3dd37482017-08-21 14:18:36 -070048 if sdk_path != GOOGLE_CLOUD_SDK_PATH:
49 _import_sdk_path(sdk_path)
xixuan82753172017-08-07 09:22:50 -070050
Xixuan Wu3dd37482017-08-21 14:18:36 -070051 # Loading appengine_config from the current project ensures that any
52 # changes to configuration there are available to all tests (e.g.
53 # sys.path modifications, namespaces, etc.)
54 try:
55 # pylint: disable=g-import-not-at-top
56 import appengine_config
57 # pylint: disable=pointless-statement
58 (appengine_config)
59 except ImportError:
60 print 'Note: unable to import appengine_config.'
xixuan82753172017-08-07 09:22:50 -070061
Xixuan Wu3dd37482017-08-21 14:18:36 -070062 # Discover and run tests.
63 suite = unittest.loader.TestLoader().discover(test_path, test_pattern)
64 return unittest.TextTestRunner(verbosity=2).run(suite)
xixuan82753172017-08-07 09:22:50 -070065
xixuan82753172017-08-07 09:22:50 -070066
Xixuan Wu3dd37482017-08-21 14:18:36 -070067def _import_sdk_path(sdk_path):
68 # If the SDK path points to a Google Cloud SDK installation
69 # then we should alter it to point to the GAE platform location.
70 appengine_path = os.path.join(sdk_path, 'platform/google_appengine')
71 sdk_path = appengine_path if os.path.exists(appengine_path) else sdk_path
72
73 # Make sure google.appengine.* modules are importable.
74 fixup_paths(sdk_path)
75
76 # Make sure all bundled third-party packages are available.
77 # pylint: disable=g-import-not-at-top
78 import dev_appserver
79 dev_appserver.fix_sys_path()
80
81
82def _make_parser():
83 """Return unittest parser."""
84 parser = argparse.ArgumentParser(
85 description=__doc__,
86 formatter_class=argparse.RawDescriptionHelpFormatter)
87 parser.add_argument(
88 '--sdk_path',
89 help='The path to the Google App Engine SDK or the Google Cloud SDK.',
90 default=GOOGLE_CLOUD_SDK_PATH)
91 parser.add_argument(
92 '--test-path',
93 help='The path to look for tests, defaults to the current directory.',
94 default=os.getcwd())
95 parser.add_argument(
96 '--test-pattern',
97 help='The file pattern for test modules, defaults to *_test.py.',
98 default='*_test.py')
99 return parser
xixuan82753172017-08-07 09:22:50 -0700100
101
102if __name__ == '__main__':
Xixuan Wu3dd37482017-08-21 14:18:36 -0700103 unittest_parser = _make_parser()
104 args = unittest_parser.parse_args()
105 try:
106 _import_sdk_path(args.sdk_path)
107 except ImportError:
108 args.sdk_path = raw_input('Cannot find google SDK in %s. Please specify '
109 'your google SDK path: ' % GOOGLE_CLOUD_SDK_PATH)
xixuan82753172017-08-07 09:22:50 -0700110
Xixuan Wu3dd37482017-08-21 14:18:36 -0700111 result = main(args.sdk_path, args.test_path, args.test_pattern)
112 if not result.wasSuccessful():
113 sys.exit(1)