tests.py 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682
  1. # -*- coding: utf-8 -*-
  2. """
  3. A series of tests to establish that the command-line managment tools work as
  4. advertised - especially with regards to the handling of the DJANGO_SETTINGS_MODULE
  5. and default settings.py files.
  6. """
  7. from __future__ import unicode_literals
  8. import os
  9. import re
  10. import shutil
  11. import socket
  12. import subprocess
  13. import sys
  14. import codecs
  15. import django
  16. from django import conf, get_version
  17. from django.conf import settings
  18. from django.core.management import BaseCommand, CommandError
  19. from django.db import connection
  20. from django.test.runner import DiscoverRunner
  21. from django.utils import unittest
  22. from django.utils.encoding import force_text
  23. from django.utils._os import upath
  24. from django.utils.six import StringIO
  25. from django.test import LiveServerTestCase
  26. test_dir = os.path.realpath(os.path.join(os.environ['DJANGO_TEST_TEMP_DIR'], 'test_project'))
  27. if not os.path.exists(test_dir):
  28. os.mkdir(test_dir)
  29. open(os.path.join(test_dir, '__init__.py'), 'w').close()
  30. custom_templates_dir = os.path.join(os.path.dirname(__file__), 'custom_templates')
  31. class AdminScriptTestCase(unittest.TestCase):
  32. def write_settings(self, filename, apps=None, is_dir=False, sdict=None):
  33. if is_dir:
  34. settings_dir = os.path.join(test_dir, filename)
  35. os.mkdir(settings_dir)
  36. settings_file_path = os.path.join(settings_dir, '__init__.py')
  37. else:
  38. settings_file_path = os.path.join(test_dir, filename)
  39. with open(settings_file_path, 'w') as settings_file:
  40. settings_file.write('# Settings file automatically generated by admin_scripts test case\n')
  41. exports = [
  42. 'DATABASES',
  43. 'ROOT_URLCONF',
  44. 'SECRET_KEY',
  45. ]
  46. for s in exports:
  47. if hasattr(settings, s):
  48. o = getattr(settings, s)
  49. if not isinstance(o, dict):
  50. o = "'%s'" % o
  51. settings_file.write("%s = %s\n" % (s, o))
  52. if apps is None:
  53. apps = ['django.contrib.auth', 'django.contrib.contenttypes', 'admin_scripts']
  54. settings_file.write("INSTALLED_APPS = %s\n" % apps)
  55. if sdict:
  56. for k, v in sdict.items():
  57. settings_file.write("%s = %s\n" % (k, v))
  58. def remove_settings(self, filename, is_dir=False):
  59. full_name = os.path.join(test_dir, filename)
  60. if is_dir:
  61. shutil.rmtree(full_name)
  62. else:
  63. os.remove(full_name)
  64. # Also try to remove the compiled file; if it exists, it could
  65. # mess up later tests that depend upon the .py file not existing
  66. try:
  67. if sys.platform.startswith('java'):
  68. # Jython produces module$py.class files
  69. os.remove(re.sub(r'\.py$', '$py.class', full_name))
  70. else:
  71. # CPython produces module.pyc files
  72. os.remove(full_name + 'c')
  73. except OSError:
  74. pass
  75. # Also remove a __pycache__ directory, if it exists
  76. cache_name = os.path.join(test_dir, '__pycache__')
  77. if os.path.isdir(cache_name):
  78. shutil.rmtree(cache_name)
  79. def _ext_backend_paths(self):
  80. """
  81. Returns the paths for any external backend packages.
  82. """
  83. paths = []
  84. first_package_re = re.compile(r'(^[^\.]+)\.')
  85. for backend in settings.DATABASES.values():
  86. result = first_package_re.findall(backend['ENGINE'])
  87. if result and result != ['django']:
  88. backend_pkg = __import__(result[0])
  89. backend_dir = os.path.dirname(backend_pkg.__file__)
  90. paths.append(os.path.dirname(backend_dir))
  91. return paths
  92. def run_test(self, script, args, settings_file=None, apps=None):
  93. project_dir = test_dir
  94. base_dir = os.path.dirname(test_dir)
  95. # The base dir for Django's tests is one level up.
  96. tests_dir = os.path.dirname(os.path.dirname(__file__))
  97. # The base dir for Django is one level above the test dir. We don't use
  98. # `import django` to figure that out, so we don't pick up a Django
  99. # from site-packages or similar.
  100. django_dir = os.path.dirname(tests_dir)
  101. ext_backend_base_dirs = self._ext_backend_paths()
  102. # Remember the old environment
  103. old_django_settings_module = os.environ.get('DJANGO_SETTINGS_MODULE', None)
  104. if sys.platform.startswith('java'):
  105. python_path_var_name = 'JYTHONPATH'
  106. else:
  107. python_path_var_name = 'PYTHONPATH'
  108. old_python_path = os.environ.get(python_path_var_name, None)
  109. old_cwd = os.getcwd()
  110. # Set the test environment
  111. if settings_file:
  112. os.environ['DJANGO_SETTINGS_MODULE'] = settings_file
  113. elif 'DJANGO_SETTINGS_MODULE' in os.environ:
  114. del os.environ['DJANGO_SETTINGS_MODULE']
  115. python_path = [base_dir, django_dir, tests_dir]
  116. python_path.extend(ext_backend_base_dirs)
  117. os.environ[python_path_var_name] = os.pathsep.join(python_path)
  118. # Move to the test directory and run
  119. os.chdir(test_dir)
  120. out, err = subprocess.Popen([sys.executable, script] + args,
  121. stdout=subprocess.PIPE, stderr=subprocess.PIPE,
  122. universal_newlines=True).communicate()
  123. # Restore the old environment
  124. if old_django_settings_module:
  125. os.environ['DJANGO_SETTINGS_MODULE'] = old_django_settings_module
  126. if old_python_path:
  127. os.environ[python_path_var_name] = old_python_path
  128. # Move back to the old working directory
  129. os.chdir(old_cwd)
  130. return out, err
  131. def run_django_admin(self, args, settings_file=None):
  132. script_dir = os.path.abspath(os.path.join(os.path.dirname(upath(django.__file__)), 'bin'))
  133. return self.run_test(os.path.join(script_dir, 'django-admin.py'), args, settings_file)
  134. def run_manage(self, args, settings_file=None):
  135. def safe_remove(path):
  136. try:
  137. os.remove(path)
  138. except OSError:
  139. pass
  140. conf_dir = os.path.dirname(upath(conf.__file__))
  141. template_manage_py = os.path.join(conf_dir, 'project_template', 'manage.py')
  142. test_manage_py = os.path.join(test_dir, 'manage.py')
  143. shutil.copyfile(template_manage_py, test_manage_py)
  144. with open(test_manage_py, 'r') as fp:
  145. manage_py_contents = fp.read()
  146. manage_py_contents = manage_py_contents.replace(
  147. "{{ project_name }}", "test_project")
  148. with open(test_manage_py, 'w') as fp:
  149. fp.write(manage_py_contents)
  150. self.addCleanup(safe_remove, test_manage_py)
  151. return self.run_test('./manage.py', args, settings_file)
  152. def assertNoOutput(self, stream):
  153. "Utility assertion: assert that the given stream is empty"
  154. self.assertEqual(len(stream), 0, "Stream should be empty: actually contains '%s'" % stream)
  155. def assertOutput(self, stream, msg):
  156. "Utility assertion: assert that the given message exists in the output"
  157. stream = force_text(stream)
  158. self.assertTrue(msg in stream, "'%s' does not match actual output text '%s'" % (msg, stream))
  159. def assertNotInOutput(self, stream, msg):
  160. "Utility assertion: assert that the given message doesn't exist in the output"
  161. stream = force_text(stream)
  162. self.assertFalse(msg in stream, "'%s' matches actual output text '%s'" % (msg, stream))
  163. ##########################################################################
  164. # DJANGO ADMIN TESTS
  165. # This first series of test classes checks the environment processing
  166. # of the django-admin.py script
  167. ##########################################################################
  168. class DjangoAdminNoSettings(AdminScriptTestCase):
  169. "A series of tests for django-admin.py when there is no settings.py file."
  170. def test_builtin_command(self):
  171. "no settings: django-admin builtin commands fail with an error when no settings provided"
  172. args = ['sqlall', 'admin_scripts']
  173. out, err = self.run_django_admin(args)
  174. self.assertNoOutput(out)
  175. self.assertOutput(err, 'settings are not configured')
  176. def test_builtin_with_bad_settings(self):
  177. "no settings: django-admin builtin commands fail if settings file (from argument) doesn't exist"
  178. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  179. out, err = self.run_django_admin(args)
  180. self.assertNoOutput(out)
  181. self.assertOutput(err, "Could not import settings 'bad_settings'")
  182. def test_builtin_with_bad_environment(self):
  183. "no settings: django-admin builtin commands fail if settings file (from environment) doesn't exist"
  184. args = ['sqlall', 'admin_scripts']
  185. out, err = self.run_django_admin(args, 'bad_settings')
  186. self.assertNoOutput(out)
  187. self.assertOutput(err, "Could not import settings 'bad_settings'")
  188. class DjangoAdminDefaultSettings(AdminScriptTestCase):
  189. """A series of tests for django-admin.py when using a settings.py file that
  190. contains the test application.
  191. """
  192. def setUp(self):
  193. self.write_settings('settings.py')
  194. def tearDown(self):
  195. self.remove_settings('settings.py')
  196. def test_builtin_command(self):
  197. "default: django-admin builtin commands fail with an error when no settings provided"
  198. args = ['sqlall', 'admin_scripts']
  199. out, err = self.run_django_admin(args)
  200. self.assertNoOutput(out)
  201. self.assertOutput(err, 'settings are not configured')
  202. def test_builtin_with_settings(self):
  203. "default: django-admin builtin commands succeed if settings are provided as argument"
  204. args = ['sqlall', '--settings=test_project.settings', 'admin_scripts']
  205. out, err = self.run_django_admin(args)
  206. self.assertNoOutput(err)
  207. self.assertOutput(out, 'CREATE TABLE')
  208. def test_builtin_with_environment(self):
  209. "default: django-admin builtin commands succeed if settings are provided in the environment"
  210. args = ['sqlall', 'admin_scripts']
  211. out, err = self.run_django_admin(args, 'test_project.settings')
  212. self.assertNoOutput(err)
  213. self.assertOutput(out, 'CREATE TABLE')
  214. def test_builtin_with_bad_settings(self):
  215. "default: django-admin builtin commands fail if settings file (from argument) doesn't exist"
  216. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  217. out, err = self.run_django_admin(args)
  218. self.assertNoOutput(out)
  219. self.assertOutput(err, "Could not import settings 'bad_settings'")
  220. def test_builtin_with_bad_environment(self):
  221. "default: django-admin builtin commands fail if settings file (from environment) doesn't exist"
  222. args = ['sqlall', 'admin_scripts']
  223. out, err = self.run_django_admin(args, 'bad_settings')
  224. self.assertNoOutput(out)
  225. self.assertOutput(err, "Could not import settings 'bad_settings'")
  226. def test_custom_command(self):
  227. "default: django-admin can't execute user commands if it isn't provided settings"
  228. args = ['noargs_command']
  229. out, err = self.run_django_admin(args)
  230. self.assertNoOutput(out)
  231. self.assertOutput(err, "Unknown command: 'noargs_command'")
  232. def test_custom_command_with_settings(self):
  233. "default: django-admin can execute user commands if settings are provided as argument"
  234. args = ['noargs_command', '--settings=test_project.settings']
  235. out, err = self.run_django_admin(args)
  236. self.assertNoOutput(err)
  237. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  238. def test_custom_command_with_environment(self):
  239. "default: django-admin can execute user commands if settings are provided in environment"
  240. args = ['noargs_command']
  241. out, err = self.run_django_admin(args, 'test_project.settings')
  242. self.assertNoOutput(err)
  243. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  244. class DjangoAdminFullPathDefaultSettings(AdminScriptTestCase):
  245. """A series of tests for django-admin.py when using a settings.py file that
  246. contains the test application specified using a full path.
  247. """
  248. def setUp(self):
  249. self.write_settings('settings.py', ['django.contrib.auth', 'django.contrib.contenttypes', 'admin_scripts'])
  250. def tearDown(self):
  251. self.remove_settings('settings.py')
  252. def test_builtin_command(self):
  253. "fulldefault: django-admin builtin commands fail with an error when no settings provided"
  254. args = ['sqlall', 'admin_scripts']
  255. out, err = self.run_django_admin(args)
  256. self.assertNoOutput(out)
  257. self.assertOutput(err, 'settings are not configured')
  258. def test_builtin_with_settings(self):
  259. "fulldefault: django-admin builtin commands succeed if a settings file is provided"
  260. args = ['sqlall', '--settings=test_project.settings', 'admin_scripts']
  261. out, err = self.run_django_admin(args)
  262. self.assertNoOutput(err)
  263. self.assertOutput(out, 'CREATE TABLE')
  264. def test_builtin_with_environment(self):
  265. "fulldefault: django-admin builtin commands succeed if the environment contains settings"
  266. args = ['sqlall', 'admin_scripts']
  267. out, err = self.run_django_admin(args, 'test_project.settings')
  268. self.assertNoOutput(err)
  269. self.assertOutput(out, 'CREATE TABLE')
  270. def test_builtin_with_bad_settings(self):
  271. "fulldefault: django-admin builtin commands fail if settings file (from argument) doesn't exist"
  272. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  273. out, err = self.run_django_admin(args)
  274. self.assertNoOutput(out)
  275. self.assertOutput(err, "Could not import settings 'bad_settings'")
  276. def test_builtin_with_bad_environment(self):
  277. "fulldefault: django-admin builtin commands fail if settings file (from environment) doesn't exist"
  278. args = ['sqlall', 'admin_scripts']
  279. out, err = self.run_django_admin(args, 'bad_settings')
  280. self.assertNoOutput(out)
  281. self.assertOutput(err, "Could not import settings 'bad_settings'")
  282. def test_custom_command(self):
  283. "fulldefault: django-admin can't execute user commands unless settings are provided"
  284. args = ['noargs_command']
  285. out, err = self.run_django_admin(args)
  286. self.assertNoOutput(out)
  287. self.assertOutput(err, "Unknown command: 'noargs_command'")
  288. def test_custom_command_with_settings(self):
  289. "fulldefault: django-admin can execute user commands if settings are provided as argument"
  290. args = ['noargs_command', '--settings=test_project.settings']
  291. out, err = self.run_django_admin(args)
  292. self.assertNoOutput(err)
  293. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  294. def test_custom_command_with_environment(self):
  295. "fulldefault: django-admin can execute user commands if settings are provided in environment"
  296. args = ['noargs_command']
  297. out, err = self.run_django_admin(args, 'test_project.settings')
  298. self.assertNoOutput(err)
  299. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  300. class DjangoAdminMinimalSettings(AdminScriptTestCase):
  301. """A series of tests for django-admin.py when using a settings.py file that
  302. doesn't contain the test application.
  303. """
  304. def setUp(self):
  305. self.write_settings('settings.py', apps=['django.contrib.auth', 'django.contrib.contenttypes'])
  306. def tearDown(self):
  307. self.remove_settings('settings.py')
  308. def test_builtin_command(self):
  309. "minimal: django-admin builtin commands fail with an error when no settings provided"
  310. args = ['sqlall', 'admin_scripts']
  311. out, err = self.run_django_admin(args)
  312. self.assertNoOutput(out)
  313. self.assertOutput(err, 'settings are not configured')
  314. def test_builtin_with_settings(self):
  315. "minimal: django-admin builtin commands fail if settings are provided as argument"
  316. args = ['sqlall', '--settings=test_project.settings', 'admin_scripts']
  317. out, err = self.run_django_admin(args)
  318. self.assertNoOutput(out)
  319. self.assertOutput(err, 'App with label admin_scripts could not be found')
  320. def test_builtin_with_environment(self):
  321. "minimal: django-admin builtin commands fail if settings are provided in the environment"
  322. args = ['sqlall', 'admin_scripts']
  323. out, err = self.run_django_admin(args, 'test_project.settings')
  324. self.assertNoOutput(out)
  325. self.assertOutput(err, 'App with label admin_scripts could not be found')
  326. def test_builtin_with_bad_settings(self):
  327. "minimal: django-admin builtin commands fail if settings file (from argument) doesn't exist"
  328. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  329. out, err = self.run_django_admin(args)
  330. self.assertNoOutput(out)
  331. self.assertOutput(err, "Could not import settings 'bad_settings'")
  332. def test_builtin_with_bad_environment(self):
  333. "minimal: django-admin builtin commands fail if settings file (from environment) doesn't exist"
  334. args = ['sqlall', 'admin_scripts']
  335. out, err = self.run_django_admin(args, 'bad_settings')
  336. self.assertNoOutput(out)
  337. self.assertOutput(err, "Could not import settings 'bad_settings'")
  338. def test_custom_command(self):
  339. "minimal: django-admin can't execute user commands unless settings are provided"
  340. args = ['noargs_command']
  341. out, err = self.run_django_admin(args)
  342. self.assertNoOutput(out)
  343. self.assertOutput(err, "Unknown command: 'noargs_command'")
  344. def test_custom_command_with_settings(self):
  345. "minimal: django-admin can't execute user commands, even if settings are provided as argument"
  346. args = ['noargs_command', '--settings=test_project.settings']
  347. out, err = self.run_django_admin(args)
  348. self.assertNoOutput(out)
  349. self.assertOutput(err, "Unknown command: 'noargs_command'")
  350. def test_custom_command_with_environment(self):
  351. "minimal: django-admin can't execute user commands, even if settings are provided in environment"
  352. args = ['noargs_command']
  353. out, err = self.run_django_admin(args, 'test_project.settings')
  354. self.assertNoOutput(out)
  355. self.assertOutput(err, "Unknown command: 'noargs_command'")
  356. class DjangoAdminAlternateSettings(AdminScriptTestCase):
  357. """A series of tests for django-admin.py when using a settings file
  358. with a name other than 'settings.py'.
  359. """
  360. def setUp(self):
  361. self.write_settings('alternate_settings.py')
  362. def tearDown(self):
  363. self.remove_settings('alternate_settings.py')
  364. def test_builtin_command(self):
  365. "alternate: django-admin builtin commands fail with an error when no settings provided"
  366. args = ['sqlall', 'admin_scripts']
  367. out, err = self.run_django_admin(args)
  368. self.assertNoOutput(out)
  369. self.assertOutput(err, 'settings are not configured')
  370. def test_builtin_with_settings(self):
  371. "alternate: django-admin builtin commands succeed if settings are provided as argument"
  372. args = ['sqlall', '--settings=test_project.alternate_settings', 'admin_scripts']
  373. out, err = self.run_django_admin(args)
  374. self.assertNoOutput(err)
  375. self.assertOutput(out, 'CREATE TABLE')
  376. def test_builtin_with_environment(self):
  377. "alternate: django-admin builtin commands succeed if settings are provided in the environment"
  378. args = ['sqlall', 'admin_scripts']
  379. out, err = self.run_django_admin(args, 'test_project.alternate_settings')
  380. self.assertNoOutput(err)
  381. self.assertOutput(out, 'CREATE TABLE')
  382. def test_builtin_with_bad_settings(self):
  383. "alternate: django-admin builtin commands fail if settings file (from argument) doesn't exist"
  384. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  385. out, err = self.run_django_admin(args)
  386. self.assertNoOutput(out)
  387. self.assertOutput(err, "Could not import settings 'bad_settings'")
  388. def test_builtin_with_bad_environment(self):
  389. "alternate: django-admin builtin commands fail if settings file (from environment) doesn't exist"
  390. args = ['sqlall', 'admin_scripts']
  391. out, err = self.run_django_admin(args, 'bad_settings')
  392. self.assertNoOutput(out)
  393. self.assertOutput(err, "Could not import settings 'bad_settings'")
  394. def test_custom_command(self):
  395. "alternate: django-admin can't execute user commands unless settings are provided"
  396. args = ['noargs_command']
  397. out, err = self.run_django_admin(args)
  398. self.assertNoOutput(out)
  399. self.assertOutput(err, "Unknown command: 'noargs_command'")
  400. def test_custom_command_with_settings(self):
  401. "alternate: django-admin can execute user commands if settings are provided as argument"
  402. args = ['noargs_command', '--settings=test_project.alternate_settings']
  403. out, err = self.run_django_admin(args)
  404. self.assertNoOutput(err)
  405. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  406. def test_custom_command_with_environment(self):
  407. "alternate: django-admin can execute user commands if settings are provided in environment"
  408. args = ['noargs_command']
  409. out, err = self.run_django_admin(args, 'test_project.alternate_settings')
  410. self.assertNoOutput(err)
  411. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  412. class DjangoAdminMultipleSettings(AdminScriptTestCase):
  413. """A series of tests for django-admin.py when multiple settings files
  414. (including the default 'settings.py') are available. The default settings
  415. file is insufficient for performing the operations described, so the
  416. alternate settings must be used by the running script.
  417. """
  418. def setUp(self):
  419. self.write_settings('settings.py', apps=['django.contrib.auth', 'django.contrib.contenttypes'])
  420. self.write_settings('alternate_settings.py')
  421. def tearDown(self):
  422. self.remove_settings('settings.py')
  423. self.remove_settings('alternate_settings.py')
  424. def test_builtin_command(self):
  425. "alternate: django-admin builtin commands fail with an error when no settings provided"
  426. args = ['sqlall', 'admin_scripts']
  427. out, err = self.run_django_admin(args)
  428. self.assertNoOutput(out)
  429. self.assertOutput(err, 'settings are not configured')
  430. def test_builtin_with_settings(self):
  431. "alternate: django-admin builtin commands succeed if settings are provided as argument"
  432. args = ['sqlall', '--settings=test_project.alternate_settings', 'admin_scripts']
  433. out, err = self.run_django_admin(args)
  434. self.assertNoOutput(err)
  435. self.assertOutput(out, 'CREATE TABLE')
  436. def test_builtin_with_environment(self):
  437. "alternate: django-admin builtin commands succeed if settings are provided in the environment"
  438. args = ['sqlall', 'admin_scripts']
  439. out, err = self.run_django_admin(args, 'test_project.alternate_settings')
  440. self.assertNoOutput(err)
  441. self.assertOutput(out, 'CREATE TABLE')
  442. def test_builtin_with_bad_settings(self):
  443. "alternate: django-admin builtin commands fail if settings file (from argument) doesn't exist"
  444. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  445. out, err = self.run_django_admin(args)
  446. self.assertOutput(err, "Could not import settings 'bad_settings'")
  447. def test_builtin_with_bad_environment(self):
  448. "alternate: django-admin builtin commands fail if settings file (from environment) doesn't exist"
  449. args = ['sqlall', 'admin_scripts']
  450. out, err = self.run_django_admin(args, 'bad_settings')
  451. self.assertNoOutput(out)
  452. self.assertOutput(err, "Could not import settings 'bad_settings'")
  453. def test_custom_command(self):
  454. "alternate: django-admin can't execute user commands unless settings are provided"
  455. args = ['noargs_command']
  456. out, err = self.run_django_admin(args)
  457. self.assertNoOutput(out)
  458. self.assertOutput(err, "Unknown command: 'noargs_command'")
  459. def test_custom_command_with_settings(self):
  460. "alternate: django-admin can execute user commands if settings are provided as argument"
  461. args = ['noargs_command', '--settings=test_project.alternate_settings']
  462. out, err = self.run_django_admin(args)
  463. self.assertNoOutput(err)
  464. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  465. def test_custom_command_with_environment(self):
  466. "alternate: django-admin can execute user commands if settings are provided in environment"
  467. args = ['noargs_command']
  468. out, err = self.run_django_admin(args, 'test_project.alternate_settings')
  469. self.assertNoOutput(err)
  470. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  471. class DjangoAdminSettingsDirectory(AdminScriptTestCase):
  472. """
  473. A series of tests for django-admin.py when the settings file is in a
  474. directory. (see #9751).
  475. """
  476. def setUp(self):
  477. self.write_settings('settings', is_dir=True)
  478. def tearDown(self):
  479. self.remove_settings('settings', is_dir=True)
  480. def test_setup_environ(self):
  481. "directory: startapp creates the correct directory"
  482. args = ['startapp', 'settings_test']
  483. app_path = os.path.join(test_dir, 'settings_test')
  484. out, err = self.run_django_admin(args, 'test_project.settings')
  485. self.addCleanup(shutil.rmtree, app_path)
  486. self.assertNoOutput(err)
  487. self.assertTrue(os.path.exists(app_path))
  488. def test_setup_environ_custom_template(self):
  489. "directory: startapp creates the correct directory with a custom template"
  490. template_path = os.path.join(custom_templates_dir, 'app_template')
  491. args = ['startapp', '--template', template_path, 'custom_settings_test']
  492. app_path = os.path.join(test_dir, 'custom_settings_test')
  493. out, err = self.run_django_admin(args, 'test_project.settings')
  494. self.addCleanup(shutil.rmtree, app_path)
  495. self.assertNoOutput(err)
  496. self.assertTrue(os.path.exists(app_path))
  497. self.assertTrue(os.path.exists(os.path.join(app_path, 'api.py')))
  498. def test_builtin_command(self):
  499. "directory: django-admin builtin commands fail with an error when no settings provided"
  500. args = ['sqlall', 'admin_scripts']
  501. out, err = self.run_django_admin(args)
  502. self.assertNoOutput(out)
  503. self.assertOutput(err, 'settings are not configured')
  504. def test_builtin_with_bad_settings(self):
  505. "directory: django-admin builtin commands fail if settings file (from argument) doesn't exist"
  506. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  507. out, err = self.run_django_admin(args)
  508. self.assertOutput(err, "Could not import settings 'bad_settings'")
  509. def test_builtin_with_bad_environment(self):
  510. "directory: django-admin builtin commands fail if settings file (from environment) doesn't exist"
  511. args = ['sqlall', 'admin_scripts']
  512. out, err = self.run_django_admin(args, 'bad_settings')
  513. self.assertNoOutput(out)
  514. self.assertOutput(err, "Could not import settings 'bad_settings'")
  515. def test_custom_command(self):
  516. "directory: django-admin can't execute user commands unless settings are provided"
  517. args = ['noargs_command']
  518. out, err = self.run_django_admin(args)
  519. self.assertNoOutput(out)
  520. self.assertOutput(err, "Unknown command: 'noargs_command'")
  521. def test_builtin_with_settings(self):
  522. "directory: django-admin builtin commands succeed if settings are provided as argument"
  523. args = ['sqlall', '--settings=test_project.settings', 'admin_scripts']
  524. out, err = self.run_django_admin(args)
  525. self.assertNoOutput(err)
  526. self.assertOutput(out, 'CREATE TABLE')
  527. def test_builtin_with_environment(self):
  528. "directory: django-admin builtin commands succeed if settings are provided in the environment"
  529. args = ['sqlall', 'admin_scripts']
  530. out, err = self.run_django_admin(args, 'test_project.settings')
  531. self.assertNoOutput(err)
  532. self.assertOutput(out, 'CREATE TABLE')
  533. ##########################################################################
  534. # MANAGE.PY TESTS
  535. # This next series of test classes checks the environment processing
  536. # of the generated manage.py script
  537. ##########################################################################
  538. class ManageNoSettings(AdminScriptTestCase):
  539. "A series of tests for manage.py when there is no settings.py file."
  540. def test_builtin_command(self):
  541. "no settings: manage.py builtin commands fail with an error when no settings provided"
  542. args = ['sqlall', 'admin_scripts']
  543. out, err = self.run_manage(args)
  544. self.assertNoOutput(out)
  545. self.assertOutput(err, "Could not import settings 'test_project.settings'")
  546. def test_builtin_with_bad_settings(self):
  547. "no settings: manage.py builtin commands fail if settings file (from argument) doesn't exist"
  548. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  549. out, err = self.run_manage(args)
  550. self.assertNoOutput(out)
  551. self.assertOutput(err, "Could not import settings 'bad_settings'")
  552. def test_builtin_with_bad_environment(self):
  553. "no settings: manage.py builtin commands fail if settings file (from environment) doesn't exist"
  554. args = ['sqlall', 'admin_scripts']
  555. out, err = self.run_manage(args, 'bad_settings')
  556. self.assertNoOutput(out)
  557. self.assertOutput(err, "Could not import settings 'bad_settings'")
  558. class ManageDefaultSettings(AdminScriptTestCase):
  559. """A series of tests for manage.py when using a settings.py file that
  560. contains the test application.
  561. """
  562. def setUp(self):
  563. self.write_settings('settings.py')
  564. def tearDown(self):
  565. self.remove_settings('settings.py')
  566. def test_builtin_command(self):
  567. "default: manage.py builtin commands succeed when default settings are appropriate"
  568. args = ['sqlall', 'admin_scripts']
  569. out, err = self.run_manage(args)
  570. self.assertNoOutput(err)
  571. self.assertOutput(out, 'CREATE TABLE')
  572. def test_builtin_with_settings(self):
  573. "default: manage.py builtin commands succeed if settings are provided as argument"
  574. args = ['sqlall', '--settings=test_project.settings', 'admin_scripts']
  575. out, err = self.run_manage(args)
  576. self.assertNoOutput(err)
  577. self.assertOutput(out, 'CREATE TABLE')
  578. def test_builtin_with_environment(self):
  579. "default: manage.py builtin commands succeed if settings are provided in the environment"
  580. args = ['sqlall', 'admin_scripts']
  581. out, err = self.run_manage(args, 'test_project.settings')
  582. self.assertNoOutput(err)
  583. self.assertOutput(out, 'CREATE TABLE')
  584. def test_builtin_with_bad_settings(self):
  585. "default: manage.py builtin commands succeed if settings file (from argument) doesn't exist"
  586. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  587. out, err = self.run_manage(args)
  588. self.assertNoOutput(out)
  589. self.assertOutput(err, "Could not import settings 'bad_settings'")
  590. def test_builtin_with_bad_environment(self):
  591. "default: manage.py builtin commands fail if settings file (from environment) doesn't exist"
  592. args = ['sqlall', 'admin_scripts']
  593. out, err = self.run_manage(args, 'bad_settings')
  594. self.assertNoOutput(out)
  595. self.assertOutput(err, "Could not import settings 'bad_settings'")
  596. def test_custom_command(self):
  597. "default: manage.py can execute user commands when default settings are appropriate"
  598. args = ['noargs_command']
  599. out, err = self.run_manage(args)
  600. self.assertNoOutput(err)
  601. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  602. def test_custom_command_with_settings(self):
  603. "default: manage.py can execute user commands when settings are provided as argument"
  604. args = ['noargs_command', '--settings=test_project.settings']
  605. out, err = self.run_manage(args)
  606. self.assertNoOutput(err)
  607. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  608. def test_custom_command_with_environment(self):
  609. "default: manage.py can execute user commands when settings are provided in environment"
  610. args = ['noargs_command']
  611. out, err = self.run_manage(args, 'test_project.settings')
  612. self.assertNoOutput(err)
  613. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  614. class ManageFullPathDefaultSettings(AdminScriptTestCase):
  615. """A series of tests for manage.py when using a settings.py file that
  616. contains the test application specified using a full path.
  617. """
  618. def setUp(self):
  619. self.write_settings('settings.py', ['django.contrib.auth', 'django.contrib.contenttypes', 'admin_scripts'])
  620. def tearDown(self):
  621. self.remove_settings('settings.py')
  622. def test_builtin_command(self):
  623. "fulldefault: manage.py builtin commands succeed when default settings are appropriate"
  624. args = ['sqlall', 'admin_scripts']
  625. out, err = self.run_manage(args)
  626. self.assertNoOutput(err)
  627. self.assertOutput(out, 'CREATE TABLE')
  628. def test_builtin_with_settings(self):
  629. "fulldefault: manage.py builtin commands succeed if settings are provided as argument"
  630. args = ['sqlall', '--settings=test_project.settings', 'admin_scripts']
  631. out, err = self.run_manage(args)
  632. self.assertNoOutput(err)
  633. self.assertOutput(out, 'CREATE TABLE')
  634. def test_builtin_with_environment(self):
  635. "fulldefault: manage.py builtin commands succeed if settings are provided in the environment"
  636. args = ['sqlall', 'admin_scripts']
  637. out, err = self.run_manage(args, 'test_project.settings')
  638. self.assertNoOutput(err)
  639. self.assertOutput(out, 'CREATE TABLE')
  640. def test_builtin_with_bad_settings(self):
  641. "fulldefault: manage.py builtin commands succeed if settings file (from argument) doesn't exist"
  642. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  643. out, err = self.run_manage(args)
  644. self.assertNoOutput(out)
  645. self.assertOutput(err, "Could not import settings 'bad_settings'")
  646. def test_builtin_with_bad_environment(self):
  647. "fulldefault: manage.py builtin commands fail if settings file (from environment) doesn't exist"
  648. args = ['sqlall', 'admin_scripts']
  649. out, err = self.run_manage(args, 'bad_settings')
  650. self.assertNoOutput(out)
  651. self.assertOutput(err, "Could not import settings 'bad_settings'")
  652. def test_custom_command(self):
  653. "fulldefault: manage.py can execute user commands when default settings are appropriate"
  654. args = ['noargs_command']
  655. out, err = self.run_manage(args)
  656. self.assertNoOutput(err)
  657. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  658. def test_custom_command_with_settings(self):
  659. "fulldefault: manage.py can execute user commands when settings are provided as argument"
  660. args = ['noargs_command', '--settings=test_project.settings']
  661. out, err = self.run_manage(args)
  662. self.assertNoOutput(err)
  663. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  664. def test_custom_command_with_environment(self):
  665. "fulldefault: manage.py can execute user commands when settings are provided in environment"
  666. args = ['noargs_command']
  667. out, err = self.run_manage(args, 'test_project.settings')
  668. self.assertNoOutput(err)
  669. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  670. class ManageMinimalSettings(AdminScriptTestCase):
  671. """A series of tests for manage.py when using a settings.py file that
  672. doesn't contain the test application.
  673. """
  674. def setUp(self):
  675. self.write_settings('settings.py', apps=['django.contrib.auth', 'django.contrib.contenttypes'])
  676. def tearDown(self):
  677. self.remove_settings('settings.py')
  678. def test_builtin_command(self):
  679. "minimal: manage.py builtin commands fail with an error when no settings provided"
  680. args = ['sqlall', 'admin_scripts']
  681. out, err = self.run_manage(args)
  682. self.assertNoOutput(out)
  683. self.assertOutput(err, 'App with label admin_scripts could not be found')
  684. def test_builtin_with_settings(self):
  685. "minimal: manage.py builtin commands fail if settings are provided as argument"
  686. args = ['sqlall', '--settings=test_project.settings', 'admin_scripts']
  687. out, err = self.run_manage(args)
  688. self.assertNoOutput(out)
  689. self.assertOutput(err, 'App with label admin_scripts could not be found')
  690. def test_builtin_with_environment(self):
  691. "minimal: manage.py builtin commands fail if settings are provided in the environment"
  692. args = ['sqlall', 'admin_scripts']
  693. out, err = self.run_manage(args, 'test_project.settings')
  694. self.assertNoOutput(out)
  695. self.assertOutput(err, 'App with label admin_scripts could not be found')
  696. def test_builtin_with_bad_settings(self):
  697. "minimal: manage.py builtin commands fail if settings file (from argument) doesn't exist"
  698. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  699. out, err = self.run_manage(args)
  700. self.assertNoOutput(out)
  701. self.assertOutput(err, "Could not import settings 'bad_settings'")
  702. def test_builtin_with_bad_environment(self):
  703. "minimal: manage.py builtin commands fail if settings file (from environment) doesn't exist"
  704. args = ['sqlall', 'admin_scripts']
  705. out, err = self.run_manage(args, 'bad_settings')
  706. self.assertNoOutput(out)
  707. self.assertOutput(err, "Could not import settings 'bad_settings'")
  708. def test_custom_command(self):
  709. "minimal: manage.py can't execute user commands without appropriate settings"
  710. args = ['noargs_command']
  711. out, err = self.run_manage(args)
  712. self.assertNoOutput(out)
  713. self.assertOutput(err, "Unknown command: 'noargs_command'")
  714. def test_custom_command_with_settings(self):
  715. "minimal: manage.py can't execute user commands, even if settings are provided as argument"
  716. args = ['noargs_command', '--settings=test_project.settings']
  717. out, err = self.run_manage(args)
  718. self.assertNoOutput(out)
  719. self.assertOutput(err, "Unknown command: 'noargs_command'")
  720. def test_custom_command_with_environment(self):
  721. "minimal: manage.py can't execute user commands, even if settings are provided in environment"
  722. args = ['noargs_command']
  723. out, err = self.run_manage(args, 'test_project.settings')
  724. self.assertNoOutput(out)
  725. self.assertOutput(err, "Unknown command: 'noargs_command'")
  726. class ManageAlternateSettings(AdminScriptTestCase):
  727. """A series of tests for manage.py when using a settings file
  728. with a name other than 'settings.py'.
  729. """
  730. def setUp(self):
  731. self.write_settings('alternate_settings.py')
  732. def tearDown(self):
  733. self.remove_settings('alternate_settings.py')
  734. def test_builtin_command(self):
  735. "alternate: manage.py builtin commands fail with an error when no default settings provided"
  736. args = ['sqlall', 'admin_scripts']
  737. out, err = self.run_manage(args)
  738. self.assertNoOutput(out)
  739. self.assertOutput(err, "Could not import settings 'test_project.settings'")
  740. def test_builtin_with_settings(self):
  741. "alternate: manage.py builtin commands work with settings provided as argument"
  742. args = ['sqlall', '--settings=alternate_settings', 'admin_scripts']
  743. out, err = self.run_manage(args)
  744. expected = ('create table %s'
  745. % connection.ops.quote_name('admin_scripts_article'))
  746. self.assertTrue(expected.lower() in out.lower())
  747. self.assertNoOutput(err)
  748. def test_builtin_with_environment(self):
  749. "alternate: manage.py builtin commands work if settings are provided in the environment"
  750. args = ['sqlall', 'admin_scripts']
  751. out, err = self.run_manage(args, 'alternate_settings')
  752. expected = ('create table %s'
  753. % connection.ops.quote_name('admin_scripts_article'))
  754. self.assertTrue(expected.lower() in out.lower())
  755. self.assertNoOutput(err)
  756. def test_builtin_with_bad_settings(self):
  757. "alternate: manage.py builtin commands fail if settings file (from argument) doesn't exist"
  758. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  759. out, err = self.run_manage(args)
  760. self.assertNoOutput(out)
  761. self.assertOutput(err, "Could not import settings 'bad_settings'")
  762. def test_builtin_with_bad_environment(self):
  763. "alternate: manage.py builtin commands fail if settings file (from environment) doesn't exist"
  764. args = ['sqlall', 'admin_scripts']
  765. out, err = self.run_manage(args, 'bad_settings')
  766. self.assertNoOutput(out)
  767. self.assertOutput(err, "Could not import settings 'bad_settings'")
  768. def test_custom_command(self):
  769. "alternate: manage.py can't execute user commands without settings"
  770. args = ['noargs_command']
  771. out, err = self.run_manage(args)
  772. self.assertNoOutput(out)
  773. self.assertOutput(err, "Could not import settings 'test_project.settings'")
  774. def test_custom_command_with_settings(self):
  775. "alternate: manage.py can execute user commands if settings are provided as argument"
  776. args = ['noargs_command', '--settings=alternate_settings']
  777. out, err = self.run_manage(args)
  778. self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
  779. self.assertNoOutput(err)
  780. def test_custom_command_with_environment(self):
  781. "alternate: manage.py can execute user commands if settings are provided in environment"
  782. args = ['noargs_command']
  783. out, err = self.run_manage(args, 'alternate_settings')
  784. self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  785. self.assertNoOutput(err)
  786. class ManageMultipleSettings(AdminScriptTestCase):
  787. """A series of tests for manage.py when multiple settings files
  788. (including the default 'settings.py') are available. The default settings
  789. file is insufficient for performing the operations described, so the
  790. alternate settings must be used by the running script.
  791. """
  792. def setUp(self):
  793. self.write_settings('settings.py', apps=['django.contrib.auth', 'django.contrib.contenttypes'])
  794. self.write_settings('alternate_settings.py')
  795. def tearDown(self):
  796. self.remove_settings('settings.py')
  797. self.remove_settings('alternate_settings.py')
  798. def test_builtin_command(self):
  799. "multiple: manage.py builtin commands fail with an error when no settings provided"
  800. args = ['sqlall', 'admin_scripts']
  801. out, err = self.run_manage(args)
  802. self.assertNoOutput(out)
  803. self.assertOutput(err, 'App with label admin_scripts could not be found.')
  804. def test_builtin_with_settings(self):
  805. "multiple: manage.py builtin commands succeed if settings are provided as argument"
  806. args = ['sqlall', '--settings=alternate_settings', 'admin_scripts']
  807. out, err = self.run_manage(args)
  808. self.assertNoOutput(err)
  809. self.assertOutput(out, 'CREATE TABLE')
  810. def test_builtin_with_environment(self):
  811. "multiple: manage.py can execute builtin commands if settings are provided in the environment"
  812. args = ['sqlall', 'admin_scripts']
  813. out, err = self.run_manage(args, 'alternate_settings')
  814. self.assertNoOutput(err)
  815. self.assertOutput(out, 'CREATE TABLE')
  816. def test_builtin_with_bad_settings(self):
  817. "multiple: manage.py builtin commands fail if settings file (from argument) doesn't exist"
  818. args = ['sqlall', '--settings=bad_settings', 'admin_scripts']
  819. out, err = self.run_manage(args)
  820. self.assertNoOutput(out)
  821. self.assertOutput(err, "Could not import settings 'bad_settings'")
  822. def test_builtin_with_bad_environment(self):
  823. "multiple: manage.py builtin commands fail if settings file (from environment) doesn't exist"
  824. args = ['sqlall', 'admin_scripts']
  825. out, err = self.run_manage(args, 'bad_settings')
  826. self.assertNoOutput(out)
  827. self.assertOutput(err, "Could not import settings 'bad_settings'")
  828. def test_custom_command(self):
  829. "multiple: manage.py can't execute user commands using default settings"
  830. args = ['noargs_command']
  831. out, err = self.run_manage(args)
  832. self.assertNoOutput(out)
  833. self.assertOutput(err, "Unknown command: 'noargs_command'")
  834. def test_custom_command_with_settings(self):
  835. "multiple: manage.py can execute user commands if settings are provided as argument"
  836. args = ['noargs_command', '--settings=alternate_settings']
  837. out, err = self.run_manage(args)
  838. self.assertNoOutput(err)
  839. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  840. def test_custom_command_with_environment(self):
  841. "multiple: manage.py can execute user commands if settings are provided in environment"
  842. args = ['noargs_command']
  843. out, err = self.run_manage(args, 'alternate_settings')
  844. self.assertNoOutput(err)
  845. self.assertOutput(out, "EXECUTE:NoArgsCommand")
  846. class ManageSettingsWithImportError(AdminScriptTestCase):
  847. """Tests for manage.py when using the default settings.py file
  848. with an import error. Ticket #14130.
  849. """
  850. def tearDown(self):
  851. self.remove_settings('settings.py')
  852. def write_settings_with_import_error(self, filename, apps=None, is_dir=False, sdict=None):
  853. if is_dir:
  854. settings_dir = os.path.join(test_dir, filename)
  855. os.mkdir(settings_dir)
  856. settings_file_path = os.path.join(settings_dir, '__init__.py')
  857. else:
  858. settings_file_path = os.path.join(test_dir, filename)
  859. with open(settings_file_path, 'w') as settings_file:
  860. settings_file.write('# Settings file automatically generated by admin_scripts test case\n')
  861. settings_file.write('# The next line will cause an import error:\nimport foo42bar\n')
  862. def test_builtin_command(self):
  863. """
  864. import error: manage.py builtin commands shows useful diagnostic info
  865. when settings with import errors is provided
  866. """
  867. self.write_settings_with_import_error('settings.py')
  868. args = ['sqlall', 'admin_scripts']
  869. out, err = self.run_manage(args)
  870. self.assertNoOutput(out)
  871. self.assertOutput(err, "No module named")
  872. self.assertOutput(err, "foo42bar")
  873. def test_builtin_command_with_attribute_error(self):
  874. """
  875. manage.py builtin commands does not swallow attribute errors from bad settings (#18845)
  876. """
  877. self.write_settings('settings.py', sdict={'BAD_VAR': 'INSTALLED_APPS.crash'})
  878. args = ['collectstatic', 'admin_scripts']
  879. out, err = self.run_manage(args)
  880. self.assertNoOutput(out)
  881. self.assertOutput(err, "AttributeError: 'list' object has no attribute 'crash'")
  882. class ManageValidate(AdminScriptTestCase):
  883. def tearDown(self):
  884. self.remove_settings('settings.py')
  885. def test_nonexistent_app(self):
  886. "manage.py validate reports an error on a non-existent app in INSTALLED_APPS"
  887. self.write_settings('settings.py', apps=['admin_scriptz.broken_app'], sdict={'USE_I18N': False})
  888. args = ['validate']
  889. out, err = self.run_manage(args)
  890. self.assertNoOutput(out)
  891. self.assertOutput(err, 'No module named')
  892. self.assertOutput(err, 'admin_scriptz')
  893. def test_broken_app(self):
  894. "manage.py validate reports an ImportError if an app's models.py raises one on import"
  895. self.write_settings('settings.py', apps=['admin_scripts.broken_app'])
  896. args = ['validate']
  897. out, err = self.run_manage(args)
  898. self.assertNoOutput(out)
  899. self.assertOutput(err, 'ImportError')
  900. def test_complex_app(self):
  901. "manage.py validate does not raise an ImportError validating a complex app with nested calls to load_app"
  902. self.write_settings('settings.py',
  903. apps=['admin_scripts.complex_app', 'admin_scripts.simple_app'],
  904. sdict={'DEBUG': True})
  905. args = ['validate']
  906. out, err = self.run_manage(args)
  907. self.assertNoOutput(err)
  908. self.assertOutput(out, '0 errors found')
  909. def test_app_with_import(self):
  910. "manage.py validate does not raise errors when an app imports a base class that itself has an abstract base"
  911. self.write_settings('settings.py',
  912. apps=['admin_scripts.app_with_import',
  913. 'django.contrib.comments',
  914. 'django.contrib.auth',
  915. 'django.contrib.contenttypes',
  916. 'django.contrib.sites'],
  917. sdict={'DEBUG': True})
  918. args = ['validate']
  919. out, err = self.run_manage(args)
  920. self.assertNoOutput(err)
  921. self.assertOutput(out, '0 errors found')
  922. class CustomTestRunner(DiscoverRunner):
  923. def __init__(self, *args, **kwargs):
  924. assert 'liveserver' not in kwargs
  925. super(CustomTestRunner, self).__init__(*args, **kwargs)
  926. def run_tests(self, test_labels, extra_tests=None, **kwargs):
  927. pass
  928. class ManageTestCommand(AdminScriptTestCase):
  929. def setUp(self):
  930. from django.core.management.commands.test import Command as TestCommand
  931. self.cmd = TestCommand()
  932. def test_liveserver(self):
  933. """
  934. Ensure that the --liveserver option sets the environment variable
  935. correctly.
  936. Refs #2879.
  937. """
  938. # Backup original state
  939. address_predefined = 'DJANGO_LIVE_TEST_SERVER_ADDRESS' in os.environ
  940. old_address = os.environ.get('DJANGO_LIVE_TEST_SERVER_ADDRESS')
  941. self.cmd.handle(verbosity=0, testrunner='admin_scripts.tests.CustomTestRunner')
  942. # Original state hasn't changed
  943. self.assertEqual('DJANGO_LIVE_TEST_SERVER_ADDRESS' in os.environ, address_predefined)
  944. self.assertEqual(os.environ.get('DJANGO_LIVE_TEST_SERVER_ADDRESS'), old_address)
  945. self.cmd.handle(verbosity=0, testrunner='admin_scripts.tests.CustomTestRunner',
  946. liveserver='blah')
  947. # Variable was correctly set
  948. self.assertEqual(os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'], 'blah')
  949. # Restore original state
  950. if address_predefined:
  951. os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS'] = old_address
  952. else:
  953. del os.environ['DJANGO_LIVE_TEST_SERVER_ADDRESS']
  954. class ManageRunserver(AdminScriptTestCase):
  955. def setUp(self):
  956. from django.core.management.commands.runserver import Command
  957. def monkey_run(*args, **options):
  958. return
  959. self.cmd = Command()
  960. self.cmd.run = monkey_run
  961. def assertServerSettings(self, addr, port, ipv6=None, raw_ipv6=False):
  962. self.assertEqual(self.cmd.addr, addr)
  963. self.assertEqual(self.cmd.port, port)
  964. self.assertEqual(self.cmd.use_ipv6, ipv6)
  965. self.assertEqual(self.cmd._raw_ipv6, raw_ipv6)
  966. def test_runserver_addrport(self):
  967. self.cmd.handle()
  968. self.assertServerSettings('127.0.0.1', '8000')
  969. self.cmd.handle(addrport="1.2.3.4:8000")
  970. self.assertServerSettings('1.2.3.4', '8000')
  971. self.cmd.handle(addrport="7000")
  972. self.assertServerSettings('127.0.0.1', '7000')
  973. @unittest.skipUnless(socket.has_ipv6, "platform doesn't support IPv6")
  974. def test_runner_addrport_ipv6(self):
  975. self.cmd.handle(addrport="", use_ipv6=True)
  976. self.assertServerSettings('::1', '8000', ipv6=True, raw_ipv6=True)
  977. self.cmd.handle(addrport="7000", use_ipv6=True)
  978. self.assertServerSettings('::1', '7000', ipv6=True, raw_ipv6=True)
  979. self.cmd.handle(addrport="[2001:0db8:1234:5678::9]:7000")
  980. self.assertServerSettings('2001:0db8:1234:5678::9', '7000', ipv6=True, raw_ipv6=True)
  981. def test_runner_hostname(self):
  982. self.cmd.handle(addrport="localhost:8000")
  983. self.assertServerSettings('localhost', '8000')
  984. self.cmd.handle(addrport="test.domain.local:7000")
  985. self.assertServerSettings('test.domain.local', '7000')
  986. @unittest.skipUnless(socket.has_ipv6, "platform doesn't support IPv6")
  987. def test_runner_hostname_ipv6(self):
  988. self.cmd.handle(addrport="test.domain.local:7000", use_ipv6=True)
  989. self.assertServerSettings('test.domain.local', '7000', ipv6=True)
  990. def test_runner_ambiguous(self):
  991. # Only 4 characters, all of which could be in an ipv6 address
  992. self.cmd.handle(addrport="beef:7654")
  993. self.assertServerSettings('beef', '7654')
  994. # Uses only characters that could be in an ipv6 address
  995. self.cmd.handle(addrport="deadbeef:7654")
  996. self.assertServerSettings('deadbeef', '7654')
  997. ##########################################################################
  998. # COMMAND PROCESSING TESTS
  999. # Check that user-space commands are correctly handled - in particular,
  1000. # that arguments to the commands are correctly parsed and processed.
  1001. ##########################################################################
  1002. class CommandTypes(AdminScriptTestCase):
  1003. "Tests for the various types of base command types that can be defined."
  1004. def setUp(self):
  1005. self.write_settings('settings.py')
  1006. def tearDown(self):
  1007. self.remove_settings('settings.py')
  1008. def test_version(self):
  1009. "version is handled as a special case"
  1010. args = ['version']
  1011. out, err = self.run_manage(args)
  1012. self.assertNoOutput(err)
  1013. self.assertOutput(out, get_version())
  1014. def test_version_alternative(self):
  1015. "--version is equivalent to version"
  1016. args1, args2 = ['version'], ['--version']
  1017. self.assertEqual(self.run_manage(args1), self.run_manage(args2))
  1018. def test_help(self):
  1019. "help is handled as a special case"
  1020. args = ['help']
  1021. out, err = self.run_manage(args)
  1022. self.assertOutput(out, "Usage: manage.py subcommand [options] [args]")
  1023. self.assertOutput(out, "Type 'manage.py help <subcommand>' for help on a specific subcommand.")
  1024. self.assertOutput(out, '[django]')
  1025. self.assertOutput(out, 'startapp')
  1026. self.assertOutput(out, 'startproject')
  1027. def test_help_commands(self):
  1028. "help --commands shows the list of all available commands"
  1029. args = ['help', '--commands']
  1030. out, err = self.run_manage(args)
  1031. self.assertNotInOutput(out, 'Usage:')
  1032. self.assertNotInOutput(out, 'Options:')
  1033. self.assertNotInOutput(out, '[django]')
  1034. self.assertOutput(out, 'startapp')
  1035. self.assertOutput(out, 'startproject')
  1036. self.assertNotInOutput(out, '\n\n')
  1037. def test_help_alternative(self):
  1038. "--help is equivalent to help"
  1039. args1, args2 = ['help'], ['--help']
  1040. self.assertEqual(self.run_manage(args1), self.run_manage(args2))
  1041. def test_help_short_altert(self):
  1042. "-h is handled as a short form of --help"
  1043. args1, args2 = ['--help'], ['-h']
  1044. self.assertEqual(self.run_manage(args1), self.run_manage(args2))
  1045. def test_specific_help(self):
  1046. "--help can be used on a specific command"
  1047. args = ['sqlall', '--help']
  1048. out, err = self.run_manage(args)
  1049. self.assertNoOutput(err)
  1050. self.assertOutput(out, "Prints the CREATE TABLE, custom SQL and CREATE INDEX SQL statements for the given model module name(s).")
  1051. def test_base_command(self):
  1052. "User BaseCommands can execute when a label is provided"
  1053. args = ['base_command', 'testlabel']
  1054. out, err = self.run_manage(args)
  1055. self.assertNoOutput(err)
  1056. self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1057. def test_base_command_no_label(self):
  1058. "User BaseCommands can execute when no labels are provided"
  1059. args = ['base_command']
  1060. out, err = self.run_manage(args)
  1061. self.assertNoOutput(err)
  1062. self.assertOutput(out, "EXECUTE:BaseCommand labels=(), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1063. def test_base_command_multiple_label(self):
  1064. "User BaseCommands can execute when no labels are provided"
  1065. args = ['base_command', 'testlabel', 'anotherlabel']
  1066. out, err = self.run_manage(args)
  1067. self.assertNoOutput(err)
  1068. self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel', 'anotherlabel'), options=[('option_a', '1'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1069. def test_base_command_with_option(self):
  1070. "User BaseCommands can execute with options when a label is provided"
  1071. args = ['base_command', 'testlabel', '--option_a=x']
  1072. out, err = self.run_manage(args)
  1073. self.assertNoOutput(err)
  1074. self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1075. def test_base_command_with_options(self):
  1076. "User BaseCommands can execute with multiple options when a label is provided"
  1077. args = ['base_command', 'testlabel', '-a', 'x', '--option_b=y']
  1078. out, err = self.run_manage(args)
  1079. self.assertNoOutput(err)
  1080. self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1081. def test_base_run_from_argv(self):
  1082. """
  1083. Test run_from_argv properly terminates even with custom execute() (#19665)
  1084. Also test proper traceback display.
  1085. """
  1086. command = BaseCommand()
  1087. def raise_command_error(*args, **kwargs):
  1088. raise CommandError("Custom error")
  1089. old_stderr = sys.stderr
  1090. sys.stderr = err = StringIO()
  1091. try:
  1092. command.execute = lambda args: args # This will trigger TypeError
  1093. with self.assertRaises(SystemExit):
  1094. command.run_from_argv(['', ''])
  1095. err_message = err.getvalue()
  1096. # Exceptions other than CommandError automatically output the traceback
  1097. self.assertIn("Traceback", err_message)
  1098. self.assertIn("TypeError", err_message)
  1099. command.execute = raise_command_error
  1100. err.truncate(0)
  1101. with self.assertRaises(SystemExit):
  1102. command.run_from_argv(['', ''])
  1103. err_message = err.getvalue()
  1104. self.assertNotIn("Traceback", err_message)
  1105. self.assertIn("CommandError", err_message)
  1106. err.truncate(0)
  1107. with self.assertRaises(SystemExit):
  1108. command.run_from_argv(['', '', '--traceback'])
  1109. err_message = err.getvalue()
  1110. self.assertIn("Traceback (most recent call last)", err_message)
  1111. self.assertIn("CommandError", err_message)
  1112. finally:
  1113. sys.stderr = old_stderr
  1114. def test_noargs(self):
  1115. "NoArg Commands can be executed"
  1116. args = ['noargs_command']
  1117. out, err = self.run_manage(args)
  1118. self.assertNoOutput(err)
  1119. self.assertOutput(out, "EXECUTE:NoArgsCommand options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1120. def test_noargs_with_args(self):
  1121. "NoArg Commands raise an error if an argument is provided"
  1122. args = ['noargs_command', 'argument']
  1123. out, err = self.run_manage(args)
  1124. self.assertOutput(err, "Error: Command doesn't accept any arguments")
  1125. def test_app_command(self):
  1126. "User AppCommands can execute when a single app name is provided"
  1127. args = ['app_command', 'auth']
  1128. out, err = self.run_manage(args)
  1129. self.assertNoOutput(err)
  1130. self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
  1131. self.assertOutput(out, os.sep.join(['django', 'contrib', 'auth', 'models.py']))
  1132. self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1133. def test_app_command_no_apps(self):
  1134. "User AppCommands raise an error when no app name is provided"
  1135. args = ['app_command']
  1136. out, err = self.run_manage(args)
  1137. self.assertOutput(err, 'Error: Enter at least one appname.')
  1138. def test_app_command_multiple_apps(self):
  1139. "User AppCommands raise an error when multiple app names are provided"
  1140. args = ['app_command', 'auth', 'contenttypes']
  1141. out, err = self.run_manage(args)
  1142. self.assertNoOutput(err)
  1143. self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.auth.models'")
  1144. self.assertOutput(out, os.sep.join(['django', 'contrib', 'auth', 'models.py']))
  1145. self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1146. self.assertOutput(out, "EXECUTE:AppCommand app=<module 'django.contrib.contenttypes.models'")
  1147. self.assertOutput(out, os.sep.join(['django', 'contrib', 'contenttypes', 'models.py']))
  1148. self.assertOutput(out, "'>, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1149. def test_app_command_invalid_appname(self):
  1150. "User AppCommands can execute when a single app name is provided"
  1151. args = ['app_command', 'NOT_AN_APP']
  1152. out, err = self.run_manage(args)
  1153. self.assertOutput(err, "App with label NOT_AN_APP could not be found")
  1154. def test_app_command_some_invalid_appnames(self):
  1155. "User AppCommands can execute when some of the provided app names are invalid"
  1156. args = ['app_command', 'auth', 'NOT_AN_APP']
  1157. out, err = self.run_manage(args)
  1158. self.assertOutput(err, "App with label NOT_AN_APP could not be found")
  1159. def test_label_command(self):
  1160. "User LabelCommands can execute when a label is provided"
  1161. args = ['label_command', 'testlabel']
  1162. out, err = self.run_manage(args)
  1163. self.assertNoOutput(err)
  1164. self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1165. def test_label_command_no_label(self):
  1166. "User LabelCommands raise an error if no label is provided"
  1167. args = ['label_command']
  1168. out, err = self.run_manage(args)
  1169. self.assertOutput(err, 'Enter at least one label')
  1170. def test_label_command_multiple_label(self):
  1171. "User LabelCommands are executed multiple times if multiple labels are provided"
  1172. args = ['label_command', 'testlabel', 'anotherlabel']
  1173. out, err = self.run_manage(args)
  1174. self.assertNoOutput(err)
  1175. self.assertOutput(out, "EXECUTE:LabelCommand label=testlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1176. self.assertOutput(out, "EXECUTE:LabelCommand label=anotherlabel, options=[('pythonpath', None), ('settings', None), ('traceback', None), ('verbosity', '1')]")
  1177. class ArgumentOrder(AdminScriptTestCase):
  1178. """Tests for 2-stage argument parsing scheme.
  1179. django-admin command arguments are parsed in 2 parts; the core arguments
  1180. (--settings, --traceback and --pythonpath) are parsed using a Lax parser.
  1181. This Lax parser ignores any unknown options. Then the full settings are
  1182. passed to the command parser, which extracts commands of interest to the
  1183. individual command.
  1184. """
  1185. def setUp(self):
  1186. self.write_settings('settings.py', apps=['django.contrib.auth', 'django.contrib.contenttypes'])
  1187. self.write_settings('alternate_settings.py')
  1188. def tearDown(self):
  1189. self.remove_settings('settings.py')
  1190. self.remove_settings('alternate_settings.py')
  1191. def test_setting_then_option(self):
  1192. "Options passed after settings are correctly handled"
  1193. args = ['base_command', 'testlabel', '--settings=alternate_settings', '--option_a=x']
  1194. out, err = self.run_manage(args)
  1195. self.assertNoOutput(err)
  1196. self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
  1197. def test_setting_then_short_option(self):
  1198. "Short options passed after settings are correctly handled"
  1199. args = ['base_command', 'testlabel', '--settings=alternate_settings', '--option_a=x']
  1200. out, err = self.run_manage(args)
  1201. self.assertNoOutput(err)
  1202. self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
  1203. def test_option_then_setting(self):
  1204. "Options passed before settings are correctly handled"
  1205. args = ['base_command', 'testlabel', '--option_a=x', '--settings=alternate_settings']
  1206. out, err = self.run_manage(args)
  1207. self.assertNoOutput(err)
  1208. self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
  1209. def test_short_option_then_setting(self):
  1210. "Short options passed before settings are correctly handled"
  1211. args = ['base_command', 'testlabel', '-a', 'x', '--settings=alternate_settings']
  1212. out, err = self.run_manage(args)
  1213. self.assertNoOutput(err)
  1214. self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', '2'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
  1215. def test_option_then_setting_then_option(self):
  1216. "Options are correctly handled when they are passed before and after a setting"
  1217. args = ['base_command', 'testlabel', '--option_a=x', '--settings=alternate_settings', '--option_b=y']
  1218. out, err = self.run_manage(args)
  1219. self.assertNoOutput(err)
  1220. self.assertOutput(out, "EXECUTE:BaseCommand labels=('testlabel',), options=[('option_a', 'x'), ('option_b', 'y'), ('option_c', '3'), ('pythonpath', None), ('settings', 'alternate_settings'), ('traceback', None), ('verbosity', '1')]")
  1221. class StartProject(LiveServerTestCase, AdminScriptTestCase):
  1222. def test_wrong_args(self):
  1223. "Make sure passing the wrong kinds of arguments raises a CommandError"
  1224. out, err = self.run_django_admin(['startproject'])
  1225. self.assertNoOutput(out)
  1226. self.assertOutput(err, "you must provide a project name")
  1227. def test_simple_project(self):
  1228. "Make sure the startproject management command creates a project"
  1229. args = ['startproject', 'testproject']
  1230. testproject_dir = os.path.join(test_dir, 'testproject')
  1231. self.addCleanup(shutil.rmtree, testproject_dir, True)
  1232. out, err = self.run_django_admin(args)
  1233. self.assertNoOutput(err)
  1234. self.assertTrue(os.path.isdir(testproject_dir))
  1235. # running again..
  1236. out, err = self.run_django_admin(args)
  1237. self.assertNoOutput(out)
  1238. self.assertOutput(err, "already exists")
  1239. def test_invalid_project_name(self):
  1240. "Make sure the startproject management command validates a project name"
  1241. for bad_name in ('7testproject', '../testproject'):
  1242. args = ['startproject', bad_name]
  1243. testproject_dir = os.path.join(test_dir, bad_name)
  1244. self.addCleanup(shutil.rmtree, testproject_dir, True)
  1245. out, err = self.run_django_admin(args)
  1246. self.assertOutput(err, "Error: '%s' is not a valid project name. "
  1247. "Please make sure the name begins with a letter or underscore." % bad_name)
  1248. self.assertFalse(os.path.exists(testproject_dir))
  1249. def test_simple_project_different_directory(self):
  1250. "Make sure the startproject management command creates a project in a specific directory"
  1251. args = ['startproject', 'testproject', 'othertestproject']
  1252. testproject_dir = os.path.join(test_dir, 'othertestproject')
  1253. os.mkdir(testproject_dir)
  1254. self.addCleanup(shutil.rmtree, testproject_dir)
  1255. out, err = self.run_django_admin(args)
  1256. self.assertNoOutput(err)
  1257. self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'manage.py')))
  1258. # running again..
  1259. out, err = self.run_django_admin(args)
  1260. self.assertNoOutput(out)
  1261. self.assertOutput(err, "already exists")
  1262. def test_custom_project_template(self):
  1263. "Make sure the startproject management command is able to use a different project template"
  1264. template_path = os.path.join(custom_templates_dir, 'project_template')
  1265. args = ['startproject', '--template', template_path, 'customtestproject']
  1266. testproject_dir = os.path.join(test_dir, 'customtestproject')
  1267. self.addCleanup(shutil.rmtree, testproject_dir, True)
  1268. out, err = self.run_django_admin(args)
  1269. self.assertNoOutput(err)
  1270. self.assertTrue(os.path.isdir(testproject_dir))
  1271. self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'additional_dir')))
  1272. def test_template_dir_with_trailing_slash(self):
  1273. "Ticket 17475: Template dir passed has a trailing path separator"
  1274. template_path = os.path.join(custom_templates_dir, 'project_template' + os.sep)
  1275. args = ['startproject', '--template', template_path, 'customtestproject']
  1276. testproject_dir = os.path.join(test_dir, 'customtestproject')
  1277. self.addCleanup(shutil.rmtree, testproject_dir, True)
  1278. out, err = self.run_django_admin(args)
  1279. self.assertNoOutput(err)
  1280. self.assertTrue(os.path.isdir(testproject_dir))
  1281. self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'additional_dir')))
  1282. def test_custom_project_template_from_tarball_by_path(self):
  1283. "Make sure the startproject management command is able to use a different project template from a tarball"
  1284. template_path = os.path.join(custom_templates_dir, 'project_template.tgz')
  1285. args = ['startproject', '--template', template_path, 'tarballtestproject']
  1286. testproject_dir = os.path.join(test_dir, 'tarballtestproject')
  1287. self.addCleanup(shutil.rmtree, testproject_dir, True)
  1288. out, err = self.run_django_admin(args)
  1289. self.assertNoOutput(err)
  1290. self.assertTrue(os.path.isdir(testproject_dir))
  1291. self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'run.py')))
  1292. def test_custom_project_template_from_tarball_to_alternative_location(self):
  1293. "Startproject can use a project template from a tarball and create it in a specified location"
  1294. template_path = os.path.join(custom_templates_dir, 'project_template.tgz')
  1295. args = ['startproject', '--template', template_path, 'tarballtestproject', 'altlocation']
  1296. testproject_dir = os.path.join(test_dir, 'altlocation')
  1297. os.mkdir(testproject_dir)
  1298. self.addCleanup(shutil.rmtree, testproject_dir)
  1299. out, err = self.run_django_admin(args)
  1300. self.assertNoOutput(err)
  1301. self.assertTrue(os.path.isdir(testproject_dir))
  1302. self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'run.py')))
  1303. def test_custom_project_template_from_tarball_by_url(self):
  1304. "Make sure the startproject management command is able to use a different project template from a tarball via a url"
  1305. template_url = '%s/admin_scripts/custom_templates/project_template.tgz' % self.live_server_url
  1306. args = ['startproject', '--template', template_url, 'urltestproject']
  1307. testproject_dir = os.path.join(test_dir, 'urltestproject')
  1308. self.addCleanup(shutil.rmtree, testproject_dir, True)
  1309. out, err = self.run_django_admin(args)
  1310. self.assertNoOutput(err)
  1311. self.assertTrue(os.path.isdir(testproject_dir))
  1312. self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'run.py')))
  1313. def test_project_template_tarball_url(self):
  1314. "Startproject management command handles project template tar/zip balls from non-canonical urls"
  1315. template_url = '%s/admin_scripts/custom_templates/project_template.tgz/' % self.live_server_url
  1316. args = ['startproject', '--template', template_url, 'urltestproject']
  1317. testproject_dir = os.path.join(test_dir, 'urltestproject')
  1318. self.addCleanup(shutil.rmtree, testproject_dir, True)
  1319. out, err = self.run_django_admin(args)
  1320. self.assertNoOutput(err)
  1321. self.assertTrue(os.path.isdir(testproject_dir))
  1322. self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'run.py')))
  1323. def test_file_without_extension(self):
  1324. "Make sure the startproject management command is able to render custom files"
  1325. template_path = os.path.join(custom_templates_dir, 'project_template')
  1326. args = ['startproject', '--template', template_path, 'customtestproject', '-e', 'txt', '-n', 'Procfile']
  1327. testproject_dir = os.path.join(test_dir, 'customtestproject')
  1328. self.addCleanup(shutil.rmtree, testproject_dir, True)
  1329. out, err = self.run_django_admin(args)
  1330. self.assertNoOutput(err)
  1331. self.assertTrue(os.path.isdir(testproject_dir))
  1332. self.assertTrue(os.path.exists(os.path.join(testproject_dir, 'additional_dir')))
  1333. base_path = os.path.join(testproject_dir, 'additional_dir')
  1334. for f in ('Procfile', 'additional_file.py', 'requirements.txt'):
  1335. self.assertTrue(os.path.exists(os.path.join(base_path, f)))
  1336. with open(os.path.join(base_path, f)) as fh:
  1337. self.assertEqual(fh.read(),
  1338. '# some file for customtestproject test project')
  1339. def test_custom_project_template_context_variables(self):
  1340. "Make sure template context variables are rendered with proper values"
  1341. template_path = os.path.join(custom_templates_dir, 'project_template')
  1342. args = ['startproject', '--template', template_path, 'another_project', 'project_dir']
  1343. testproject_dir = os.path.join(test_dir, 'project_dir')
  1344. os.mkdir(testproject_dir)
  1345. self.addCleanup(shutil.rmtree, testproject_dir)
  1346. out, err = self.run_django_admin(args)
  1347. self.assertNoOutput(err)
  1348. test_manage_py = os.path.join(testproject_dir, 'manage.py')
  1349. with open(test_manage_py, 'r') as fp:
  1350. content = force_text(fp.read())
  1351. self.assertIn("project_name = 'another_project'", content)
  1352. self.assertIn("project_directory = '%s'" % testproject_dir, content)
  1353. def test_no_escaping_of_project_variables(self):
  1354. "Make sure template context variables are not html escaped"
  1355. # We're using a custom command so we need the alternate settings
  1356. self.write_settings('alternate_settings.py')
  1357. self.addCleanup(self.remove_settings, 'alternate_settings.py')
  1358. template_path = os.path.join(custom_templates_dir, 'project_template')
  1359. args = ['custom_startproject', '--template', template_path, 'another_project', 'project_dir', '--extra', '<&>', '--settings=alternate_settings']
  1360. testproject_dir = os.path.join(test_dir, 'project_dir')
  1361. os.mkdir(testproject_dir)
  1362. self.addCleanup(shutil.rmtree, testproject_dir)
  1363. out, err = self.run_manage(args)
  1364. self.assertNoOutput(err)
  1365. test_manage_py = os.path.join(testproject_dir, 'additional_dir', 'extra.py')
  1366. with open(test_manage_py, 'r') as fp:
  1367. content = fp.read()
  1368. self.assertIn("<&>", content)
  1369. def test_custom_project_destination_missing(self):
  1370. """
  1371. Make sure an exception is raised when the provided
  1372. destination directory doesn't exist
  1373. """
  1374. template_path = os.path.join(custom_templates_dir, 'project_template')
  1375. args = ['startproject', '--template', template_path, 'yet_another_project', 'project_dir2']
  1376. testproject_dir = os.path.join(test_dir, 'project_dir2')
  1377. out, err = self.run_django_admin(args)
  1378. self.assertNoOutput(out)
  1379. self.assertOutput(err, "Destination directory '%s' does not exist, please create it first." % testproject_dir)
  1380. self.assertFalse(os.path.exists(testproject_dir))
  1381. def test_custom_project_template_with_non_ascii_templates(self):
  1382. "Ticket 18091: Make sure the startproject management command is able to render templates with non-ASCII content"
  1383. template_path = os.path.join(custom_templates_dir, 'project_template')
  1384. args = ['startproject', '--template', template_path, '--extension=txt', 'customtestproject']
  1385. testproject_dir = os.path.join(test_dir, 'customtestproject')
  1386. self.addCleanup(shutil.rmtree, testproject_dir, True)
  1387. out, err = self.run_django_admin(args)
  1388. self.assertNoOutput(err)
  1389. self.assertTrue(os.path.isdir(testproject_dir))
  1390. path = os.path.join(testproject_dir, 'ticket-18091-non-ascii-template.txt')
  1391. with codecs.open(path, 'r', 'utf-8') as f:
  1392. self.assertEqual(f.read(),
  1393. 'Some non-ASCII text for testing ticket #18091:\nüäö €\n')
  1394. class DiffSettings(AdminScriptTestCase):
  1395. """Tests for diffsettings management command."""
  1396. def test_basic(self):
  1397. """Runs without error and emits settings diff."""
  1398. self.write_settings('settings_to_diff.py', sdict={'FOO': '"bar"'})
  1399. self.addCleanup(self.remove_settings, 'settings_to_diff.py')
  1400. args = ['diffsettings', '--settings=settings_to_diff']
  1401. out, err = self.run_manage(args)
  1402. self.assertNoOutput(err)
  1403. self.assertOutput(out, "FOO = 'bar' ###")
  1404. def test_all(self):
  1405. """The all option also shows settings with the default value."""
  1406. self.write_settings('settings_to_diff.py', sdict={'STATIC_URL': 'None'})
  1407. self.addCleanup(self.remove_settings, 'settings_to_diff.py')
  1408. args = ['diffsettings', '--settings=settings_to_diff', '--all']
  1409. out, err = self.run_manage(args)
  1410. self.assertNoOutput(err)
  1411. self.assertOutput(out, "### STATIC_URL = None")