Explicitly close files opened by selftest
[mudpy.git] / mudpy / tests / selftest.py
index 86ffe22..b1eb7cf 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (c) 2004-2019 mudpy authors. Permission to use, copy,
+# Copyright (c) 2004-2020 mudpy authors. Permission to use, copy,
 # modify, and distribute this software is granted under terms
 # provided in the LICENSE file distributed with this software.
 
 # modify, and distribute this software is granted under terms
 # provided in the LICENSE file distributed with this software.
 
@@ -143,9 +143,48 @@ test_actor_disappears = (
     (0, r"You suddenly wonder where .* went\.", ""),
 )
 
     (0, r"You suddenly wonder where .* went\.", ""),
 )
 
-test_account1_teardown = (
+test_abort_avatar_deletion = (
     (1, r"What would you like to do\?", "d"),
     (1, r"Whom would you like to delete\?", ""),
     (1, r"What would you like to do\?", "d"),
     (1, r"Whom would you like to delete\?", ""),
+    (1, r"delete an unwanted avatar.*What would you like to do\?", ""),
+)
+
+test_avatar_creation_limit = (
+    (1, r"What would you like to do\?", "c"),
+    (1, "Pick a birth gender for your new avatar:", "m"),
+    (1, "Choose a name for him:", "3"),
+    (1, r"What would you like to do\?", "c"),
+    (1, "Pick a birth gender for your new avatar:", "m"),
+    (1, "Choose a name for him:", "4"),
+    (1, r"What would you like to do\?", "c"),
+    (1, "Pick a birth gender for your new avatar:", "m"),
+    (1, "Choose a name for him:", "7"),
+    (1, r"What would you like to do\?", "c"),
+    (1, "Pick a birth gender for your new avatar:", "m"),
+    (1, "Choose a name for him:", "5"),
+    (1, r"What would you like to do\?", "c"),
+    (1, "Pick a birth gender for your new avatar:", "m"),
+    (1, "Choose a name for him:", "2"),
+    (1, r"What would you like to do\?", "c"),
+    (1, "Pick a birth gender for your new avatar:", "m"),
+    (1, "Choose a name for him:", "6"),
+    (1, r"What would you like to do\?", "c"),
+    (1, r"That is not a valid choice\.\.\.", ""),
+)
+
+test_avatar_deletion = (
+    (1, r"What would you like to do\?", "d"),
+    (1, r"Whom would you like to delete\?", "1"),
+    (1, r"create a new avatar.*What would you like to do\?", ""),
+)
+
+test_abort_account_deletion = (
+    (1, r"What would you like to do\?", "p"),
+    (1, r"permanently delete your account\?", ""),
+    (1, r"What would you like to do\?", ""),
+)
+
+test_account_deletion = (
     (1, r"What would you like to do\?", "p"),
     (1, r"permanently delete your account\?", "y"),
     (1, r"Disconnecting\.\.\.", ""),
     (1, r"What would you like to do\?", "p"),
     (1, r"permanently delete your account\?", "y"),
     (1, r"Disconnecting\.\.\.", ""),
@@ -297,7 +336,7 @@ test_show_result = (
     (2, r"\r\n838102050\r\n.*> ", "show result 1/0"),
     (2, r"Your expression raised an exception.*division by zero.*> ",
      "show result mudpy"),
     (2, r"\r\n838102050\r\n.*> ", "show result 1/0"),
     (2, r"Your expression raised an exception.*division by zero.*> ",
      "show result mudpy"),
-    (2, r"<module 'mudpy' from .*> ", "show result re"),
+    (2, r"<module 'mudpy' from.*> ", "show result re"),
     (2, r"Your expression raised an exception.*name 're' is not defined.*> ",
      "show result universe"),
     (2, r"<mudpy\.misc\.Universe object at 0x.*> ", "show result actor"),
     (2, r"Your expression raised an exception.*name 're' is not defined.*> ",
      "show result universe"),
     (2, r"<mudpy\.misc\.Universe object at 0x.*> ", "show result actor"),
@@ -308,14 +347,14 @@ test_show_result = (
 test_show_log = (
     (2, "> ", "show log"),
     (2, r"There are [0-9]+ log lines in memory and [0-9]+ at or above level "
 test_show_log = (
     (2, "> ", "show log"),
     (2, r"There are [0-9]+ log lines in memory and [0-9]+ at or above level "
-        r"[0-9]+\. The matching lines\r\nfrom [0-9]+ to [0-9]+ are:", ""),
+        r"[0-9]+\. The matching.*from [0-9]+ to [0-9]+ are:", ""),
 )
 
 test_custom_loglevel = (
     (2, "> ", "set account.admin loglevel 2"),
     (2, "You have successfully .*> ", "show log"),
     (2, r"There are [0-9]+ log lines in memory and [0-9]+ at or above level "
 )
 
 test_custom_loglevel = (
     (2, "> ", "set account.admin loglevel 2"),
     (2, "You have successfully .*> ", "show log"),
     (2, r"There are [0-9]+ log lines in memory and [0-9]+ at or above level "
-        r"[0-9]+\. The matching lines\r\nfrom [0-9]+ to [0-9]+ are:", ""),
+        r"[0-9]+\. The matching.*from [0-9]+ to [0-9]+ are:", ""),
 )
 
 test_invalid_loglevel = (
 )
 
 test_invalid_loglevel = (
@@ -330,14 +369,10 @@ test_log_no_errors = (
 
 final_cleanup = (
     (0, "> ", "quit"),
 
 final_cleanup = (
     (0, "> ", "quit"),
-    (0, r"What would you like to do\?", "d"),
-    (0, r"Whom would you like to delete\?", ""),
     (0, r"What would you like to do\?", "p"),
     (0, r"permanently delete your account\?", "y"),
     (0, r"Disconnecting\.\.\.", ""),
     (2, "> ", "quit"),
     (0, r"What would you like to do\?", "p"),
     (0, r"permanently delete your account\?", "y"),
     (0, r"Disconnecting\.\.\.", ""),
     (2, "> ", "quit"),
-    (2, r"What would you like to do\?", "d"),
-    (2, r"Whom would you like to delete\?", ""),
     (2, r"What would you like to do\?", "p"),
     (2, r"permanently delete your account\?", "y"),
     (2, r"Disconnecting\.\.\.", ""),
     (2, r"What would you like to do\?", "p"),
     (2, r"permanently delete your account\?", "y"),
     (2, r"Disconnecting\.\.\.", ""),
@@ -357,7 +392,11 @@ dialogue = (
     (test_escape_macros, "replacement macros are escaped"),
     (test_movement, "movement"),
     (test_actor_disappears, "actor spontaneous disappearance"),
     (test_escape_macros, "replacement macros are escaped"),
     (test_movement, "movement"),
     (test_actor_disappears, "actor spontaneous disappearance"),
-    (test_account1_teardown, "second account teardown"),
+    (test_abort_avatar_deletion, "abort avatar deletion"),
+    (test_avatar_creation_limit, "avatar creation limit"),
+    (test_avatar_deletion, "avatar deletion"),
+    (test_abort_account_deletion, "abort account deletion"),
+    (test_account_deletion, "account deletion"),
     (test_admin_setup, "admin account setup"),
     (test_preferences, "set and show preferences"),
     (test_crlf_eol, "send crlf from the client as eol"),
     (test_admin_setup, "admin account setup"),
     (test_preferences, "set and show preferences"),
     (test_crlf_eol, "send crlf from the client as eol"),
@@ -390,8 +429,8 @@ dialogue = (
 def start_service(config):
     # Clean up any previously run daemon which didn't terminate
     if os.path.exists(pidfile):
 def start_service(config):
     # Clean up any previously run daemon which didn't terminate
     if os.path.exists(pidfile):
-        pidfd = open(pidfile)
-        pid = int(pidfd.read())
+        with open(pidfile) as pidfd:
+            pid = int(pidfd.read())
         try:
             # Stop the running service
             os.kill(pid, 15)
         try:
             # Stop the running service
             os.kill(pid, 15)
@@ -434,8 +473,8 @@ def stop_service(service):
 
     # This cleans up a daemonized and disassociated service
     if os.path.exists(pidfile):
 
     # This cleans up a daemonized and disassociated service
     if os.path.exists(pidfile):
-        pidfd = open(pidfile)
-        pid = int(pidfd.read())
+        with open(pidfile) as pidfd:
+            pid = int(pidfd.read())
         try:
             # Stop the running service
             os.kill(pid, 15)
         try:
             # Stop the running service
             os.kill(pid, 15)
@@ -451,11 +490,11 @@ def stop_service(service):
     # Log the contents of stdout and stderr, if any
     stdout, stderr = service.communicate()
     tlog("\nRecording stdout as capture_stdout.log.")
     # Log the contents of stdout and stderr, if any
     stdout, stderr = service.communicate()
     tlog("\nRecording stdout as capture_stdout.log.")
-    serviceout = open("capture_stdout.log", "w")
-    serviceout.write(stdout.decode("utf-8"))
+    with open("capture_stdout.log", "w") as serviceout:
+        serviceout.write(stdout.decode("utf-8"))
     tlog("\nRecording stderr as capture_stderr.log.")
     tlog("\nRecording stderr as capture_stderr.log.")
-    serviceerr = open("capture_stderr.log", "w")
-    serviceerr.write(stderr.decode("utf-8"))
+    with open("capture_stderr.log", "w") as serviceerr:
+        serviceerr.write(stderr.decode("utf-8"))
 
     return(success)
 
 
     return(success)
 
@@ -489,6 +528,9 @@ def main():
     if len(sys.argv) > 1:
         # Start the service if a config file was provided on the command line
         service = start_service(sys.argv[1])
     if len(sys.argv) > 1:
         # Start the service if a config file was provided on the command line
         service = start_service(sys.argv[1])
+        if not service:
+            tlog("\nERROR: Service did not start.\n")
+            sys.exit(1)
     for luser in lusers:
         luser.open("::1", 4000)
         luser.set_option_negotiation_callback(option_callback)
     for luser in lusers:
         luser.open("::1", 4000)
         luser.set_option_negotiation_callback(option_callback)