code: def test_remove_listener(self):
      # SPARK-38804: Test StreamingQueryManager.removeListener
      # V1: Initial interface of StreamingQueryListener containing methods `onQueryStarted`,
      # `onQueryProgress`, `onQueryTerminated`. It is prior to Spark 3.5.
      class TestListenerV1(StreamingQueryListener):
          def onQueryStarted(self, event):
              pass
  
          def onQueryProgress(self, event):
              pass
  
          def onQueryTerminated(self, event):
              pass
  
      # V2: The interface after the method `onQueryIdle` is added. It is Spark 3.5+.
      class TestListenerV2(StreamingQueryListener):
          def onQueryStarted(self, event):
              pass
  
          def onQueryProgress(self, event):
              pass
  
          def onQueryIdle(self, event):
              pass
  
          def onQueryTerminated(self, event):
              pass
  
      def verify(test_listener):
          num_listeners = len(self.spark.streams._jsqm.listListeners())
          self.spark.streams.addListener(test_listener)
          self.assertEqual(
              num_listeners + 1,
              len(self.spark.streams._jsqm.listListeners()),
          )
          self.spark.streams.removeListener(test_listener)
          self.assertEqual(
              num_listeners,
              len(self.spark.streams._jsqm.listListeners()),
          )
  
      verify(TestListenerV1())
      verify(TestListenerV2())
  
imports: import json
  import time
  import uuid
  from datetime import datetime
  from pyspark import Row
  from pyspark.sql.streaming import StreamingQueryListener
  from pyspark.sql.streaming.listener import QueryStartedEvent, QueryProgressEvent, QueryTerminatedEvent, SinkProgress, SourceProgress, StateOperatorProgress, StreamingQueryProgress
  from pyspark.testing.sqlutils import ReusedSQLTestCase
label_desc: Use image node_id 3 for calling the StreamingListenerTests obj's underlying member method code with example usage: obj.test_remove_listener() without return types