entry.py 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #!/usr/bin/env python3
  2. import os
  3. import sys
  4. import time
  5. import flexitest
  6. import rpc
  7. class ServerFactory(flexitest.Factory):
  8. def __init__(self, port_range: list[int]):
  9. super().__init__(port_range)
  10. def create_server(self, name: str) -> flexitest.Service:
  11. raise NotImplementedError()
  12. class ProcServerFactory(ServerFactory):
  13. def __init__(self, port_range: list[int]):
  14. super().__init__(port_range)
  15. @flexitest.with_ectx("ectx")
  16. def create_server(self, name: str, ectx: flexitest.EnvContext) -> flexitest.Service:
  17. rpc_port = self.next_port()
  18. rpc_url = "ws://localhost:%s" % rpc_port
  19. p2p_port = self.next_port()
  20. dd = ectx.make_service_dir(name)
  21. sqlite_url = "sqlite://" + os.path.realpath(os.path.join(dd, "db.sqlite")) + "?mode=rwc"
  22. sled_path = os.path.join(dd, "sled")
  23. logfile_path = os.path.join(dd, "service.log")
  24. cmd = ["aspect-homeserver", "-d", sqlite_url, "-s", sled_path, "-r", str(rpc_port), "-p", str(p2p_port)]
  25. props = {
  26. "rpc_port": rpc_port,
  27. "rpc_url": rpc_url,
  28. "p2p_port": p2p_port,
  29. "p2p_addr": "127.0.0.1:%s" % p2p_port,
  30. "logfile": logfile_path
  31. }
  32. svc = flexitest.service.ProcService(props, cmd, stdout=logfile_path)
  33. _inject_rpc(svc)
  34. return svc
  35. class ClientFactory(flexitest.Factory):
  36. def __init__(self, port_range: list[int]):
  37. super().__init__(port_range)
  38. def create_client(self, name: str) -> flexitest.Service:
  39. raise NotImplementedError()
  40. class ProcClientFactory(ClientFactory):
  41. def __init__(self, port_range: list[int]):
  42. super().__init__(port_range)
  43. @flexitest.with_ectx("ectx")
  44. def create_client(self, name: str, ectx: flexitest.EnvContext) -> flexitest.Service:
  45. rpc_port = self.next_port()
  46. rpc_url = "ws://localhost:%s" % rpc_port
  47. dd = ectx.make_service_dir(name)
  48. sqlite_url = "sqlite://" + os.path.realpath(os.path.join(dd, "db.sqlite")) + "?mode=rwc"
  49. logfile_path = os.path.join(dd, "service.log")
  50. cmd = ["aspect-user", "-d", dd, "-u", sqlite_url, "-r", str(rpc_port)]
  51. props = {
  52. "rpc_port": rpc_port,
  53. "rpc_url": rpc_url,
  54. "logfile": logfile_path
  55. }
  56. svc = flexitest.service.ProcService(props, cmd, stdout=logfile_path)
  57. _inject_rpc(svc)
  58. return svc
  59. class BareEnvConfig(flexitest.EnvConfig):
  60. """Environment that just inits some number of clients and servers."""
  61. def __init__(self, nserv, nclients):
  62. self.num_servers = nserv
  63. self.num_clients = nclients
  64. def init(self, ectx: flexitest.EnvContext) -> flexitest.LiveEnv:
  65. sfac = ectx.get_factory("server")
  66. cfac = ectx.get_factory("client")
  67. svcs = {}
  68. for i in range(self.num_servers):
  69. name = "serv%s" % i
  70. svc = sfac.create_server(name)
  71. svcs[name] = svc
  72. svc.start()
  73. for i in range(self.num_clients):
  74. name = "client%s" % i
  75. svc = cfac.create_client(name)
  76. svcs[name] = svc
  77. svc.start()
  78. time.sleep(1)
  79. return flexitest.LiveEnv(svcs)
  80. class SimpleEnvConfig(flexitest.EnvConfig):
  81. """
  82. Environment that creates a single server and some number of clients that are
  83. all connected and registered to it.
  84. """
  85. def __init__(self, nclients):
  86. self.num_clients = nclients
  87. def init(self, ectx: flexitest.EnvContext) -> flexitest.LiveEnv:
  88. sfac = ectx.get_factory("server")
  89. cfac = ectx.get_factory("client")
  90. svcs = {}
  91. s = sfac.create_server("serv")
  92. svcs["serv"] = s
  93. serv_addr = s.get_prop("p2p_addr")
  94. time.sleep(1)
  95. for i in range(self.num_clients):
  96. name = "cli%s" % i
  97. print("creating client", name)
  98. c = cfac.create_client(name)
  99. c.start()
  100. time.sleep(1)
  101. svcs[name] = c
  102. crpc = c.create_rpc()
  103. crpc.aspc_register(serv_addr, name, name)
  104. return flexitest.LiveEnv(svcs)
  105. def _inject_rpc(svc: flexitest.Service):
  106. def _create_rpc():
  107. return rpc.RpcClient(svc.get_prop("rpc_url"))
  108. setattr(svc, "create_rpc", _create_rpc)
  109. def main(argv):
  110. test_dir = os.path.dirname(os.path.abspath(__file__))
  111. # Create datadir.
  112. datadir_root = flexitest.create_datadir_in_workspace(os.path.join(test_dir, "_dd"))
  113. # Probe tests.
  114. modules = flexitest.runtime.scan_dir_for_modules(test_dir)
  115. tests = flexitest.runtime.load_candidate_modules(modules)
  116. print(tests)
  117. # Init factors to be able to create the test envs with.
  118. sfac = ProcServerFactory([12300 + i for i in range(20)])
  119. cfac = ProcClientFactory([12400 + i for i in range(20)])
  120. factories = {"server": sfac, "client": cfac}
  121. # Prepare env configs.
  122. bare_env = BareEnvConfig(1, 2)
  123. basic_env = SimpleEnvConfig(1)
  124. basic2_env = SimpleEnvConfig(2)
  125. env_configs = {"bare": bare_env, "basic": basic_env, "basic2": basic2_env}
  126. # Set up the runtime and prepare tests.
  127. rt = flexitest.TestRuntime(env_configs, datadir_root, factories)
  128. rt.prepare_registered_tests()
  129. # Run the tests and then dump the results.
  130. arg_test_names = argv[1:]
  131. if len(arg_test_names) > 0:
  132. tests = arg_test_names
  133. results = rt.run_tests(tests)
  134. rt.save_json_file("results.json", results)
  135. flexitest.dump_results(results)
  136. flexitest.fail_on_error(results)
  137. return 0
  138. if __name__ == "__main__":
  139. sys.exit(main(sys.argv))