class TestMyTask(SingleTaskTestCase): TASK = MyTask def setUp(self): self.testpath = NamedTemporaryDirectory() MyTask.PATH = self.testpath.name MyTask.INTERVAL = 0.25 super(TestMyTask, self).setUp() self.task.execute() def tearDown(self): self.testpath.close() super(TestMyTask, self).tearDown() def test_file_create(self): fn = self.testpath.join('foo') with open(fn, mode='w'): pass os.utime(fn, None) self.task.execute() self.assertTrue(self.task.onFileCreated.called) self.assertEqual(self.task.onFileCreated.call_count, 1) self.assertEqual(self.task.onFileCreated.call_args[0][0], 'foo', self.task.onFileCreated.call_args) def test_file_delete(self): self.test_file_create() os.remove(self.testpath.join('foo')) self.task.execute() self.assertTrue(self.task.onFileDeleted.called) self.assertEqual(self.task.onFileDeleted.call_count, 1) self.assertEqual(self.task.onFileDeleted.call_args[0][0], 'foo', self.task.onFileDeleted.call_args) def test_file_update(self): self.test_file_create() self.task.execute() path = self.testpath.join('foo') # Run once to make sure we detect the current time for the files self.task.execute() # Forcibly update the atime/mtime of the file st = os.stat(path) self.task.stat = self.mock.Mock() self.task.stat.return_value = self.mock.NonCallableMock(wraps=st) self.task.stat.return_value.st_atime = st.st_atime - 10 self.task.stat.return_value.st_mtime = st.st_mtime - 10 self.task.execute() self.task.stat.assert_called() st2 = self.task.stat() self.assertEqual(st2.st_atime, st.st_atime - 10) self.assertEqual(st2.st_mtime, st.st_mtime - 10) self.assertTrue(self.task.onFileChanged.called) self.assertEqual(self.task.onFileChanged.call_count, 1) self.assertEqual(self.task.onFileChanged.call_args[0][0], 'foo', self.task.onFileChanged.call_args) def test_file_delete_race_condition(self): self.test_file_create() self.task.stat = self.mock.Mock() self.task.stat.side_effect = OSError(errno.ENOENT, 'Fake ENOENT') self.task.execute() self.assertTrue(self.task.onFileDeleted.called) def test_nodirectory_ok(self): # Call close() on the named directory to cleanup the directory self.testpath.close() # Then, call execute() and make sure nothing blows up self.task.execute()
def importThrift(self, path, **kwargs): """Compiles a .thrift file, importing its contents into its return value""" path = os.path.abspath(path) assert os.path.exists(path) assert os.path.isfile(path) srcdir = self.makeTemporaryIncludeDir() pathbase = os.path.basename(path) srcdir.symlink(pathbase, path) outdir = NamedTemporaryDirectory(prefix='to1_') outdir_recurse = NamedTemporaryDirectory(prefix='tor_') if self.debug: outdir.keep() outdir_recurse.keep() args = [self.thrift_bin] + self.makeIncludeArgs(srcdir) + \ ["--gen", self.getThriftOptions(**kwargs), '-v', "-o", outdir.name, srcdir.join(pathbase)] check_output(args) args = [self.thrift_bin] + self.makeIncludeArgs(srcdir) + \ ["--gen", self.getThriftOptions(**kwargs), '-v', '-r', "-o", outdir_recurse.name, srcdir.join(pathbase)] check_output(args) # Prepend output directory to the path with ctx.add_path(outdir_recurse.join('gen-py'), 0): thriftname = os.path.splitext(pathbase)[0] for dirpath, dirnames, filenames in os.walk(outdir.join('gen-py')): # Emulate relative imports badly dirpath = os.path.abspath(outdir.join('gen-py', dirpath)) with ctx.add_path(dirpath): # Add types to module first if 'ttypes.py' in filenames: ttypes = self.importPython(dirpath + '/ttypes.py') result = ttypes filenames.remove('ttypes.py') # Then constants if 'constants.py' in filenames: result = self.mergeModules( self.importPython(dirpath + '/constants.py'), result) filenames.remove('constants.py') for filename in filenames: # Skip pyremotes if not filename.endswith('.py') or \ filename == '__init__.py': continue # Attach services as attributes on the module. svcpath = dirpath + '/' + filename svcname = os.path.splitext(filename)[0] svcmod = self.importPython(svcpath) svcmod.__file__ = os.path.abspath(svcpath) svcmod.__name__ = '%s.%s (generated)' % \ (thriftname, svcname) setattr(result, svcname, svcmod) assert result is not None, "No files generated by %s" % (path, ) # Set the __file__ attribute to the .thrift file instead # of the dynamically generated jonx result.__file__ = os.path.abspath(path) result.__name__ = thriftname + " (generated)" return result
def importThrift(self, path, **kwargs): """Compiles a .thrift file, importing its contents into its return value""" path = os.path.abspath(path) assert os.path.exists(path) assert os.path.isfile(path) srcdir = self.makeTemporaryIncludeDir() pathbase = os.path.basename(path) srcdir.symlink(pathbase, path) outdir = NamedTemporaryDirectory(prefix='to1_') outdir_recurse = NamedTemporaryDirectory(prefix='tor_') if self.debug: outdir.keep() outdir_recurse.keep() args = [self.thrift_bin] + self.makeIncludeArgs(srcdir) + \ ["--gen", self.getThriftOptions(**kwargs), '-v', "-o", outdir.name, srcdir.join(pathbase)] check_output(args) args = [self.thrift_bin] + self.makeIncludeArgs(srcdir) + \ ["--gen", self.getThriftOptions(**kwargs), '-v', '-r', "-o", outdir_recurse.name, srcdir.join(pathbase)] check_output(args) # Prepend output directory to the path with ctx.add_path(outdir_recurse.join('gen-py'), 0): thriftname = os.path.splitext(pathbase)[0] for dirpath, dirnames, filenames in os.walk(outdir.join('gen-py')): # Emulate relative imports badly dirpath = os.path.abspath(outdir.join('gen-py', dirpath)) with ctx.add_path(dirpath): # Add types to module first if 'ttypes.py' in filenames: ttypes = self.importPython(dirpath + '/ttypes.py') result = ttypes filenames.remove('ttypes.py') # Then constants if 'constants.py' in filenames: result = self.mergeModules( self.importPython(dirpath + '/constants.py'), result) filenames.remove('constants.py') for filename in filenames: # Skip pyremotes if not filename.endswith('.py') or \ filename == '__init__.py': continue # Attach services as attributes on the module. svcpath = dirpath + '/' + filename svcname = os.path.splitext(filename)[0] svcmod = self.importPython(svcpath) svcmod.__file__ = os.path.abspath(svcpath) svcmod.__name__ = '%s.%s (generated)' % \ (thriftname, svcname) setattr(result, svcname, svcmod) assert result is not None, "No files generated by %s" % (path, ) # Set the __file__ attribute to the .thrift file instead # of the dynamically generated jonx result.__file__ = os.path.abspath(path) result.__name__ = thriftname + " (generated)" return result
class TestMyTask(SingleTaskTestCase): TASK = MyTask def setUp(self): self.testpath = NamedTemporaryDirectory() MyTask.PATH = self.testpath.name MyTask.INTERVAL = 0.25 super(TestMyTask, self).setUp() self.task.execute() def tearDown(self): self.testpath.close() super(TestMyTask, self).tearDown() def test_file_create(self): fn = self.testpath.join('foo') with open(fn, mode='w'): pass os.utime(fn, None) self.task.execute() self.assertTrue(self.task.onFileCreated.called) self.assertEqual(self.task.onFileCreated.call_count, 1) self.assertEqual(self.task.onFileCreated.call_args[0][0], 'foo', self.task.onFileCreated.call_args) def test_file_delete(self): self.test_file_create() os.remove(self.testpath.join('foo')) self.task.execute() self.assertTrue(self.task.onFileDeleted.called) self.assertEqual(self.task.onFileDeleted.call_count, 1) self.assertEqual(self.task.onFileDeleted.call_args[0][0], 'foo', self.task.onFileDeleted.call_args) def test_file_update(self): self.test_file_create() self.task.execute() path = self.testpath.join('foo') # Run once to make sure we detect the current time for the files self.task.execute() # Forcibly update the atime/mtime of the file st = os.stat(path) self.task.stat = self.mock.Mock() self.task.stat.return_value = self.mock.NonCallableMock(wraps=st) self.task.stat.return_value.st_atime = st.st_atime - 10 self.task.stat.return_value.st_mtime = st.st_mtime - 10 self.task.execute() self.task.stat.assert_called_with(path) st2 = self.task.stat() self.assertEqual(st2.st_atime, st.st_atime - 10) self.assertEqual(st2.st_mtime, st.st_mtime - 10) self.assertTrue(self.task.onFileChanged.called) self.assertEqual(self.task.onFileChanged.call_count, 1) self.assertEqual(self.task.onFileChanged.call_args[0][0], 'foo', self.task.onFileChanged.call_args) def test_file_delete_race_condition(self): self.test_file_create() self.task.stat = self.mock.Mock() self.task.stat.side_effect = OSError(errno.ENOENT, 'Fake ENOENT') self.task.execute() self.assertTrue(self.task.onFileDeleted.called) def test_nodirectory_ok(self): # Call close() on the named directory to cleanup the directory self.testpath.close() # Then, call execute() and make sure nothing blows up self.task.execute()