3
# Copyright 2008 Google Inc.
5
# Licensed under the Apache License, Version 2.0 (the "License");
6
# you may not use this file except in compliance with the License.
7
# You may obtain a copy of the License at
9
# http://www.apache.org/licenses/LICENSE-2.0
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS,
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
# See the License for the specific language governing permissions and
15
# limitations under the License.
18
Tests that the manage.py commands execute correctly.
20
These tests only verify that the commands execute and exit with a success code.
21
They are intended to catch import exceptions and similar problems, it is left
22
up to tests in other modules to verify that the functionality of each command
35
from django.db.models import get_models
37
from google.appengine.ext import db
38
from appengine_django.models import BaseModel
39
from appengine_django.models import ModelManager
40
from appengine_django.models import ModelOptions
41
from appengine_django.models import RegistrationTestModel
44
class CommandsTest(unittest.TestCase):
45
"""Unit tests for the manage.py commands."""
47
# How many seconds to wait for a command to exit.
50
def runCommand(self, command, args=None, int_after=None, input=None):
51
"""Helper to run the specified command in a child process.
54
command: The name of the command to run.
55
args: List of command arguments to run the command with.
56
int_after: If set to a positive integer, SIGINT will be sent to the
57
running child process after this many seconds to cause an exit. This
58
should be less than the COMMAND_TIMEOUT value (10 seconds).
59
input: A string to write to stdin when the command starts. stdin is
60
closed after the string is written.
63
rc: The integer return code of the process.
64
output: A string containing the childs output.
72
child = subprocess.Popen(["./manage.py", command] + args, stdin=fd,
73
stdout=fd, stderr=fd, cwd=os.getcwdu())
75
child.stdin.write(input)
83
elapsed = time.time() - start
84
if int_after and int_after > 0 and elapsed > int_after and not int_sent:
85
# Sent SIGINT as requested, give child time to exit cleanly.
86
os.kill(child.pid, signal.SIGINT)
90
if elapsed < self.COMMAND_TIMEOUT:
92
# Command is over time, kill and exit loop.
93
os.kill(child.pid, signal.SIGKILL)
94
time.sleep(2) # Give time for the signal to be received.
97
# Return status and output.
98
return rc, child.stdout.read(), child.stderr.read()
100
def assertCommandSucceeds(self, command, *args, **kwargs):
101
"""Asserts that the specified command successfully completes.
104
command: The name of the command to run.
105
All other arguments are passed directly through to the runCommand
109
This function does not return anything but will raise assertion errors if
110
the command does not exit successfully.
112
rc, stdout, stderr = self.runCommand(command, *args, **kwargs)
113
fd, tempname = tempfile.mkstemp()
116
self.assertEquals(0, rc,
117
"%s did not return successfully (rc: %d): Output in %s" %
118
(command, rc, tempname))
121
def getCommands(self):
122
"""Returns a list of valid commands for manage.py.
128
A list of valid commands for manage.py as read from manage.py's help
131
rc, stdout, stderr = self.runCommand("help")
132
parts = re.split("Available subcommands:", stderr)
136
return [t.strip() for t in parts[-1].split("\n") if t.strip()]
138
def testDiffSettings(self):
139
"""Tests the diffsettings command."""
140
self.assertCommandSucceeds("diffsettings")
142
def testDumpData(self):
143
"""Tests the dumpdata command."""
144
self.assertCommandSucceeds("dumpdata")
147
"""Tests the flush command."""
148
self.assertCommandSucceeds("flush")
150
def testLoadData(self):
151
"""Tests the loaddata command."""
152
self.assertCommandSucceeds("loaddata")
154
def testLoadData(self):
155
"""Tests the loaddata command."""
156
self.assertCommandSucceeds("loaddata")
159
"""Tests the reste command."""
160
self.assertCommandSucceeds("reset", ["appengine_django"])
162
def testRunserver(self):
163
"""Tests the runserver command."""
164
self.assertCommandSucceeds("runserver", int_after=2.0)
167
"""Tests the shell command."""
168
self.assertCommandSucceeds("shell", input="exit")
170
def testUpdate(self):
171
"""Tests that the update command exists.
173
Cannot test that it works without mocking out parts of dev_appserver so for
174
now we just assume that if it is present it will work.
176
cmd_list = self.getCommands()
177
self.assert_("update" in cmd_list)
179
def testZipCommandListFiltersCorrectly(self):
180
"""When running under a zipfile test that only valid commands are found."""
181
cmd_list = self.getCommands()
182
self.assert_("__init__" not in cmd_list)
183
self.assert_("base" not in cmd_list)