github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/acceptancetests/assess_model_change_watcher.py (about)

     1  #!/usr/bin/env python3
     2  
     3  import argparse
     4  import asyncio
     5  import logging
     6  import os
     7  import sys
     8  
     9  from juju.client.connection import Connection
    10  from juju.client import watcher
    11  
    12  from deploy_stack import (
    13      BootstrapManager,
    14      until_timeout,
    15      )
    16  from jujucharm import local_charm_path
    17  from utility import (
    18      add_basic_testing_arguments,
    19      configure_logging,
    20      JujuAssertionError,
    21      )
    22  
    23  
    24  log = logging.getLogger("assess_model_change_watcher")
    25  TOKEN = "1234asdf"
    26  
    27  
    28  def is_config_change_in_event(event):
    29      message = _get_message(event)
    30      return all([
    31          "application" in event,
    32          "change" in event,
    33          is_in_dict("config", {"token": TOKEN}, message),
    34      ])
    35  
    36  
    37  def _get_message(event):
    38      for message in event:
    39          if isinstance(message, dict):
    40              return message
    41      return None
    42  
    43  
    44  def is_in_dict(key, value, items):
    45      return items.get(key) == value
    46  
    47  
    48  async def listen_to_watcher(event_found, conn, future):
    49      logging.info("Starting to listen for the watcher.")
    50      all_watcher = watcher.AllWatcher()
    51      all_watcher.connect(conn)
    52      for _ in until_timeout(120):
    53          logging.info("Listening for events...")
    54          change = await all_watcher.Next()
    55          for delta in change.deltas:
    56              logging.info("Event received: {}".format(str(delta.deltas)))
    57              if event_found(delta.deltas) is True:
    58                  await all_watcher.Stop()
    59                  await conn.close()
    60                  logging.info("Event found: {}".format(str(delta.deltas)))
    61                  future.set_result(True)
    62                  return
    63  
    64      await all_watcher.Stop()
    65      await conn.close()
    66      logging.warning("Event not found.")
    67      future.set_result(False)
    68  
    69  
    70  def run_listener(client, event, juju_bin):
    71      logging.info("Running listener.")
    72      loop = asyncio.get_event_loop()
    73      future = asyncio.Future()
    74  
    75      logging.info("Connect to the current model.")
    76      os.environ['JUJU_DATA'] = client.env.juju_home
    77      os.environ['PATH'] = "{}{}{}".format(
    78          juju_bin, os.pathsep, os.environ.get('PATH', ''))
    79      conn = loop.run_until_complete(Connection.connect_current())
    80      logging.info("Connected to the current model.")
    81  
    82      asyncio.ensure_future(listen_to_watcher(event, conn, future))
    83      return loop, future
    84  
    85  
    86  def assess_model_change_watcher(client, charm_series, juju_bin):
    87      charm = local_charm_path(
    88          charm='dummy-source', juju_ver=client.version, series=charm_series,
    89          platform='ubuntu')
    90      client.deploy(charm)
    91      client.wait_for_started()
    92  
    93      loop, future = run_listener(client, is_config_change_in_event, juju_bin)
    94  
    95      logging.info("Making config change.")
    96      client.set_config('dummy-source', {'token': TOKEN})
    97  
    98      loop.run_until_complete(future)
    99      result = future.result()
   100      if result is not True:
   101          raise JujuAssertionError("Config change event was not sent.")
   102      loop.close()
   103  
   104  
   105  def parse_args(argv):
   106      parser = argparse.ArgumentParser(description="Assess config change.")
   107      add_basic_testing_arguments(parser)
   108      return parser.parse_args(argv)
   109  
   110  
   111  def main(argv=None):
   112      args = parse_args(argv)
   113      configure_logging(args.verbose)
   114      bs_manager = BootstrapManager.from_args(args)
   115      with bs_manager.booted_context(args.upload_tools):
   116          assess_model_change_watcher(
   117              bs_manager.client, bs_manager.series, args.juju_bin)
   118      return 0
   119  
   120  
   121  if __name__ == '__main__':
   122      sys.exit(main())