diff --git a/components/config/opts.rs b/components/config/opts.rs index 440062a7b30..a296c6ec8d0 100644 --- a/components/config/opts.rs +++ b/components/config/opts.rs @@ -60,6 +60,9 @@ pub struct Opts { /// Directory for a default config directory pub config_dir: Option, + /// Use temporary storage (data on disk will not persist across restarts). + pub temporary_storage: bool, + /// Path to PEM encoded SSL CA certificate store. pub certificate_path: Option, @@ -222,6 +225,7 @@ impl Default for Opts { sandbox: false, debug: Default::default(), config_dir: None, + temporary_storage: false, shaders_path: None, certificate_path: None, ignore_certificate_errors: false, diff --git a/components/servo/servo.rs b/components/servo/servo.rs index 196f6e08afc..e4a4a1854f6 100644 --- a/components/servo/servo.rs +++ b/components/servo/servo.rs @@ -930,8 +930,11 @@ impl Servo { protocols.clone(), ); - let (private_storage_threads, public_storage_threads) = - new_storage_threads(mem_profiler_chan.clone(), opts.config_dir.clone()); + let (private_storage_threads, public_storage_threads) = new_storage_threads( + mem_profiler_chan.clone(), + opts.config_dir.clone(), + opts.temporary_storage, + ); create_constellation( embedder_to_constellation_receiver, diff --git a/components/storage/client_storage.rs b/components/storage/client_storage.rs index 33525a081a2..1bf2a44ba5c 100644 --- a/components/storage/client_storage.rs +++ b/components/storage/client_storage.rs @@ -642,19 +642,25 @@ impl RegistryEngine for SqliteEngine { } pub trait ClientStorageThreadFactory { - fn new(config_dir: Option) -> Self; + fn new(config_dir: Option, temporary_storage: bool) -> Self; } impl ClientStorageThreadFactory for ClientStorageThreadHandle { - fn new(config_dir: Option) -> ClientStorageThreadHandle { + fn new(config_dir: Option, temporary_storage: bool) -> ClientStorageThreadHandle { let (generic_sender, generic_receiver) = generic_channel::channel().unwrap(); - let storage_dir = config_dir + let base_dir = config_dir .unwrap_or_else(|| { let tmp_dir = tempfile::tempdir().unwrap(); tmp_dir.path().to_path_buf() }) .join("clientstorage"); + let storage_dir = if temporary_storage { + let unique_id = uuid::Uuid::new_v4().to_string(); + base_dir.join("temporary").join(unique_id) + } else { + base_dir.join("default_v1") + }; std::fs::create_dir_all(&storage_dir) .expect("Failed to create ClientStorage storage directory"); let sender_clone = generic_sender.clone(); diff --git a/components/storage/storage_thread.rs b/components/storage/storage_thread.rs index 2df953f8fcb..9fd8ab6a2d5 100644 --- a/components/storage/storage_thread.rs +++ b/components/storage/storage_thread.rs @@ -16,10 +16,11 @@ use crate::{ClientStorageThreadFactory, IndexedDBThreadFactory, WebStorageThread fn new_storage_thread_group( mem_profiler_chan: MemProfilerChan, config_dir: Option, + temporary_storage: bool, label: &str, ) -> StorageThreads { let client_storage: ClientStorageThreadHandle = - ClientStorageThreadFactory::new(config_dir.clone()); + ClientStorageThreadFactory::new(config_dir.clone(), temporary_storage); let idb: GenericSender = IndexedDBThreadFactory::new( config_dir.clone(), mem_profiler_chan.clone(), @@ -37,10 +38,16 @@ fn new_storage_thread_group( pub fn new_storage_threads( mem_profiler_chan: MemProfilerChan, config_dir: Option, + temporary_storage: bool, ) -> (StorageThreads, StorageThreads) { - let private_storage_threads = - new_storage_thread_group(mem_profiler_chan.clone(), config_dir.clone(), "private"); - let public_storage_threads = new_storage_thread_group(mem_profiler_chan, config_dir, "public"); + let private_storage_threads = new_storage_thread_group( + mem_profiler_chan.clone(), + config_dir.clone(), + temporary_storage, + "private", + ); + let public_storage_threads = + new_storage_thread_group(mem_profiler_chan, config_dir, temporary_storage, "public"); (private_storage_threads, public_storage_threads) } diff --git a/components/storage/tests/client_storage.rs b/components/storage/tests/client_storage.rs index 02bb3fe193c..e5575e64fbd 100644 --- a/components/storage/tests/client_storage.rs +++ b/components/storage/tests/client_storage.rs @@ -19,7 +19,11 @@ fn install_test_namespace() { } fn registry_db_path(tmp_dir: &tempfile::TempDir) -> PathBuf { - tmp_dir.path().join("clientstorage").join("reg.sqlite") + tmp_dir + .path() + .join("clientstorage") + .join("default_v1") + .join("reg.sqlite") } fn open_registry(tmp_dir: &tempfile::TempDir) -> Connection { @@ -42,7 +46,7 @@ fn obtain_bottle_map( #[test] fn test_exit() { - let handle: ClientStorageThreadHandle = ClientStorageThreadFactory::new(None); + let handle: ClientStorageThreadHandle = ClientStorageThreadFactory::new(None, false); let (sender, receiver) = generic_channel::channel().unwrap(); handle @@ -60,7 +64,7 @@ fn test_workflow() { install_test_namespace(); let tmp_dir = tempfile::tempdir().unwrap(); let handle: ClientStorageThreadHandle = - ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf())); + ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf()), false); let url = ServoUrl::parse("https://example.com").unwrap(); @@ -124,7 +128,7 @@ fn test_repeated_local_obtain_reuses_same_logical_rows() { install_test_namespace(); let tmp_dir = tempfile::tempdir().unwrap(); let handle: ClientStorageThreadHandle = - ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf())); + ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf()), false); let origin = ServoUrl::parse("https://example.com").unwrap().origin(); let webview = WebViewId::new(servo_base::id::TEST_PAINTER_ID); @@ -179,7 +183,7 @@ fn test_repeated_session_obtain_reuses_same_logical_rows() { install_test_namespace(); let tmp_dir = tempfile::tempdir().unwrap(); let handle: ClientStorageThreadHandle = - ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf())); + ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf()), false); let origin = ServoUrl::parse("https://example.com").unwrap().origin(); let webview = WebViewId::new(servo_base::id::TEST_PAINTER_ID); @@ -235,7 +239,7 @@ fn test_local_persistence_and_estimate() { install_test_namespace(); let tmp_dir = tempfile::tempdir().unwrap(); let handle: ClientStorageThreadHandle = - ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf())); + ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf()), false); let origin = ServoUrl::parse("https://example.com").unwrap().origin(); let webview = WebViewId::new(servo_base::id::TEST_PAINTER_ID); @@ -287,7 +291,7 @@ fn test_storage_manager_operations_fail_for_opaque_origins() { install_test_namespace(); let tmp_dir = tempfile::tempdir().unwrap(); let handle: ClientStorageThreadHandle = - ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf())); + ClientStorageThreadFactory::new(Some(tmp_dir.path().to_path_buf()), false); let origin = ServoUrl::parse("data:text/plain,hello").unwrap().origin(); diff --git a/components/storage/tests/storage_thread.rs b/components/storage/tests/storage_thread.rs index 45369bd4700..65740284ef3 100644 --- a/components/storage/tests/storage_thread.rs +++ b/components/storage/tests/storage_thread.rs @@ -39,7 +39,7 @@ fn shutdown_storage_group(threads: &StorageThreads) { fn test_new_storage_threads_create_independent_groups() { let mem_profiler_chan = profile_mem::Profiler::create(); let (private_storage_threads, public_storage_threads) = - storage::new_storage_threads(mem_profiler_chan, None); + storage::new_storage_threads(mem_profiler_chan, None, false); shutdown_storage_group(&private_storage_threads); shutdown_storage_group(&public_storage_threads); diff --git a/components/storage/tests/webstorage.rs b/components/storage/tests/webstorage.rs index ec4a60f7cd6..5aa35992e11 100644 --- a/components/storage/tests/webstorage.rs +++ b/components/storage/tests/webstorage.rs @@ -22,7 +22,7 @@ impl WebStorageTest { let tmp_dir = tempfile::tempdir().unwrap(); let config_dir = tmp_dir.path().to_path_buf(); let mem_profiler_chan = profile_mem::Profiler::create(); - let threads = storage::new_storage_threads(mem_profiler_chan, Some(config_dir)); + let threads = storage::new_storage_threads(mem_profiler_chan, Some(config_dir), false); Self { tmp_dir: Some(tmp_dir), @@ -32,7 +32,7 @@ impl WebStorageTest { pub(crate) fn new_in_memory() -> Self { let mem_profiler_chan = profile_mem::Profiler::create(); - let threads = storage::new_storage_threads(mem_profiler_chan, None); + let threads = storage::new_storage_threads(mem_profiler_chan, None, false); Self { tmp_dir: None, @@ -44,7 +44,7 @@ impl WebStorageTest { let tmp_dir = self.tmp_dir.take(); let config_dir = tmp_dir.as_ref().map(|d| d.path().to_path_buf()); let mem_profiler_chan = profile_mem::Profiler::create(); - let threads = storage::new_storage_threads(mem_profiler_chan, config_dir); + let threads = storage::new_storage_threads(mem_profiler_chan, config_dir, false); Self { tmp_dir: tmp_dir, diff --git a/ports/servoshell/prefs.rs b/ports/servoshell/prefs.rs index b3633945fe0..d3b26dee50d 100644 --- a/ports/servoshell/prefs.rs +++ b/ports/servoshell/prefs.rs @@ -378,6 +378,10 @@ struct CmdArgs { #[bpaf(argument("~/.config/servo"))] config_dir: Option, + /// Use temporary storage (data on disk will not persist across restarts). + #[bpaf(long)] + temporary_storage: bool, + /// /// Run as a content process and connect to the given pipe. #[bpaf(argument("servo-ipc-channel.abcdefg"))] @@ -634,6 +638,7 @@ fn parse_arguments_helper(args_without_binary: Args) -> ArgumentParsingResult { fs::create_dir_all(config_dir).expect("Could not create config_dir"); } }); + let temporary_storage = cmd_args.temporary_storage; if let Some(ref time_profiler_trace_path) = cmd_args.profiler_trace_path { let mut path = PathBuf::from(time_profiler_trace_path); path.pop(); @@ -706,6 +711,7 @@ fn parse_arguments_helper(args_without_binary: Args) -> ArgumentParsingResult { random_pipeline_closure_probability: cmd_args.random_pipeline_closure_probability, random_pipeline_closure_seed: cmd_args.random_pipeline_closure_seed, config_dir, + temporary_storage, shaders_path: cmd_args.shaders, certificate_path: cmd_args .certificate_path diff --git a/python/wpt/run.py b/python/wpt/run.py index f5463dc6170..c9f5ec5fb94 100644 --- a/python/wpt/run.py +++ b/python/wpt/run.py @@ -136,6 +136,9 @@ def run_tests(default_binary_path: str, multiprocess: bool, **kwargs: Any) -> in with tempfile.TemporaryDirectory(prefix="servo-") as config_dir: kwargs["binary_args"] += ["--config-dir", config_dir] + # Temporary workaround to avoid shared storage across parallel processes. + # Can be removed once per-process config dirs are supported. + kwargs["binary_args"] += ["--temporary-storage"] wptrunner.run_tests(**kwargs)