~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to testsweet.py

  • Committer: Robert Collins
  • Date: 2005-08-23 08:58:06 UTC
  • mto: (974.1.50) (1185.1.10) (1092.3.1)
  • mto: This revision was merged to the branch mainline in revision 1139.
  • Revision ID: robertc@robertcollins.net-20050823085806-15dff1c25274ec7b
rename InTempDir to FunctionalTestCase providing InTempDir for compatability

Show diffs side-by-side

added added

removed removed

Lines of Context:
56
56
 
57
57
 
58
58
class TestCase(unittest.TestCase):
59
 
    """Base class for bzr test cases.
60
 
 
61
 
    Just defines some useful helper functions; doesn't actually test
62
 
    anything.
 
59
    """Base class for bzr unit tests.
 
60
    
 
61
    Tests that need access to disk resources should subclass 
 
62
    FunctionalTestCase not TestCase.
63
63
    """
64
64
    
65
65
    # TODO: Special methods to invoke bzr, so that we can run it
88
88
        self.log('')
89
89
        super(TestCase, self).tearDown()
90
90
 
91
 
    def formcmd(self, cmd):
92
 
        if isinstance(cmd, basestring):
93
 
            cmd = cmd.split()
94
 
 
95
 
        if cmd[0] == 'bzr':
96
 
            cmd[0] = self.BZRPATH
97
 
            if self.OVERRIDE_PYTHON:
98
 
                cmd.insert(0, self.OVERRIDE_PYTHON)
99
 
 
100
 
        self.log('$ %r' % cmd)
101
 
 
102
 
        return cmd
103
 
 
104
 
 
105
 
    def runcmd(self, cmd, retcode=0):
106
 
        """Run one command and check the return code.
107
 
 
108
 
        Returns a tuple of (stdout,stderr) strings.
109
 
 
110
 
        If a single string is based, it is split into words.
111
 
        For commands that are not simple space-separated words, please
112
 
        pass a list instead."""
113
 
        try:
114
 
            import shutil
115
 
            from subprocess import call
116
 
        except ImportError, e:
117
 
            _need_subprocess()
118
 
            raise
119
 
 
120
 
 
121
 
        cmd = self.formcmd(cmd)
122
 
 
123
 
        self.log('$ ' + ' '.join(cmd))
124
 
        actual_retcode = call(cmd, stdout=self.TEST_LOG, stderr=self.TEST_LOG)
125
 
 
126
 
        if retcode != actual_retcode:
127
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
128
 
                                % (cmd, actual_retcode, retcode))
129
 
 
130
 
 
131
 
    def backtick(self, cmd, retcode=0):
132
 
        """Run a command and return its output"""
133
 
        try:
134
 
            import shutil
135
 
            from subprocess import Popen, PIPE
136
 
        except ImportError, e:
137
 
            _need_subprocess()
138
 
            raise
139
 
 
140
 
        cmd = self.formcmd(cmd)
141
 
        child = Popen(cmd, stdout=PIPE, stderr=self.TEST_LOG)
142
 
        outd, errd = child.communicate()
143
 
        self.log(outd)
144
 
        actual_retcode = child.wait()
145
 
 
146
 
        outd = outd.replace('\r', '')
147
 
 
148
 
        if retcode != actual_retcode:
149
 
            raise CommandFailed("test failed: %r returned %d, expected %d"
150
 
                                % (cmd, actual_retcode, retcode))
151
 
 
152
 
        return outd
153
 
 
154
 
 
155
 
 
156
 
    def build_tree(self, shape):
157
 
        """Build a test tree according to a pattern.
158
 
 
159
 
        shape is a sequence of file specifications.  If the final
160
 
        character is '/', a directory is created.
161
 
 
162
 
        This doesn't add anything to a branch.
163
 
        """
164
 
        # XXX: It's OK to just create them using forward slashes on windows?
165
 
        import os
166
 
        for name in shape:
167
 
            assert isinstance(name, basestring)
168
 
            if name[-1] == '/':
169
 
                os.mkdir(name[:-1])
170
 
            else:
171
 
                f = file(name, 'wt')
172
 
                print >>f, "contents of", name
173
 
                f.close()
174
 
 
175
 
 
176
91
    def log(self, msg):
177
92
        """Log a message to a progress file"""
178
93
        print >>self.TEST_LOG, msg
179
94
 
180
 
 
181
95
    def check_inventory_shape(self, inv, shape):
182
96
        """
183
97
        Compare an inventory to a list of expected names.
198
112
            self.fail("expected paths not found in inventory: %r" % shape)
199
113
        if extras:
200
114
            self.fail("unexpected paths found in inventory: %r" % extras)
201
 
 
202
 
    def check_file_contents(self, filename, expect):
203
 
        self.log("check contents of file %s" % filename)
204
 
        contents = file(filename, 'r').read()
205
 
        if contents != expect:
206
 
            self.log("expected: %r" % expect)
207
 
            self.log("actually: %r" % contents)
208
 
            self.fail("contents of %s not as expected")
209
115
     
210
116
    def _get_log(self):
211
117
        """Get the log the test case used. This can only be called once,
217
123
        return log
218
124
 
219
125
 
220
 
class InTempDir(TestCase):
221
 
    """Base class for tests that use disk resources - i.e to run in a temporary
222
 
    branch.
 
126
class FunctionalTestCase(TestCase):
 
127
    """Base class for tests that perform function testing - running bzr,
 
128
    using files on disk, and similar activities.
 
129
 
 
130
    InTempDir is an old alias for FunctionalTestCase.
223
131
    """
224
132
 
225
133
    TEST_ROOT = None
226
134
    _TEST_NAME = 'test'
227
135
 
 
136
    def check_file_contents(self, filename, expect):
 
137
        self.log("check contents of file %s" % filename)
 
138
        contents = file(filename, 'r').read()
 
139
        if contents != expect:
 
140
            self.log("expected: %r" % expect)
 
141
            self.log("actually: %r" % contents)
 
142
            self.fail("contents of %s not as expected")
 
143
 
228
144
    def _make_test_root(self):
229
145
        import os
230
146
        import shutil
231
147
        import tempfile
232
148
        
233
 
        if InTempDir.TEST_ROOT is not None:
 
149
        if FunctionalTestCase.TEST_ROOT is not None:
234
150
            return
235
 
        InTempDir.TEST_ROOT = os.path.abspath(
 
151
        FunctionalTestCase.TEST_ROOT = os.path.abspath(
236
152
                                 tempfile.mkdtemp(suffix='.tmp',
237
153
                                                  prefix=self._TEST_NAME + '-',
238
154
                                                  dir=os.curdir))
239
155
    
240
 
        # print '%-30s %s\n' % ('running tests in', TestCase.TEST_ROOT)
241
 
    
242
 
        os.chdir(InTempDir.TEST_ROOT)
243
156
        # make a fake bzr directory there to prevent any tests propagating
244
157
        # up onto the source directory's real branch
245
 
        os.mkdir(os.path.join(InTempDir.TEST_ROOT, '.bzr'))
 
158
        os.mkdir(os.path.join(FunctionalTestCase.TEST_ROOT, '.bzr'))
246
159
 
247
160
    def setUp(self):
248
 
        super(InTempDir, self).setUp()
 
161
        super(FunctionalTestCase, self).setUp()
249
162
        import os
250
163
        self._make_test_root()
 
164
        self._currentdir = os.getcwdu()
251
165
        self.test_dir = os.path.join(self.TEST_ROOT, self.__class__.__name__)
252
166
        os.mkdir(self.test_dir)
253
167
        os.chdir(self.test_dir)
254
168
        
255
169
    def tearDown(self):
256
170
        import os
257
 
        os.chdir(self.TEST_ROOT)
258
 
        super(InTempDir, self).tearDown()
 
171
        os.chdir(self._currentdir)
 
172
        super(FunctionalTestCase, self).tearDown()
 
173
 
 
174
    def formcmd(self, cmd):
 
175
        if isinstance(cmd, basestring):
 
176
            cmd = cmd.split()
 
177
 
 
178
        if cmd[0] == 'bzr':
 
179
            cmd[0] = self.BZRPATH
 
180
            if self.OVERRIDE_PYTHON:
 
181
                cmd.insert(0, self.OVERRIDE_PYTHON)
 
182
 
 
183
        self.log('$ %r' % cmd)
 
184
 
 
185
        return cmd
 
186
 
 
187
 
 
188
    def runcmd(self, cmd, retcode=0):
 
189
        """Run one command and check the return code.
 
190
 
 
191
        Returns a tuple of (stdout,stderr) strings.
 
192
 
 
193
        If a single string is based, it is split into words.
 
194
        For commands that are not simple space-separated words, please
 
195
        pass a list instead."""
 
196
        try:
 
197
            import shutil
 
198
            from subprocess import call
 
199
        except ImportError, e:
 
200
            _need_subprocess()
 
201
            raise
 
202
 
 
203
 
 
204
        cmd = self.formcmd(cmd)
 
205
 
 
206
        self.log('$ ' + ' '.join(cmd))
 
207
        actual_retcode = call(cmd, stdout=self.TEST_LOG, stderr=self.TEST_LOG)
 
208
 
 
209
        if retcode != actual_retcode:
 
210
            raise CommandFailed("test failed: %r returned %d, expected %d"
 
211
                                % (cmd, actual_retcode, retcode))
 
212
 
 
213
 
 
214
    def backtick(self, cmd, retcode=0):
 
215
        """Run a command and return its output"""
 
216
        try:
 
217
            import shutil
 
218
            from subprocess import Popen, PIPE
 
219
        except ImportError, e:
 
220
            _need_subprocess()
 
221
            raise
 
222
 
 
223
        cmd = self.formcmd(cmd)
 
224
        child = Popen(cmd, stdout=PIPE, stderr=self.TEST_LOG)
 
225
        outd, errd = child.communicate()
 
226
        self.log(outd)
 
227
        actual_retcode = child.wait()
 
228
 
 
229
        outd = outd.replace('\r', '')
 
230
 
 
231
        if retcode != actual_retcode:
 
232
            raise CommandFailed("test failed: %r returned %d, expected %d"
 
233
                                % (cmd, actual_retcode, retcode))
 
234
 
 
235
        return outd
 
236
 
 
237
 
 
238
 
 
239
    def build_tree(self, shape):
 
240
        """Build a test tree according to a pattern.
 
241
 
 
242
        shape is a sequence of file specifications.  If the final
 
243
        character is '/', a directory is created.
 
244
 
 
245
        This doesn't add anything to a branch.
 
246
        """
 
247
        # XXX: It's OK to just create them using forward slashes on windows?
 
248
        import os
 
249
        for name in shape:
 
250
            assert isinstance(name, basestring)
 
251
            if name[-1] == '/':
 
252
                os.mkdir(name[:-1])
 
253
            else:
 
254
                f = file(name, 'wt')
 
255
                print >>f, "contents of", name
 
256
                f.close()
 
257
                
 
258
InTempDir = FunctionalTestCase
259
259
 
260
260
 
261
261
class _MyResult(unittest._TextTestResult):
319
319
 
320
320
def run_suite(suite, name='test', verbose=False):
321
321
    import shutil
322
 
    InTempDir._TEST_NAME = name
 
322
    FunctionalTestCase._TEST_NAME = name
323
323
    if verbose:
324
324
        verbosity = 2
325
325
    else:
330
330
    # but only a little. Folk not using our testrunner will
331
331
    # have to delete their temp directories themselves.
332
332
    if result.wasSuccessful():
333
 
        shutil.rmtree(InTempDir.TEST_ROOT) 
 
333
        shutil.rmtree(FunctionalTestCase.TEST_ROOT) 
334
334
    else:
335
 
        print "Failed tests working directories are in '%s'\n" % InTempDir.TEST_ROOT
 
335
        print "Failed tests working directories are in '%s'\n" % FunctionalTestCase.TEST_ROOT
336
336
    return result.wasSuccessful()