src/tests/api/t_altroot.py
changeset 2339 aa5954c06b9d
child 3158 58c9c2c21e67
equal deleted inserted replaced
2338:63a4d56416c6 2339:aa5954c06b9d
       
     1 #!/usr/bin/python
       
     2 #
       
     3 # CDDL HEADER START
       
     4 #
       
     5 # The contents of this file are subject to the terms of the
       
     6 # Common Development and Distribution License (the "License").
       
     7 # You may not use this file except in compliance with the License.
       
     8 #
       
     9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
       
    10 # or http://www.opensolaris.org/os/licensing.
       
    11 # See the License for the specific language governing permissions
       
    12 # and limitations under the License.
       
    13 #
       
    14 # When distributing Covered Code, include this CDDL HEADER in each
       
    15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
       
    16 # If applicable, add the following below this CDDL HEADER, with the
       
    17 # fields enclosed by brackets "[]" replaced with your own identifying
       
    18 # information: Portions Copyright [yyyy] [name of copyright owner]
       
    19 #
       
    20 # CDDL HEADER END
       
    21 #
       
    22 
       
    23 # Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
       
    24 
       
    25 import testutils
       
    26 if __name__ == "__main__":
       
    27         testutils.setup_environment("../../../proto")
       
    28 import pkg5unittest
       
    29 
       
    30 import errno
       
    31 import os
       
    32 import sys
       
    33 import traceback
       
    34 import unittest
       
    35 
       
    36 import pkg.altroot as ar
       
    37 import pkg.client.image as image
       
    38 
       
    39 class TestAltroot(pkg5unittest.CliTestCase):
       
    40         persistent_setup = True
       
    41 
       
    42         def setUp(self):
       
    43                 self.i_count = 4
       
    44                 pkg5unittest.CliTestCase.setUp(self, image_count=self.i_count)
       
    45 
       
    46                 # image path
       
    47                 self.i = []
       
    48 
       
    49                 # image files and directories
       
    50                 self.p_f1 = "f1"
       
    51                 self.p_f2 = "f2"
       
    52                 self.p_none = "none"
       
    53                 self.p_d = "d"
       
    54                 self.p_d_f1 = os.path.join(self.p_d, "f1")
       
    55                 self.p_d_f2 = os.path.join(self.p_d, "f2")
       
    56                 self.p_d_none = os.path.join(self.p_d, "none")
       
    57                 self.p_f1_redir = "f1_redir"
       
    58                 self.p_f2_redir = "f2_redir"
       
    59                 self.p_d_redir = "d_redir"
       
    60                 self.p_d_f1_redir = os.path.join(self.p_d_redir, "f1")
       
    61                 self.p_d_f2_redir = os.path.join(self.p_d_redir, "f2")
       
    62                 self.p_d_none_redir = os.path.join(self.p_d_redir, "none")
       
    63 
       
    64                 for i in range(0, self.i_count):
       
    65                         # first assign paths.  we'll use the image paths even
       
    66                         # though we're not actually doing any testing with
       
    67                         # real images.
       
    68                         r = self.img_path(i)
       
    69                         self.i.insert(i, r)
       
    70 
       
    71                         os.makedirs(r)
       
    72                         if i == 0:
       
    73                                 # simulate a root image
       
    74                                 os.makedirs(
       
    75                                     os.path.join(r, image.img_user_prefix))
       
    76                         elif i == 1:
       
    77                                 # simulate a user image
       
    78                                 os.makedirs(
       
    79                                     os.path.join(r, image.img_root_prefix))
       
    80                         elif i == 2:
       
    81                                 # corrupt image: both root and user
       
    82                                 os.makedirs(
       
    83                                     os.path.join(r, image.img_user_prefix))
       
    84                                 os.makedirs(
       
    85                                     os.path.join(r, image.img_root_prefix))
       
    86 
       
    87                 for i in range(0, self.i_count):
       
    88                         r = self.i[i]
       
    89                         if i > 0:
       
    90                                 r_alt = self.i[i - 1]
       
    91                         else:
       
    92                                 r_alt = self.i[self.i_count - 1]
       
    93                         r_redir = os.path.basename(r_alt)
       
    94 
       
    95                         # create directories and files within the image
       
    96                         self.make_file(os.path.join(r, self.p_f1), "foo")
       
    97                         self.make_file(os.path.join(r, self.p_f2), "foo")
       
    98                         self.make_file(os.path.join(r, self.p_d_f1), "bar")
       
    99                         self.make_file(os.path.join(r, self.p_d_f2), "bar")
       
   100 
       
   101                         # create sym links that point outside that image
       
   102                         os.symlink(os.path.join("..", r_redir, self.p_f1),
       
   103                             os.path.join(r, self.p_f1_redir))
       
   104 
       
   105                         os.symlink(os.path.join("..", r_redir, self.p_f2),
       
   106                             os.path.join(r, self.p_f2_redir))
       
   107 
       
   108                         os.symlink(os.path.join("..", r_redir, self.p_d),
       
   109                             os.path.join(r, self.p_d_redir))
       
   110 
       
   111         def __eremote(self, func, args):
       
   112                 e = None
       
   113                 try:
       
   114                         func(*args)
       
   115                 except:
       
   116                         e_type, e, e_traceback = sys.exc_info()
       
   117 
       
   118                 if isinstance(e, OSError) and e.errno == errno.EREMOTE:
       
   119                         return
       
   120 
       
   121                 if e == None:
       
   122                         e_str = str(None)
       
   123                 else:
       
   124                         e_str = traceback.format_exc()
       
   125 
       
   126                 args = ", ".join([str(a) for a in args])
       
   127                 self.fail(
       
   128                     "altroot call didn't return OSError EREMOTE exception\n"
       
   129                     "call: %s(%s)\n"
       
   130                     "exception: %s\n" %
       
   131                     (func.__name__, args, e_str))
       
   132 
       
   133         def test_ar_err_eremote(self):
       
   134                 """Verify that all altroot accessor functions return EREMOTE
       
   135                 if they traverse a path which contains a symlink that point
       
   136                 somewhere outside the specified altroot namespace."""
       
   137 
       
   138                 r = self.i[0]
       
   139                 invoke = [
       
   140                     (ar.ar_open, (r, self.p_f1_redir, os.O_RDONLY)),
       
   141                     (ar.ar_open, (r, self.p_d_f1_redir, os.O_RDONLY)),
       
   142 
       
   143                     (ar.ar_unlink, (r, self.p_d_f1_redir)),
       
   144 
       
   145                     (ar.ar_rename, (r, self.p_d_f1_redir, self.p_d_f1)),
       
   146                     (ar.ar_rename, (r, self.p_d_f1, self.p_d_f1_redir)),
       
   147                     (ar.ar_rename, (r, self.p_d_f1_redir, self.p_d_f2_redir)),
       
   148 
       
   149                     (ar.ar_mkdir, (r, self.p_d_none_redir, 0777)),
       
   150 
       
   151                     (ar.ar_stat, (r, self.p_f1_redir)),
       
   152                     (ar.ar_stat, (r, self.p_d_f1_redir)),
       
   153 
       
   154                     (ar.ar_isdir, (r, self.p_d_redir)),
       
   155                     (ar.ar_isdir, (r, self.p_d_f1_redir)),
       
   156 
       
   157                     (ar.ar_exists, (r, self.p_f1_redir)),
       
   158                     (ar.ar_exists, (r, self.p_d_redir)),
       
   159                     (ar.ar_exists, (r, self.p_d_f1_redir)),
       
   160 
       
   161                     (ar.ar_diff, (r, self.p_f1, self.p_f2_redir)),
       
   162                     (ar.ar_diff, (r, self.p_f1_redir, self.p_f2)),
       
   163                     (ar.ar_diff, (r, self.p_d_f1, self.p_d_f2_redir)),
       
   164                     (ar.ar_diff, (r, self.p_d_f1_redir, self.p_d_f2)),
       
   165                 ]
       
   166                 for func, args in invoke:
       
   167                         self.__eremote(func, args)
       
   168 
       
   169         def __bad_img_prefix(self, func, args):
       
   170                 rv = func(*args)
       
   171                 if rv == None:
       
   172                         return
       
   173 
       
   174                 args = ", ".join([str(a) for a in args])
       
   175                 self.fail(
       
   176                     "altroot call didn't return None\n"
       
   177                     "call: %s(%s)\n"
       
   178                     "rv: %s\n" %
       
   179                     (func.__name__, args, str(rv)))
       
   180 
       
   181         def test_ar_err_img_prefix(self):
       
   182                 """Verify that ar_img_prefix() returns None if we have a
       
   183                 corrupt image.  image 2 has both user and root image
       
   184                 repositories.  image 3 is not an image, it's an empty
       
   185                 directory."""
       
   186 
       
   187                 invoke = [
       
   188                     (ar.ar_img_prefix, (self.i[2],)),
       
   189                     (ar.ar_img_prefix, (self.i[3],)),
       
   190                 ]
       
   191                 for func, args in invoke:
       
   192                         self.__bad_img_prefix(func, args)
       
   193 
       
   194 if __name__ == "__main__":
       
   195         unittest.main()