def test_load_missing(self): config_path = os.path.join(self.colpath, "does_not_exist") config.load([(config_path, True)]) with pytest.raises(Exception) as exc_info: config.load([(config_path, False)]) e = exc_info.value assert "Failed to load config file %r" % config_path in str(e)
def __init__(self, **kwargs): configuration = config.load(extra_config=settings.RADICALE_CONFIG) logger = logging.getLogger("diary") super(DiaryView, self).__init__(configuration, logger) super(View, self).__init__(**kwargs)
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.shutdown_socket, shutdown_socket_out = socket.socketpair() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: # Find available port sock.bind(("127.0.0.1", 0)) self.sockname = sock.getsockname() self.configuration.update( { "storage": { "filesystem_folder": self.colpath }, "server": { "hosts": "[%s]:%d" % self.sockname }, # Enable debugging for new processes "logging": { "level": "debug" }, # Disable syncing to disk for better performance "internal": { "filesystem_fsync": "False" } }, "test", internal=True) self.thread = threading.Thread(target=server.serve, args=(self.configuration, shutdown_socket_out)) ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE self.opener = request.build_opener( request.HTTPSHandler(context=ssl_context), DisabledRedirectHandler)
def test_invalid_option_plugin(self): configuration = config.load() with pytest.raises(Exception) as exc_info: configuration.update({"auth": {"x": "x"}}, "test") e = exc_info.value assert "Invalid option 'x'" in str(e) assert "section 'auth'" in str(e)
def test_plugin_schema_duplicate_option(self): plugin_schema = {"auth": {"type": {"value": "False", "type": bool}}} configuration = config.load() with pytest.raises(Exception) as exc_info: configuration.copy(plugin_schema) e = exc_info.value assert "option already exists in 'auth': 'type'" in str(e)
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.configuration["storage"]["filesystem_folder"] = self.colpath # Disable syncing to disk for better performance self.configuration["internal"]["filesystem_fsync"] = "False" self.application = Application(self.configuration)
def test_copy(self): configuration1 = config.load() configuration1.update({"server": {"max_connections": "1111"}}, "test") configuration2 = configuration1.copy() configuration2.update({"server": {"max_connections": "1112"}}, "test") assert configuration1.get("server", "max_connections") == 1111 assert configuration2.get("server", "max_connections") == 1112
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.configuration.update({ "storage": {"filesystem_folder": self.colpath}, # Disable syncing to disk for better performance "internal": {"filesystem_fsync": "False"}}, "test", internal=True)
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.configuration["storage"]["filesystem_folder"] = self.colpath # Disable syncing to disk for better performance self.configuration["internal"]["filesystem_fsync"] = "False" # Set incorrect authentication delay to a very low value self.configuration["auth"]["delay"] = "0.002"
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.configuration["storage"]["filesystem_folder"] = self.colpath # Disable syncing to disk for better performance self.configuration["storage"]["filesystem_fsync"] = "False" # Required on Windows, doesn't matter on Unix self.configuration["storage"]["filesystem_close_lock_file"] = "True"
def test_plugin_schema_invalid(self): PLUGIN_SCHEMA = {"server": {"new_option": {"value": "False", "type": bool}}} configuration = config.load() with pytest.raises(Exception) as exc_info: configuration.copy(PLUGIN_SCHEMA) e = exc_info.value assert "not a plugin section: 'server" in str(e)
def test_internal(self): configuration = config.load() configuration.update({"internal": {"internal_server": "True"}}, "test", internal=True) with pytest.raises(Exception) as exc_info: configuration.update( {"internal": {"internal_server": "True"}}, "test") e = exc_info.value assert "Invalid section 'internal'" in str(e)
def test_invalid_value(self): configuration = config.load() with pytest.raises(Exception) as exc_info: configuration.update({"server": {"max_connections": "x"}}, "test") e = exc_info.value assert "Invalid positive_int" in str(e) assert "option 'max_connections" in str(e) assert "section 'server" in str(e) assert "'x'" in str(e)
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.configuration.update({ "storage": {"filesystem_folder": self.colpath}, # Disable syncing to disk for better performance "internal": {"filesystem_fsync": "False"}, # Set incorrect authentication delay to a very low value "auth": {"delay": "0.002"}}, "test", internal=True)
def test_load_multiple(self): config_path1 = self._write_config({ "server": {"hosts": "192.0.2.1:1111"}}, "config1") config_path2 = self._write_config({ "server": {"max_connections": 1111}}, "config2") configuration = config.load([(config_path1, False), (config_path2, False)]) assert len(configuration.get("server", "hosts")) == 1 assert configuration.get("server", "hosts")[0] == ("192.0.2.1", 1111) assert configuration.get("server", "max_connections") == 1111
def test_plugin_schema_option_invalid(self): PLUGIN_SCHEMA = {"auth": {}} configuration = config.load() configuration.update({"auth": {"type": "new_plugin", "new_option": False}}, "test") with pytest.raises(Exception) as exc_info: configuration.copy(PLUGIN_SCHEMA) e = exc_info.value assert "Invalid option 'new_option'" in str(e) assert "section 'auth'" in str(e)
def test_plugin_schema(self): PLUGIN_SCHEMA = {"auth": {"new_option": {"value": "False", "type": bool}}} configuration = config.load() configuration.update({"auth": {"type": "new_plugin"}}, "test") plugin_configuration = configuration.copy(PLUGIN_SCHEMA) assert plugin_configuration.get("auth", "new_option") is False configuration.update({"auth": {"new_option": "True"}}, "test") plugin_configuration = configuration.copy(PLUGIN_SCHEMA) assert plugin_configuration.get("auth", "new_option") is True
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.configuration["storage"]["filesystem_folder"] = self.colpath # Disable syncing to disk for better performance self.configuration["storage"]["filesystem_fsync"] = "False" # Required on Windows, doesn't matter on Unix self.configuration["storage"]["filesystem_close_lock_file"] = "True" # Set incorrect authentication delay to a very low value self.configuration["auth"]["delay"] = "0.002"
def setup(self): self.configuration = config.load() self.configuration.set("storage", "type", self.storage_type) self.logger = logging.getLogger("radicale_test") self.colpath = tempfile.mkdtemp() self.configuration.set("storage", "filesystem_folder", self.colpath) # Disable syncing to disk for better performance self.configuration.set("storage", "filesystem_fsync", "False") # Required on Windows, doesn't matter on Unix self.configuration.set("storage", "close_lock_file", "True") self.application = Application(self.configuration, self.logger)
def test_custom(self): """Custom authentication.""" configuration = config.load() configuration.set("auth", "type", "tests.custom.auth") self.application = Application(configuration, logging.getLogger("radicale_test")) status, headers, answer = self.request( "GET", "/", HTTP_AUTHORIZATION="dG1wOmJlcG8=") assert status == 200 assert "Radicale works!" in answer
def test_custom(self): """Custom authentication.""" configuration = config.load() configuration.set("auth", "type", "tests.custom.auth") self.application = Application( configuration, logging.getLogger("radicale_test")) status, headers, answer = self.request( "GET", "/", HTTP_AUTHORIZATION="dG1wOmJlcG8=") assert status in (200, 303) assert "Radicale works!" in answer or "Redirected to .web/" in answer
def __init__(self, **kwargs): # radicale/__main__.py: # configuration = config.load(config_paths, # ignore_missing_paths=ignore_missing_paths) # serve(configuration, logger) configuration = config.load(extra_config=settings.DJRADICALE_CONFIG) logger = logging.getLogger('djradicale') super(DjRadicaleView, self).__init__(configuration, logger) super(View, self).__init__(**kwargs)
def setup(self): self.configuration = config.load() self.configuration.set("storage", "type", self.storage_type) self.logger = logging.getLogger("radicale_test") self.colpath = tempfile.mkdtemp() self.configuration.set("storage", "filesystem_folder", self.colpath) # Disable syncing to disk for better performance self.configuration.set("storage", "fsync", "False") # Required on Windows, doesn't matter on Unix self.configuration.set("storage", "close_lock_file", "True") self.application = Application(self.configuration, self.logger)
def _init_application(config_path): global _application, _application_config_path with _application_lock: if _application is not None: return _application_config_path = config_path configuration = config.load([config_path] if config_path else [], ignore_missing_paths=False) filename = os.path.expanduser(configuration.get("logging", "config")) debug = configuration.getboolean("logging", "debug") logger = log.start("radicale", filename, debug) _application = Application(configuration, logger)
def _init_application(config_path, wsgi_errors): global _application, _application_config_path with _application_lock: if _application is not None: return log.setup() with log.register_stream(wsgi_errors): _application_config_path = config_path configuration = config.load([config_path] if config_path else [], ignore_missing_paths=False) log.set_level(configuration.get("logging", "level")) _application = Application(configuration)
def test_privileged(self): configuration = config.load() configuration.update({"server": { "_internal_server": "True" }}, "test", privileged=True) with pytest.raises(Exception) as exc_info: configuration.update({"server": { "_internal_server": "True" }}, "test") e = exc_info.value assert "Invalid option '_internal_server'" in str(e)
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.configuration.update( { "storage": { "filesystem_folder": self.colpath, # Disable syncing to disk for better performance "_filesystem_fsync": "False" } }, "test", privileged=True) self.application = Application(self.configuration)
def _init_application(config_path, wsgi_errors): global _application, _application_config_path with _application_lock: if _application is not None: return log.setup() with log.register_stream(wsgi_errors): _application_config_path = config_path configuration = config.load( config.parse_compound_paths(config.DEFAULT_CONFIG_PATH, config_path)) log.set_level(configuration.get("logging", "level")) # Inspect configuration after logger is configured configuration.inspect() _application = Application(configuration)
def application(environ, start_response): global _application if _application is None: with _application_lock: if _application is None: config_paths = [] if os.environ.get("RADICALE_CONFIG"): config_paths.append(os.environ["RADICALE_CONFIG"]) configuration = config.load(config_paths, ignore_missing_paths=False) filename = os.path.expanduser(configuration.get("logging", "config")) debug = configuration.getboolean("logging", "debug") logger = log.start("radicale", filename, debug) _application = Application(configuration, logger) return _application(environ, start_response)
def application(environ, start_response): global _application if _application is None: with _application_lock: if _application is None: config_paths = [] if os.environ.get("RADICALE_CONFIG"): config_paths.append(os.environ["RADICALE_CONFIG"]) configuration = config.load(config_paths, ignore_missing_paths=False) filename = os.path.expanduser( configuration.get("logging", "config")) debug = configuration.getboolean("logging", "debug") logger = log.start("radicale", filename, debug) _application = Application(configuration, logger) return _application(environ, start_response)
def _init_application(config_path, wsgi_errors): global _application, _application_config_path with _application_lock: if _application is not None: return log.setup() with log.register_stream(wsgi_errors): _application_config_path = config_path configuration = config.load( config.parse_compound_paths(config.DEFAULT_CONFIG_PATH, config_path)) log.set_level(configuration.get("logging", "level")) # Log configuration after logger is configured for source, miss in configuration.sources(): logger.info("%s %s", "Skipped missing" if miss else "Loaded", source) _application = Application(configuration)
def test_root(self): """Htpasswd authentication.""" htpasswd_file_path = os.path.join(self.colpath, ".htpasswd") with open(htpasswd_file_path, "wb") as fd: fd.write(b"tmp:{SHA}" + base64.b64encode(hashlib.sha1(b"bepo").digest())) configuration = config.load() configuration.set("auth", "type", "htpasswd") configuration.set("auth", "htpasswd_filename", htpasswd_file_path) configuration.set("auth", "htpasswd_encryption", "sha1") self.application = Application(configuration, logging.getLogger("radicale_test")) status, headers, answer = self.request( "GET", "/", HTTP_AUTHORIZATION="dG1wOmJlcG8=") assert status == 200 assert "Radicale works!" in answer
def test_root(self): """Htpasswd authentication.""" htpasswd_file_path = os.path.join(self.colpath, ".htpasswd") with open(htpasswd_file_path, "wb") as fd: fd.write(b"tmp:{SHA}" + base64.b64encode( hashlib.sha1(b"bepo").digest())) configuration = config.load() configuration.set("auth", "type", "htpasswd") configuration.set("auth", "htpasswd_filename", htpasswd_file_path) configuration.set("auth", "htpasswd_encryption", "sha1") self.application = Application( configuration, logging.getLogger("radicale_test")) status, headers, answer = self.request( "GET", "/", HTTP_AUTHORIZATION="dG1wOmJlcG8=") assert status in (200, 303) assert "Radicale works!" in answer or "Redirected to .web/" in answer
def setup(): """Set global logging up.""" global register_stream handler = ThreadedStreamHandler() logging.basicConfig(format=LOGGER_FORMAT, datefmt=DATE_FORMAT, handlers=[handler]) register_stream = handler.register_stream log_record_factory = IdentLogRecordFactory(logging.getLogRecordFactory()) logging.setLogRecordFactory(log_record_factory) """If a logfile is provided, also add a filehandler as logger""" configuration = config.load() logfile = configuration.get("logging", "logfile") if logfile: logfile_handler = logging.FileHandler(logfile, mode="w") logger.addHandler(logfile_handler) logger.info(f"Registered filelogger to {logfile}") set_level(logging.WARNING)
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.configuration["storage"]["filesystem_folder"] = self.colpath # Enable debugging for new processes self.configuration["logging"]["level"] = "debug" # Disable syncing to disk for better performance self.configuration["internal"]["filesystem_fsync"] = "False" self.shutdown_socket, shutdown_socket_out = socket.socketpair() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: # Find available port sock.bind(("127.0.0.1", 0)) self.sockname = sock.getsockname() self.configuration["server"]["hosts"] = "[%s]:%d" % self.sockname self.thread = threading.Thread(target=server.serve, args=( self.configuration, shutdown_socket_out)) ssl_context = ssl.create_default_context() ssl_context.check_hostname = False ssl_context.verify_mode = ssl.CERT_NONE self.opener = request.build_opener( request.HTTPSHandler(context=ssl_context), DisabledRedirectHandler)
def run(): """Run Radicale as a standalone server.""" # Get command-line arguments parser = argparse.ArgumentParser(usage="radicale [OPTIONS]") parser.add_argument("--version", action="version", version=VERSION) parser.add_argument("--verify-storage", action="store_true", help="check the storage for errors and exit") parser.add_argument( "-C", "--config", help="use a specific configuration file") groups = {} for section, values in config.INITIAL_CONFIG.items(): group = parser.add_argument_group(section) groups[group] = [] for option, data in values.items(): kwargs = data.copy() long_name = "--{0}-{1}".format( section, option.replace("_", "-")) args = kwargs.pop("aliases", []) args.append(long_name) kwargs["dest"] = "{0}_{1}".format(section, option) groups[group].append(kwargs["dest"]) del kwargs["value"] if "internal" in kwargs: del kwargs["internal"] if kwargs["type"] == bool: del kwargs["type"] kwargs["action"] = "store_const" kwargs["const"] = "True" opposite_args = kwargs.pop("opposite", []) opposite_args.append("--no{0}".format(long_name[1:])) group.add_argument(*args, **kwargs) kwargs["const"] = "False" kwargs["help"] = "do not {0} (opposite of {1})".format( kwargs["help"], long_name) group.add_argument(*opposite_args, **kwargs) else: group.add_argument(*args, **kwargs) args = parser.parse_args() if args.config is not None: config_paths = [args.config] if args.config else [] ignore_missing_paths = False else: config_paths = ["/etc/radicale/config", os.path.expanduser("~/.config/radicale/config")] if "RADICALE_CONFIG" in os.environ: config_paths.append(os.environ["RADICALE_CONFIG"]) ignore_missing_paths = True try: configuration = config.load(config_paths, ignore_missing_paths=ignore_missing_paths) except Exception as e: print("ERROR: Invalid configuration: %s" % e, file=sys.stderr) if args.logging_debug: raise exit(1) # Update Radicale configuration according to arguments for group, actions in groups.items(): section = group.title for action in actions: value = getattr(args, action) if value is not None: configuration.set(section, action.split('_', 1)[1], value) if args.verify_storage: # Write to stderr when storage verification is requested configuration["logging"]["config"] = "" # Start logging filename = os.path.expanduser(configuration.get("logging", "config")) debug = configuration.getboolean("logging", "debug") try: logger = log.start("radicale", filename, debug) except Exception as e: print("ERROR: Failed to start logger: %s" % e, file=sys.stderr) if debug: raise exit(1) if args.verify_storage: logger.info("Verifying storage") try: Collection = storage.load(configuration, logger) with Collection.acquire_lock("r"): if not Collection.verify(): logger.error("Storage verifcation failed") exit(1) except Exception as e: logger.error("An exception occurred during storage verification: " "%s", e, exc_info=True) exit(1) return try: serve(configuration, logger) except Exception as e: logger.error("An exception occurred during server startup: %s", e, exc_info=True) exit(1)
def setup(self): self.configuration = config.load() self.colpath = tempfile.mkdtemp() self.configuration["storage"]["filesystem_folder"] = self.colpath # Disable syncing to disk for better performance self.configuration["internal"]["filesystem_fsync"] = "False"
test_events = gen_events() def get_col(): return list(app.Collection.discover(environ['PATH_INFO'], '0')) for type in ('multifilesystem', 'radicale_timerange_indexed_storage'): if len(sys.argv) > 2 and type not in sys.argv[2:]: continue shutil.rmtree(collection_folder, True) os.mkdir(collection_folder) app = Application( load(extra_config=dict( storage=dict( type=type, filesystem_folder=collection_folder ))), getLogger('rt')) collections = get_col() app.do_MKCALENDAR(environ, collections, collections, mkcal, None) collections = get_col() t0 = time() app.do_PUT(environ, collections, collections, test_events, None) print('PUT using %s %f' % (type, time() - t0)) def f(y): return y['y'], y['m'], y['d'], y['h']
def setup(self): self.configuration = config.load() self.configuration.set("storage", "type", self.storage_type) self.logger = logging.getLogger("radicale_test")