run_tests.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #!/usr/bin/env python
  2. import argparse
  3. import glob
  4. import os
  5. import os.path as p
  6. import subprocess
  7. import sys
  8. DIR_OF_THIS_SCRIPT = p.dirname( p.abspath( __file__ ) )
  9. DIR_OF_THIRD_PARTY = p.join( DIR_OF_THIS_SCRIPT, 'third_party' )
  10. # We don't include python-future (not to be confused with pythonfutures) because
  11. # it needs to be inserted in sys.path AFTER the standard library imports but we
  12. # can't do that with PYTHONPATH because the std lib paths are always appended to
  13. # PYTHONPATH. We do it correctly inside Vim because we have access to the right
  14. # sys.path. So for dev, we rely on python-future being installed correctly with
  15. #
  16. # pip install -r python/test_requirements.txt
  17. #
  18. # Pip knows how to install this correctly so that it doesn't matter where in
  19. # sys.path the path is.
  20. python_path = [ p.join( DIR_OF_THIRD_PARTY, 'pythonfutures' ),
  21. p.join( DIR_OF_THIRD_PARTY, 'requests-futures' ),
  22. p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'chardet' ),
  23. p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'certifi' ),
  24. p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'idna' ),
  25. p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'requests' ),
  26. p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'urllib3', 'src' ),
  27. p.join( DIR_OF_THIRD_PARTY, 'ycmd' ) ]
  28. if os.environ.get( 'PYTHONPATH' ):
  29. python_path.append( os.environ[ 'PYTHONPATH' ] )
  30. os.environ[ 'PYTHONPATH' ] = os.pathsep.join( python_path )
  31. def RunFlake8():
  32. print( 'Running flake8' )
  33. args = [ sys.executable,
  34. '-m',
  35. 'flake8',
  36. p.join( DIR_OF_THIS_SCRIPT, 'python' ) ]
  37. root_dir_scripts = glob.glob( p.join( DIR_OF_THIS_SCRIPT, '*.py' ) )
  38. args.extend( root_dir_scripts )
  39. subprocess.check_call( args )
  40. def ParseArguments():
  41. parser = argparse.ArgumentParser()
  42. parser.add_argument( '--skip-build', action = 'store_true',
  43. help = 'Do not build ycmd before testing' )
  44. parser.add_argument( '--coverage', action = 'store_true',
  45. help = 'Enable coverage report' )
  46. parser.add_argument( '--no-flake8', action = 'store_true',
  47. help = 'Do not run flake8' )
  48. parser.add_argument( '--dump-path', action = 'store_true',
  49. help = 'Dump the PYTHONPATH required to run tests '
  50. 'manually, then exit.' )
  51. parsed_args, nosetests_args = parser.parse_known_args()
  52. if 'COVERAGE' in os.environ:
  53. parsed_args.coverage = ( os.environ[ 'COVERAGE' ] == 'true' )
  54. return parsed_args, nosetests_args
  55. def BuildYcmdLibs( args ):
  56. if not args.skip_build:
  57. subprocess.check_call( [
  58. sys.executable,
  59. p.join( DIR_OF_THIS_SCRIPT, 'third_party', 'ycmd', 'build.py' )
  60. ] )
  61. def NoseTests( parsed_args, extra_nosetests_args ):
  62. # Always passing --with-id to nosetests enables non-surprising usage of
  63. # its --failed flag.
  64. nosetests_args = [ '-v', '--with-id' ]
  65. if parsed_args.coverage:
  66. nosetests_args += [ '--with-coverage',
  67. '--cover-erase',
  68. '--cover-package=ycm',
  69. '--cover-html' ]
  70. if extra_nosetests_args:
  71. nosetests_args.extend( extra_nosetests_args )
  72. else:
  73. nosetests_args.append( p.join( DIR_OF_THIS_SCRIPT, 'python' ) )
  74. subprocess.check_call( [ sys.executable, '-m', 'nose' ] + nosetests_args )
  75. def Main():
  76. ( parsed_args, nosetests_args ) = ParseArguments()
  77. if parsed_args.dump_path:
  78. print( os.environ[ 'PYTHONPATH' ] )
  79. sys.exit()
  80. if not parsed_args.no_flake8:
  81. RunFlake8()
  82. BuildYcmdLibs( parsed_args )
  83. NoseTests( parsed_args, nosetests_args )
  84. if __name__ == "__main__":
  85. Main()