contrib/python/compare_RecordsConfigcc.py (72 lines of code) (raw):

#!/usr/bin/env python3 # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # import re import sys try: src_dir = sys.argv[1] except IndexError: print(f"Usage: {sys.argv[0]} [trafficserver_source_dir]") print("Compares values in RecordsConfig.cc with the default records.config file") sys.exit(1) # We expect these keys to differ between files, so ignore them ignore_keys = { "proxy.config.ssl.server.cert.path": 1, "proxy.config.admin.user_id": 1, "proxy.config.ssl.client.cert.path": 1, "proxy.config.log.logfile_dir": 1, "proxy.config.ssl.CA.cert.path": 1, "proxy.config.ssl.client.CA.cert.path": 1, "proxy.config.ssl.server.private_key.path": 1, "proxy.config.proxy_name": 1, "proxy.config.ssl.client.private_key.path": 1, "proxy.config.net.defer_accept": 1 # Specified in RecordsConfig.cc funny } rc_cc = {} # RecordsConfig.cc values rc_in = {} # records.config.in values rc_doc = {} # documented values # Process RecordsConfig.cc with open(f"{src_dir}/src/mgmt/RecordsConfig.cc") as fh: cc_re = re.compile(r'\{RECT_(?:CONFIG|LOCAL), "([^"]+)", RECD_([A-Z]+), (.+?), ') for line in fh: m = cc_re.search(line) if m: value = m.group(3) value = value.lstrip('"') value = value.rstrip('"') rc_cc[m.group(1)] = (m.group(2), value) # Process records.config.default.in with open(f"{src_dir}/configs/records.config.default.in") as fh: in_re = re.compile(r'(?:CONFIG|LOCAL) (\S+)\s+(\S+)\s+(\S+)') for line in fh: m = in_re.match(line) if m: rc_in[m.group(1)] = (m.group(2), m.group(3)) # Process records.config documentation. # eg. .. ts:cv:: CONFIG proxy.config.proxy_binary STRING traffic_server with open(f"{src_dir}/doc/admin-guide/files/records.config.en.rst") as fh: doc_re = re.compile(r'ts:cv:: CONFIG (\S+)\s+(\S+)\s+(\S+)') for line in fh: m = doc_re.search(line) if m: rc_doc[m.group(1)] = (m.group(2), m.group(3)) rc_doc[m.group(1)] = (m.group(2), m.group(3)) # Compare the two # If a value is in RecordsConfig.cc and not records.config.default.in, it is # ignored right now. print("# Comparing RecordsConfig.cc -> records.config.default.in") for key in rc_in: if key in ignore_keys: continue if key not in rc_cc: print("%s missing -> %s" % (key, "%s %s" % rc_in[key])) continue if rc_cc[key] != rc_in[key]: print("%s : %s -> %s" % (key, "%s %s" % rc_cc[key], "%s %s" % rc_in[key])) # Search for undocumented variables ... missing = [k for k in rc_cc if k not in rc_doc] if len(missing) > 0: print() print("Undocumented configuration variables:") for m in sorted(missing): print("\t%s %s" % (m, "%s %s" % rc_cc[m])) # Search for incorrectly documented default values ... defaults = [k for k in rc_cc if k in rc_doc and rc_cc[k] != rc_doc[k]] if len(defaults) > 0: print() print("Incorrectly documented defaults:") for d in sorted(defaults): print("\t%s %s -> %s" % (d, "%s %s" % rc_cc[d], "%s %s" % rc_doc[d])) # Search for stale documentation ... stale = [k for k in rc_doc if k not in rc_cc] if (len(stale) > 0): print() print("Stale documentation:") for s in sorted(stale): print(f"\t{s}")