Package pike :: Package test :: Module persistent
[hide private]
[frames] | no frames]

Source Code for Module pike.test.persistent

  1  # 
  2  # Copyright (c) 2013, EMC Corporation 
  3  # All rights reserved. 
  4  # 
  5  # Redistribution and use in source and binary forms, with or without 
  6  # modification, are permitted provided that the following conditions are met: 
  7  # 
  8  # 1. Redistributions of source code must retain the above copyright notice, 
  9  # this list of conditions and the following disclaimer. 
 10  # 2. Redistributions in binary form must reproduce the above copyright notice, 
 11  # this list of conditions and the following disclaimer in the documentation 
 12  # and/or other materials provided with the distribution. 
 13  # 
 14  # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 15  # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 16  # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 17  # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 
 18  # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 19  # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 20  # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 21  # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 22  # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 23  # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 24  # POSSIBILITY OF SUCH DAMAGE. 
 25  # 
 26  # Module Name: 
 27  # 
 28  #        persistent.py 
 29  # 
 30  # Abstract: 
 31  # 
 32  #        Persistent handle tests 
 33  # 
 34  # Authors: Paul Martin (paul.o.martin@emc.com) 
 35  # 
 36   
 37  import pike.model as model 
 38  import pike.smb2 as smb2 
 39  import pike.test as test 
 40  import pike.ntstatus as ntstatus 
 41  import random 
 42  import array 
 43   
 44  # Constants 
 45  LEASE_R   = smb2.SMB2_LEASE_READ_CACHING 
 46  LEASE_RW  = LEASE_R | smb2.SMB2_LEASE_WRITE_CACHING 
 47  LEASE_RH  = LEASE_R | smb2.SMB2_LEASE_HANDLE_CACHING 
 48  LEASE_RWH = LEASE_RW | LEASE_RH 
 49  SHARE_ALL = smb2.FILE_SHARE_READ | smb2.FILE_SHARE_WRITE | smb2.FILE_SHARE_DELETE 
 50   
 51  @test.RequireDialect(smb2.DIALECT_SMB3_0) 
 52  @test.RequireCapabilities(smb2.SMB2_GLOBAL_CAP_PERSISTENT_HANDLES) 
 53  @test.RequireShareCapabilities(smb2.SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY) 
54 -class Persistent(test.PikeTest):
55 - def setup(self):
56 self.lease_key = array.array('B',map(random.randint, [0]*16, [255]*16)) 57 self.channel, self.tree = self.tree_connect()
58
59 - def create_persistent(self, prev_handle = 0):
60 """Helper to create a persistent handle, optionally reconnecting an old one""" 61 handle = self.channel.create( 62 self.tree, 63 "persistent.txt", 64 access = smb2.FILE_READ_DATA | smb2.FILE_WRITE_DATA | smb2.DELETE, 65 share = SHARE_ALL, 66 disposition = smb2.FILE_OPEN_IF, 67 options = smb2.FILE_DELETE_ON_CLOSE, 68 oplock_level = smb2.SMB2_OPLOCK_LEVEL_LEASE, 69 lease_key = self.lease_key, 70 lease_state = LEASE_RWH, 71 durable = prev_handle, 72 persistent = True 73 ).result() 74 self.assertEqual(handle.durable_flags, smb2.SMB2_DHANDLE_FLAG_PERSISTENT) 75 76 return handle
77 78 # Opening a persistent handle grants persistent flag
79 - def test_create(self):
80 handle = self.create_persistent() 81 82 self.channel.close(handle)
83 84 # Reconnecting a persistent handle after TCP disconnect works and preserves lease
85 - def test_reconnect(self):
86 # Do a persistent open, drop connection, reconnect 87 handle1 = self.create_persistent() 88 self.channel.connection.close() 89 self.channel, self.tree = self.tree_connect() 90 91 handle2 = self.create_persistent(prev_handle = handle1) 92 93 # Was the original lease state granted in the response? 94 self.assertEqual(handle2.lease.lease_state, LEASE_RWH) 95 96 self.channel.close(handle2)
97 98 # Opening a file with a disconnected persistent handle fails with 99 # STATUS_FILE_NOT_AVAILABLE
101 # Do a persistent open, drop connection, reconnect 102 handle1 = self.create_persistent() 103 self.channel.connection.close() 104 self.channel, self.tree = self.tree_connect() 105 106 with self.assert_error(ntstatus.STATUS_FILE_NOT_AVAILABLE): 107 # Perform a failing second open 108 self.channel.create( 109 self.tree, 110 "persistent.txt", 111 access = smb2.FILE_READ_DATA, 112 share = SHARE_ALL, 113 disposition = smb2.FILE_OPEN).result() 114 115 # Clean up: Reconnect and close file (handle) 116 self.channel.connection.close() 117 self.channel, self.tree = self.tree_connect() 118 handle2 = self.create_persistent(prev_handle = handle1) 119 self.channel.close(handle2)
120