text: from __future__ import absolute_import, print_function
  
  import sys
  import os
  import re
  import glob
  import string
  import stat
  import tempfile
  
  from distutils.dir_util import remove_tree
  
  from numpy.testing import TestCase, assert_, run_module_suite
  from numpy.testing.noseclasses import KnownFailureTest
  
  from scipy.weave import catalog
  from weave_test_utils import (clear_temp_catalog, restore_temp_catalog,
                                empty_temp_dir, cleanup_temp_dir, dec)
  
  
  skip_on_windows = dec.skipif(sys.platform == 'win32',
                               "Test works only on posix")
  
  
  def samefile(a, b):
      try:
          return os.path.samefile(a, b)
      except AttributeError:
          return os.path.realpath(a) == os.path.realpath(b)
  
  
  class TestIntermediateDir(TestCase):
      """
      Tests for intermediate dir (store of .cpp and .o during builds).
      These tests test whether intermediate dir is safe. If it's not,
      new one should be created.
      """
      def dirs_are_valid(self, wrong_dir, tmpdir):
          # Test if new dir is created and is consistent.
          new_im_dir = catalog.intermediate_dir(tmpdir)
          assert_(not samefile(new_im_dir, wrong_dir))
          new_im_dir2 = catalog.intermediate_dir(tmpdir)
          assert_(samefile(new_im_dir, new_im_dir2))
  
      @skip_on_windows
      def test_ownership(self):
          # Test if intermediate dir is owned by correct user.
          im_dir = catalog.intermediate_dir()
          im_dir_stat = os.stat(im_dir)
          proc_uid = os.getuid()
          assert_(proc_uid == im_dir_stat.st_uid)
          r_im_dir_stat = os.stat(os.path.dirname(im_dir))
          assert_(proc_uid == r_im_dir_stat.st_uid)
  
      @skip_on_windows
      def test_incorrect_ownership(self):
          # Test if new intermediate dir is created when there is only one
          # im dir owned by improper user.
          import pwd
          tmpdir = tempfile.mkdtemp()
          try:
              im_dir = catalog.create_intermediate_dir(tmpdir)
              root_im_dir = os.path.dirname(im_dir)
              nobody = pwd.getpwnam('nobody')[2]
              nobody_g = pwd.getpwnam('nobody')[3]
              try:
                  os.chown(root_im_dir, nobody, nobody_g)
              except OSError:
                  raise KnownFailureTest("Can't change owner.")
              else:
                  self.dirs_are_valid(im_dir, tmpdir)
          finally:
              remove_tree(tmpdir)
  
      @skip_on_windows
      def test_permissions(self):
          # im dir should have permissions 0700
          im_dir = catalog.intermediate_dir()
          im_dir_stat = os.stat(im_dir)
          assert_(stat.S_IMODE(im_dir_stat.st_mode) == 0o0700)
          r_im_dir_stat = os.stat(os.path.dirname(im_dir))
          assert_(stat.S_IMODE(r_im_dir_stat.st_mode) == 0o0700)
  
      @skip_on_windows
      def test_incorrect_permissions(self):
          # If permissions on existing im dir are not correct,
          # a new one should be created.
          tmpdir = tempfile.mkdtemp()
          try:
              im_dir = catalog.create_intermediate_dir(tmpdir)
              root_im_dir = os.path.dirname(im_dir)
              try:
                  os.chmod(root_im_dir, 0o777)
              except OSError:
                  raise KnownFailureTest("Can't set file permissions.")
              else:
                  self.dirs_are_valid(im_dir, tmpdir)
          finally:
              remove_tree(tmpdir)
  
      @skip_on_windows
      def test_symlink(self):
          # im dir shouldn't be a symlink
          r_im_dir = os.path.dirname(catalog.intermediate_dir())
          assert_(os.path.islink(r_im_dir) is False)
  
      @skip_on_windows
      def test_symlink_raise(self):
          # If existing im dir is a symlink, new one should be created.
          tmpdir = tempfile.mkdtemp()
          try:
              im_dir = catalog.create_intermediate_dir(tmpdir)
              root_im_dir = os.path.dirname(im_dir)
  
              tempdir = tempfile.mkdtemp(prefix='scipy-test', dir=tmpdir)
              try:
                  os.rename(root_im_dir, tempdir)
              except OSError:
                  raise KnownFailureTest("Can't move intermediate dir.")
  
              try:
                  os.symlink(tempdir, root_im_dir)
              except OSError:
                  raise KnownFailureTest(
                      "Can't create symlink to intermediate dir.")
              else:
                  self.dirs_are_valid(im_dir, tmpdir)
          finally:
              remove_tree(tmpdir)
  
  
  class TestDefaultDir(TestCase):
      """
      Tests for 'catalog.default_dir()'.
      These should verified posix and win default_dir function.
      """
      def test_win(self):
          # test if default_dir for Windows platform is accessible
          #
          # since default_dir_win() does not have any Windows specific code,
          # let's test it everywhere
          d = catalog.default_dir_win()
          assert_(catalog.is_writable(d))
  
      @skip_on_windows
      def test_posix(self):
          # test if posix default_dir is writable
          d = catalog.default_dir_posix()
          assert_(catalog.is_writable(d))
  
      @skip_on_windows
      def test_posix_home_inaccessible(self):
          # what happens when home catalog dir is innaccessible
          tmpdir = tempfile.mkdtemp()
          try:
              d_dir = catalog.default_dir_posix(tmpdir)
  
              try:
                  os.chmod(d_dir, 0o000)
              except OSError:
                  raise KnownFailureTest("Can't change permissions of default_dir.")
  
              new_ddir = catalog.default_dir_posix(tmpdir)
              assert_(not os.path.samefile(new_ddir, d_dir))
              new_ddir2 = catalog.default_dir_posix(tmpdir)
              assert_(os.path.samefile(new_ddir, new_ddir2))
          finally:
              os.chmod(d_dir, 0o700)
              remove_tree(tmpdir)
  
      @skip_on_windows
      def test_posix_dirs_inaccessible(self):
          # test if new dir is created if both implicit dirs are not valid
          tmpdir = tempfile.mkdtemp()
          try:
              d_dir = catalog.default_dir_posix(tmpdir)
  
              try:
                  os.chmod(d_dir, 0o000)
              except OSError:
                  raise KnownFailureTest("Can't change permissions of default_dir.")
  
              d_dir2 = catalog.default_dir_posix(tmpdir)
  
              try:
                  os.chmod(d_dir2, 0o000)
              except OSError:
                  raise KnownFailureTest("Can't change permissions of default_dir.")
  
              new_ddir = catalog.default_dir_posix(tmpdir)
              assert_(not (os.path.samefile(new_ddir, d_dir) or os.path.samefile(new_ddir, d_dir2)))
              new_ddir2 = catalog.default_dir_posix(tmpdir)
              assert_(os.path.samefile(new_ddir, new_ddir2))
          finally:
              os.chmod(d_dir, 0o700)
              os.chmod(d_dir2, 0o700)
              remove_tree(tmpdir)
  
      def test_is_writable(self):
          # default_dir has to be writable
          path = catalog.default_dir()
          name = os.path.join(path,'dummy_catalog')
          test_file = open(name,'w')
          try:
              test_file.write('making sure default location is writable\n')
          finally:
              test_file.close()
              os.remove(name)
  
  
  class TestOsDependentCatalogName(TestCase):
      pass
  
  
  class TestCatalogPath(TestCase):
  
      def test_default(self):
          in_path = catalog.default_dir()
          path = catalog.catalog_path(in_path)
          d,f = os.path.split(path)
          assert_(d == in_path)
          assert_(f == catalog.os_dependent_catalog_name())
  
      def test_current(self):
          in_path = '.'
          path = catalog.catalog_path(in_path)
          d,f = os.path.split(path)
          assert_(d == os.path.abspath(in_path))
          assert_(f == catalog.os_dependent_catalog_name())
  
      @skip_on_windows
      def test_user(path):
          in_path = '~'
          path = catalog.catalog_path(in_path)
          d,f = os.path.split(path)
          assert_(d == os.path.expanduser(in_path))
          assert_(f == catalog.os_dependent_catalog_name())
  
      def test_module(self):
          # hand it a module and see if it uses the parent directory
          # of the module.
          path = catalog.catalog_path(os.__file__)
          d,f = os.path.split(os.__file__)
          d2,f = os.path.split(path)
          assert_(d2 == d)
  
      def test_path(self):
          # use os.__file__ to get a usable directory.
          in_path,f = os.path.split(os.__file__)
          path = catalog.catalog_path(in_path)
          d,f = os.path.split(path)
          assert_(d == in_path)
  
      def test_bad_path(self):
          # stupid_path_name
          in_path = 'stupid_path_name'
          path = catalog.catalog_path(in_path)
          assert_(path is None)
  
  
  class TestGetCatalog(TestCase):
      """ This only tests whether new catalogs are created correctly.
          And whether non-existent return None correctly with read mode.
          Putting catalogs in the right place is all tested with
          catalog_dir tests.
      """
  
      def get_test_dir(self,erase=0):
          # make sure tempdir catalog doesn't exist
          pardir = tempfile.mkdtemp(suffix='cat_test')
          cat_glob = os.path.join(pardir,catalog.os_dependent_catalog_name()+'.*')
          cat_files = glob.glob(cat_glob)
          if erase:
              for cat_file in cat_files:
                  os.remove(cat_file)
          return pardir
  
      def test_nonexistent_catalog_is_none(self):
          pardir = self.get_test_dir(erase=1)
          cat = catalog.get_catalog(pardir,'r')
          remove_tree(pardir)
          assert_(cat is None)
  
      def test_create_catalog(self):
          pardir = self.get_test_dir(erase=1)
          cat = catalog.get_catalog(pardir,'c')
          assert_(cat is not None)
          cat.close()
          remove_tree(pardir)
  
  
  class TestCatalog(TestCase):
  
      def clear_environ(self):
          if 'PYTHONCOMPILED' in os.environ:
              self.old_PYTHONCOMPILED = os.environ['PYTHONCOMPILED']
              del os.environ['PYTHONCOMPILED']
          else:
              self.old_PYTHONCOMPILED = None
  
      def reset_environ(self):
          if self.old_PYTHONCOMPILED:
              os.environ['PYTHONCOMPILED'] = self.old_PYTHONCOMPILED
              self.old_PYTHONCOMPILED = None
  
      def setUp(self):
          self.clear_environ()
  
      def tearDown(self):
          self.reset_environ()
  
      def test_set_module_directory(self):
          q = catalog.catalog()
          q.set_module_directory('bob')
          r = q.get_module_directory()
          assert_(r == 'bob')
  
      def test_clear_module_directory(self):
          q = catalog.catalog()
          r = q.get_module_directory()
          assert_(r is None)
          q.set_module_directory('bob')
          r = q.clear_module_directory()
          assert_(r is None)
  
      def test_get_environ_path(self):
          if sys.platform == 'win32':
              sep = ';'
          else:
              sep = ':'
          os.environ['PYTHONCOMPILED'] = sep.join(('path1','path2','path3'))
          q = catalog.catalog()
          path = q.get_environ_path()
          assert_(path == ['path1','path2','path3'])
  
      def test_build_search_order1(self):
          # MODULE in search path should be replaced by module_dir.
          q = catalog.catalog(['first','MODULE','third'])
          q.set_module_directory('second')
          order = q.build_search_order()
          assert_(order == ['first','second','third',catalog.default_dir()])
  
      def test_build_search_order2(self):
          # MODULE in search path should be removed if module_dir==None.
          q = catalog.catalog(['first','MODULE','third'])
          order = q.build_search_order()
          assert_(order == ['first','third',catalog.default_dir()])
  
      def test_build_search_order3(self):
          # If MODULE is absent, module_dir shouldn't be in search path.
          q = catalog.catalog(['first','second'])
          q.set_module_directory('third')
          order = q.build_search_order()
          assert_(order == ['first','second',catalog.default_dir()])
  
      def test_build_search_order4(self):
          # Make sure environment variable is getting used.
          q = catalog.catalog(['first','second'])
          if sys.platform == 'win32':
              sep = ';'
          else:
              sep = ':'
          os.environ['PYTHONCOMPILED'] = sep.join(('MODULE','fourth','fifth'))
          q.set_module_directory('third')
          order = q.build_search_order()
          assert_(order == ['first','second','third','fourth','fifth',catalog.default_dir()])
  
      def test_catalog_files1(self):
          # Be sure we get at least one file even without specifying the path.
          q = catalog.catalog()
          files = q.get_catalog_files()
          assert_(len(files) == 1)
  
      def test_catalog_files2(self):
          # Ignore bad paths in the path.
          q = catalog.catalog()
          os.environ['PYTHONCOMPILED'] = '_some_bad_path_'
          files = q.get_catalog_files()
          assert_(len(files) == 1)
  
      def test_get_existing_files1(self):
          # Shouldn't get any files when temp doesn't exist and no path set.
          backup_dir = clear_temp_catalog()
          q = catalog.catalog()
          files = q.get_existing_files()
          restore_temp_catalog(backup_dir)
          assert_(len(files) == 0)
  
      def test_get_existing_files2(self):
          # Shouldn't get a single file from the temp dir.
          backup_dir = clear_temp_catalog()
          q = catalog.catalog()
          # create a dummy file
          q.add_function('code', os.getpid)
          del q
          q = catalog.catalog()
          files = q.get_existing_files()
          restore_temp_catalog(backup_dir)
          assert_(len(files) == 1)
  
      def test_access_writable_file(self):
          # There should always be a writable file -- even if it is in temp
          q = catalog.catalog()
          file = q.get_writable_file()
          try:
              f = open(file,'w')
              f.write('bob')
          finally:
              f.close()
              os.remove(file)
  
      def test_writable_with_bad_path(self):
          # There should always be a writable file -- even if search paths
          # contain bad values.
          if sys.platform == 'win32':
              sep = ';'
          else:
              sep = ':'
          os.environ['PYTHONCOMPILED'] = sep.join(('_bad_path_name_'))
          q = catalog.catalog()
          file = q.get_writable_file()
          try:
              f = open(file,'w')
              f.write('bob')
          finally:
              f.close()
          os.remove(file)
  
      def test_writable_dir(self):
          # Check that we can create a file in the writable directory
          q = catalog.catalog()
          d = q.get_writable_dir()
          file = os.path.join(d,'some_silly_file')
          try:
              f = open(file,'w')
              f.write('bob')
          finally:
              f.close()
              os.remove(file)
  
      def test_unique_module_name(self):
          # Check that we can create a file in the writable directory
          q = catalog.catalog()
          file = q.unique_module_name('bob')
          cfile1 = file+'.cpp'
          assert_(not os.path.exists(cfile1))
          # Make sure it is writable
          try:
              f = open(cfile1,'w')
              f.write('bob')
          finally:
              f.close()
          # try again with same code fragment -- should get unique name
          file = q.unique_module_name('bob')
          cfile2 = file+'.cpp'
          assert_(not os.path.exists(cfile2+'.cpp'))
          os.remove(cfile1)
  
      def test_add_function_persistent1(self):
          # Test persisting a function in the default catalog
          backup_dir = clear_temp_catalog()
          q = catalog.catalog()
          # just use some already available functions
          funcs = [string.upper, string.lower, string.find,string.replace]
          for i in funcs:
              q.add_function_persistent('code',i)
          pfuncs = q.get_cataloged_functions('code')
          # any way to clean modules???
          restore_temp_catalog(backup_dir)
          for i in funcs:
              assert_(i in pfuncs)
  
      def test_add_function_ordered(self):
          backup_dir = clear_temp_catalog()
          q = catalog.catalog()
  
          q.add_function('f',string.upper)
          q.add_function('f',string.lower)
          q.add_function('ff',string.find)
          q.add_function('ff',string.replace)
          q.add_function('fff',string.atof)
          q.add_function('fff',string.atoi)
          del q
  
          # now we're gonna make a new catalog with same code
          # but different functions in a specified module directory
          env_dir = empty_temp_dir()
          r = catalog.catalog(env_dir)
          r.add_function('ff',os.abort)
          r.add_function('ff',os.chdir)
          r.add_function('fff',os.access)
          r.add_function('fff',os.open)
          del r
          # now we're gonna make a new catalog with same code
          # but different functions in a user specified directory
          user_dir = empty_temp_dir()
          s = catalog.catalog(user_dir)
          s.add_function('fff',re.match)
          s.add_function('fff',re.purge)
          del s
  
          # open new catalog and make sure it retreives the functions
          # from d catalog instead of the temp catalog (made by q)
          os.environ['PYTHONCOMPILED'] = env_dir
          t = catalog.catalog(user_dir)
          funcs1 = t.get_functions('f')
          funcs2 = t.get_functions('ff')
          funcs3 = t.get_functions('fff')
          restore_temp_catalog(backup_dir)
          # make sure everything is read back in the correct order
          # a little cheating... I'm ignoring any functions that might have
          # been read in from a prior catalog file (such as the defualt one).
          # the test should really be made so that these aren't read in, but
          # until I get this figured out...
          #assert_(funcs1 == [string.lower,string.upper])
          #assert_(funcs2 == [os.chdir,os.abort,string.replace,string.find])
          #assert_(funcs3 == [re.purge,re.match,os.open,
          #                  os.access,string.atoi,string.atof])
          assert_(funcs1[:2] == [string.lower,string.upper]),repr(funcs1)
          assert_(funcs2[:4] == [os.chdir,os.abort,string.replace,string.find])
          assert_(funcs3[:6] == [re.purge,re.match,os.open,
                            os.access,string.atoi,string.atof])
          cleanup_temp_dir(user_dir)
          cleanup_temp_dir(env_dir)
  
  
  if __name__ == '__main__':
      run_module_suite()
  