feature_settings.py raw

   1  #!/usr/bin/env python3
   2  # Copyright (c) 2017-2021 The Limenka developers
   3  # Distributed under the MIT software license, see the accompanying
   4  # file COPYING or http://www.opensource.org/licenses/mit-license.php.
   5  """Test various command line arguments and configuration file parameters."""
   6  
   7  import json
   8  
   9  
  10  from test_framework.test_framework import LimenkaTestFramework
  11  from test_framework.test_node import ErrorMatch
  12  from test_framework.util import assert_equal
  13  
  14  
  15  class SettingsTest(LimenkaTestFramework):
  16      def add_options(self, parser):
  17          self.add_wallet_options(parser)
  18  
  19      def set_test_params(self):
  20          self.setup_clean_chain = True
  21          self.num_nodes = 1
  22          self.wallet_names = []
  23  
  24      def test_wallet_settings(self, settings_path):
  25          if not self.is_wallet_compiled():
  26              return
  27  
  28          self.log.info("Testing wallet settings..")
  29          node = self.nodes[0]
  30          # Create wallet to use it during tests
  31          self.start_node(0)
  32          node.createwallet(wallet_name='w1')
  33          self.stop_node(0)
  34  
  35          # Verify wallet settings can only be strings. Either names or paths. Not booleans, nums nor anything else.
  36          for wallets_data in [[10], [True], [[]], [{}], ["w1", 10], ["w1", False]]:
  37              with settings_path.open("w") as fp:
  38                  json.dump({"wallet": wallets_data}, fp)
  39              node.assert_start_raises_init_error(expected_msg="Error: Invalid value detected for '-wallet' or '-nowallet'. '-wallet' requires a string value, while '-nowallet' accepts only '1' to disable all wallets",
  40                                                  extra_args=[f'-settings={settings_path}'])
  41  
  42      def run_test(self):
  43          node, = self.nodes
  44          settings = node.chain_path / "settings.json"
  45          conf = node.datadir_path / "limenka.conf"
  46  
  47          # Assert default settings file was created
  48          self.stop_node(0)
  49          default_settings = {"_warning_": f"This file is automatically generated and updated by {self.config['environment']['CLIENT_NAME']}. Please do not edit this file while the node is running, as any changes might be ignored or overwritten."}
  50          with settings.open() as fp:
  51              assert_equal(json.load(fp), default_settings)
  52  
  53          # Assert settings are parsed and logged
  54          with settings.open("w") as fp:
  55              json.dump({"string": "string", "num": 5, "bool": True, "null": None, "list": [6, 7]}, fp)
  56          with node.assert_debug_log(expected_msgs=[
  57                  'Ignoring unknown rw_settings value bool',
  58                  'Ignoring unknown rw_settings value list',
  59                  'Ignoring unknown rw_settings value null',
  60                  'Ignoring unknown rw_settings value num',
  61                  'Ignoring unknown rw_settings value string',
  62                  'Setting file arg: string = "string"',
  63                  'Setting file arg: num = 5',
  64                  'Setting file arg: bool = true',
  65                  'Setting file arg: null = null',
  66                  'Setting file arg: list = [6,7]',
  67          ]):
  68              self.start_node(0)
  69              self.stop_node(0)
  70  
  71          # Assert settings are unchanged after shutdown
  72          with settings.open() as fp:
  73              assert_equal(json.load(fp), {**default_settings, **{"string": "string", "num": 5, "bool": True, "null": None, "list": [6, 7]}})
  74  
  75          # Test invalid json
  76          with settings.open("w") as fp:
  77              fp.write("invalid json")
  78          node.assert_start_raises_init_error(expected_msg='does not contain valid JSON. This is probably caused by disk corruption or a crash', match=ErrorMatch.PARTIAL_REGEX)
  79  
  80          # Test invalid json object
  81          with settings.open("w") as fp:
  82              fp.write('"string"')
  83          node.assert_start_raises_init_error(expected_msg='Found non-object value "string" in settings file', match=ErrorMatch.PARTIAL_REGEX)
  84  
  85          # Test invalid settings file containing duplicate keys
  86          with settings.open("w") as fp:
  87              fp.write('{"key": 1, "key": 2}')
  88          node.assert_start_raises_init_error(expected_msg='Found duplicate key key in settings file', match=ErrorMatch.PARTIAL_REGEX)
  89  
  90          # Test invalid settings file is ignored with command line -nosettings
  91          with node.assert_debug_log(expected_msgs=['Command-line arg: settings=false']):
  92              self.start_node(0, extra_args=["-nosettings"])
  93              self.stop_node(0)
  94  
  95          # Test invalid settings file is ignored with config file -nosettings
  96          with conf.open('a') as conf:
  97              conf.write('nosettings=1\n')
  98          with node.assert_debug_log(expected_msgs=['Config file arg: [regtest] settings=false']):
  99              self.start_node(0)
 100              self.stop_node(0)
 101  
 102          # Test alternate settings path
 103          altsettings = node.datadir_path / "altsettings.json"
 104          with altsettings.open("w") as fp:
 105              fp.write('{"key": "value"}')
 106          with node.assert_debug_log(expected_msgs=['Setting file arg: key = "value"']):
 107              self.start_node(0, extra_args=[f"-settings={altsettings}"])
 108              self.stop_node(0)
 109  
 110          self.test_wallet_settings(settings)
 111  
 112  
 113  if __name__ == '__main__':
 114      SettingsTest(__file__).main()
 115