1*1902Szelenkov@nginx.comimport os 2*1902Szelenkov@nginx.comimport subprocess 3*1902Szelenkov@nginx.comfrom pathlib import Path 4*1902Szelenkov@nginx.com 5*1902Szelenkov@nginx.comimport pytest 6*1902Szelenkov@nginx.com 7*1902Szelenkov@nginx.comfrom unit.applications.proto import TestApplicationProto 8*1902Szelenkov@nginx.com 9*1902Szelenkov@nginx.com 10*1902Szelenkov@nginx.comclass TestStaticMount(TestApplicationProto): 11*1902Szelenkov@nginx.com prerequisites = {'features': ['chroot']} 12*1902Szelenkov@nginx.com 13*1902Szelenkov@nginx.com @pytest.fixture(autouse=True) 14*1902Szelenkov@nginx.com def setup_method_fixture(self, is_su, temp_dir): 15*1902Szelenkov@nginx.com if not is_su: 16*1902Szelenkov@nginx.com pytest.skip('requires root') 17*1902Szelenkov@nginx.com 18*1902Szelenkov@nginx.com os.makedirs(temp_dir + '/assets/dir/mount') 19*1902Szelenkov@nginx.com os.makedirs(temp_dir + '/assets/dir/dir') 20*1902Szelenkov@nginx.com os.makedirs(temp_dir + '/assets/mount') 21*1902Szelenkov@nginx.com Path(temp_dir + '/assets/index.html').write_text('index') 22*1902Szelenkov@nginx.com Path(temp_dir + '/assets/dir/dir/file').write_text('file') 23*1902Szelenkov@nginx.com Path(temp_dir + '/assets/mount/index.html').write_text('mount') 24*1902Szelenkov@nginx.com 25*1902Szelenkov@nginx.com try: 26*1902Szelenkov@nginx.com process = subprocess.Popen( 27*1902Szelenkov@nginx.com [ 28*1902Szelenkov@nginx.com "mount", 29*1902Szelenkov@nginx.com "--bind", 30*1902Szelenkov@nginx.com temp_dir + "/assets/mount", 31*1902Szelenkov@nginx.com temp_dir + "/assets/dir/mount", 32*1902Szelenkov@nginx.com ], 33*1902Szelenkov@nginx.com stderr=subprocess.STDOUT, 34*1902Szelenkov@nginx.com ) 35*1902Szelenkov@nginx.com 36*1902Szelenkov@nginx.com process.communicate() 37*1902Szelenkov@nginx.com 38*1902Szelenkov@nginx.com except KeyboardInterrupt: 39*1902Szelenkov@nginx.com raise 40*1902Szelenkov@nginx.com 41*1902Szelenkov@nginx.com except: 42*1902Szelenkov@nginx.com pytest.fail('Can\'t run mount process.') 43*1902Szelenkov@nginx.com 44*1902Szelenkov@nginx.com self._load_conf( 45*1902Szelenkov@nginx.com { 46*1902Szelenkov@nginx.com "listeners": {"*:7080": {"pass": "routes"}}, 47*1902Szelenkov@nginx.com "routes": [{"action": {"share": temp_dir + "/assets/dir"}}], 48*1902Szelenkov@nginx.com } 49*1902Szelenkov@nginx.com ) 50*1902Szelenkov@nginx.com 51*1902Szelenkov@nginx.com yield 52*1902Szelenkov@nginx.com 53*1902Szelenkov@nginx.com try: 54*1902Szelenkov@nginx.com process = subprocess.Popen( 55*1902Szelenkov@nginx.com ["umount", "--lazy", temp_dir + "/assets/dir/mount"], 56*1902Szelenkov@nginx.com stderr=subprocess.STDOUT, 57*1902Szelenkov@nginx.com ) 58*1902Szelenkov@nginx.com 59*1902Szelenkov@nginx.com process.communicate() 60*1902Szelenkov@nginx.com 61*1902Szelenkov@nginx.com except KeyboardInterrupt: 62*1902Szelenkov@nginx.com raise 63*1902Szelenkov@nginx.com 64*1902Szelenkov@nginx.com except: 65*1902Szelenkov@nginx.com pytest.fail('Can\'t run umount process.') 66*1902Szelenkov@nginx.com 67*1902Szelenkov@nginx.com def test_static_mount(self, temp_dir, skip_alert): 68*1902Szelenkov@nginx.com skip_alert(r'opening.*failed') 69*1902Szelenkov@nginx.com 70*1902Szelenkov@nginx.com resp = self.get(url='/mount/') 71*1902Szelenkov@nginx.com assert resp['status'] == 200 72*1902Szelenkov@nginx.com assert resp['body'] == 'mount' 73*1902Szelenkov@nginx.com 74*1902Szelenkov@nginx.com assert 'success' in self.conf( 75*1902Szelenkov@nginx.com {"share": temp_dir + "/assets/dir", "traverse_mounts": False}, 76*1902Szelenkov@nginx.com 'routes/0/action', 77*1902Szelenkov@nginx.com ), 'configure mount disable' 78*1902Szelenkov@nginx.com 79*1902Szelenkov@nginx.com assert self.get(url='/mount/')['status'] == 403 80*1902Szelenkov@nginx.com 81*1902Szelenkov@nginx.com assert 'success' in self.conf( 82*1902Szelenkov@nginx.com {"share": temp_dir + "/assets/dir", "traverse_mounts": True}, 83*1902Szelenkov@nginx.com 'routes/0/action', 84*1902Szelenkov@nginx.com ), 'configure mount enable' 85*1902Szelenkov@nginx.com 86*1902Szelenkov@nginx.com resp = self.get(url='/mount/') 87*1902Szelenkov@nginx.com assert resp['status'] == 200 88*1902Szelenkov@nginx.com assert resp['body'] == 'mount' 89*1902Szelenkov@nginx.com 90*1902Szelenkov@nginx.com def test_static_mount_two_blocks(self, temp_dir, skip_alert): 91*1902Szelenkov@nginx.com skip_alert(r'opening.*failed') 92*1902Szelenkov@nginx.com 93*1902Szelenkov@nginx.com os.symlink(temp_dir + '/assets/dir', temp_dir + '/assets/link') 94*1902Szelenkov@nginx.com 95*1902Szelenkov@nginx.com assert 'success' in self.conf( 96*1902Szelenkov@nginx.com [ 97*1902Szelenkov@nginx.com { 98*1902Szelenkov@nginx.com "match": {"method": "HEAD"}, 99*1902Szelenkov@nginx.com "action": { 100*1902Szelenkov@nginx.com "share": temp_dir + "/assets/dir", 101*1902Szelenkov@nginx.com "traverse_mounts": False, 102*1902Szelenkov@nginx.com }, 103*1902Szelenkov@nginx.com }, 104*1902Szelenkov@nginx.com { 105*1902Szelenkov@nginx.com "match": {"method": "GET"}, 106*1902Szelenkov@nginx.com "action": { 107*1902Szelenkov@nginx.com "share": temp_dir + "/assets/dir", 108*1902Szelenkov@nginx.com "traverse_mounts": True, 109*1902Szelenkov@nginx.com }, 110*1902Szelenkov@nginx.com }, 111*1902Szelenkov@nginx.com ], 112*1902Szelenkov@nginx.com 'routes', 113*1902Szelenkov@nginx.com ), 'configure two options' 114*1902Szelenkov@nginx.com 115*1902Szelenkov@nginx.com assert self.get(url='/mount/')['status'] == 200, 'block enabled' 116*1902Szelenkov@nginx.com assert self.head(url='/mount/')['status'] == 403, 'block disabled' 117*1902Szelenkov@nginx.com 118*1902Szelenkov@nginx.com def test_static_mount_chroot(self, temp_dir, skip_alert): 119*1902Szelenkov@nginx.com skip_alert(r'opening.*failed') 120*1902Szelenkov@nginx.com 121*1902Szelenkov@nginx.com assert 'success' in self.conf( 122*1902Szelenkov@nginx.com { 123*1902Szelenkov@nginx.com "share": temp_dir + "/assets/dir", 124*1902Szelenkov@nginx.com "chroot": temp_dir + "/assets", 125*1902Szelenkov@nginx.com }, 126*1902Szelenkov@nginx.com 'routes/0/action', 127*1902Szelenkov@nginx.com ), 'configure chroot mount default' 128*1902Szelenkov@nginx.com 129*1902Szelenkov@nginx.com assert self.get(url='/mount/')['status'] == 200, 'chroot' 130*1902Szelenkov@nginx.com 131*1902Szelenkov@nginx.com assert 'success' in self.conf( 132*1902Szelenkov@nginx.com { 133*1902Szelenkov@nginx.com "share": temp_dir + "/assets/dir", 134*1902Szelenkov@nginx.com "chroot": temp_dir + "/assets", 135*1902Szelenkov@nginx.com "traverse_mounts": False, 136*1902Szelenkov@nginx.com }, 137*1902Szelenkov@nginx.com 'routes/0/action', 138*1902Szelenkov@nginx.com ), 'configure chroot mount disable' 139*1902Szelenkov@nginx.com 140*1902Szelenkov@nginx.com assert self.get(url='/mount/')['status'] == 403, 'chroot mount' 141