text: #!/usr/bin/env python
  #
  # Public Domain 2014-2017 MongoDB, Inc.
  # Public Domain 2008-2014 WiredTiger, Inc.
  #
  # This is free and unencumbered software released into the public domain.
  #
  # Anyone is free to copy, modify, publish, use, compile, sell, or
  # distribute this software, either in source code form or as a compiled
  # binary, for any purpose, commercial or non-commercial, and by any
  # means.
  #
  # In jurisdictions that recognize copyright laws, the author or authors
  # of this software dedicate any and all copyright interest in the
  # software to the public domain. We make this dedication for the benefit
  # of the public at large and to the detriment of our heirs and
  # successors. We intend this dedication to be an overt act of
  # relinquishment in perpetuity of all present and future rights to this
  # software under copyright law.
  #
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  # IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  # OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  # OTHER DEALINGS IN THE SOFTWARE.
  
  import wiredtiger, wttest, exceptions
  
  # test_autoclose
  class test_autoclose(wttest.WiredTigerTestCase):
      """
      Check that when closed handles are used, there is a catchable
      error thrown, and that when a handle is closed, any subordinate
      handles are also closed.
      """
      uri = 'table:test_autoclose'
  
      def create_table(self):
          self.session.create(self.uri,
                              'key_format=S,value_format=S')
  
      def drop_table(self):
          self.session.drop(self.uri, None)
  
      def open_cursor(self):
          cursor = self.session.open_cursor(self.uri, None, None)
          return cursor
  
      def test_close_cursor1(self):
          """
          Use a cursor handle after it is explicitly closed.
          """
          self.create_table()
  
          inscursor = self.open_cursor()
          inscursor['key1'] = 'value1'
          inscursor.close()
          self.assertRaisesHavingMessage(exceptions.RuntimeError,
                                         lambda: inscursor.next(),
                                         '/wt_cursor.* is None/')
          self.drop_table()
          self.close_conn()
  
      def test_close_cursor2(self):
          """
          Use a cursor handle after its session is closed.
          """
          self.create_table()
  
          inscursor = self.open_cursor()
          inscursor['key1'] = 'value1'
          self.session.close()
          self.assertRaisesHavingMessage(exceptions.RuntimeError,
                                         lambda: inscursor.next(),
                                         '/wt_cursor.* is None/')
          self.close_conn()
  
      def test_close_cursor3(self):
          """
          Use a cursor handle after the connection is closed.
          """
          self.create_table()
  
          inscursor = self.open_cursor()
          inscursor['key1'] = 'value1'
          self.close_conn()
          self.assertRaisesHavingMessage(exceptions.RuntimeError,
                                         lambda: inscursor.next(),
                                         '/wt_cursor.* is None/')
  
      def test_close_cursor4(self):
          """
          The truncate call allows both of its cursor args
          to be null, so we don't expect null checking.
          """
          self.create_table()
          inscursor = self.open_cursor()
          inscursor['key1'] = 'value1'
          inscursor.set_key('key1')
          inscursor2 = self.session.open_cursor(None, inscursor, None)
          self.session.truncate(None, inscursor, inscursor2, '')
          inscursor.close()
          inscursor2.close()
          self.session.truncate(self.uri, None, None, '')
  
      def test_close_cursor5(self):
          """
          Test Cursor.compare() which should not allow a null cursor arg.
          """
          self.create_table()
  
          inscursor = self.open_cursor()
          inscursor['key1'] = 'value1'
          inscursor.set_key('key1')
          inscursor2 = self.session.open_cursor(None, inscursor, None)
          inscursor.compare(inscursor2)
  
          # Note: SWIG generates a TypeError in this case.
          # A RuntimeError to match the other cases would be better.
          inscursor2.close()
          self.assertRaises(exceptions.TypeError,
                            lambda: inscursor.compare(inscursor2))
  
          inscursor2 = None
          self.assertRaisesHavingMessage(exceptions.RuntimeError,
                                         lambda: inscursor.compare(inscursor2),
                                         '/wt_cursor.* is None/')
  
      def test_close_session1(self):
          """
          Use a session handle after it is explicitly closed.
          """
          self.session.close()
          self.assertRaisesHavingMessage(exceptions.RuntimeError,
                                         lambda: self.create_table(),
                                         '/wt_session.* is None/')
          self.close_conn()
  
      def test_close_session2(self):
          """
          Use a session handle after the connection is closed.
          """
          self.close_conn()
          self.assertRaisesHavingMessage(exceptions.RuntimeError,
                                         lambda: self.create_table(),
                                         '/wt_session.* is None/')
  
      def test_close_connection1(self):
          """
          Use a connection handle after it is closed.
          """
          conn = self.conn
          self.close_conn()
          self.assertRaisesHavingMessage(exceptions.RuntimeError,
                                         lambda: conn.open_session(None),
                                         '/wt_connection.* is None/')
  
  if __name__ == '__main__':
      wttest.run()
  