@@ -441,6 +441,7 @@ mod tests {
441441 use std:: { collections:: HashMap , sync:: Arc } ;
442442
443443 use spin_factors:: RuntimeFactors ;
444+ use spin_factors_test:: TestEnvironment ;
444445
445446 use super :: * ;
446447
@@ -458,10 +459,13 @@ mod tests {
458459 Self :: from_source( value)
459460 }
460461 }
461- fn resolve_toml( toml: toml:: Table ) -> ResolvedRuntimeConfig <TestFactorsRuntimeConfig > {
462+ fn resolve_toml(
463+ toml: toml:: Table ,
464+ path: impl AsRef <std:: path:: Path >,
465+ ) -> ResolvedRuntimeConfig <TestFactorsRuntimeConfig > {
462466 ResolvedRuntimeConfig :: <TestFactorsRuntimeConfig >:: new(
463467 toml_resolver( & toml) ,
464- None ,
468+ Some ( path . as_ref ( ) ) ,
465469 false ,
466470 )
467471 . unwrap( )
@@ -500,13 +504,13 @@ mod tests {
500504 type = "spin"
501505 } ;
502506 assert_eq ! (
503- resolve_toml( toml) . runtime_config. configured_labels( ) ,
507+ resolve_toml( toml, "." ) . runtime_config. configured_labels( ) ,
504508 vec![ "default" , "foo" ]
505509 ) ;
506510
507511 // Test that the default label is added with an empty toml config.
508512 let toml = toml:: Table :: new ( ) ;
509- let runtime_config = resolve_toml ( toml) . runtime_config ;
513+ let runtime_config = resolve_toml ( toml, "config.toml" ) . runtime_config ;
510514 assert_eq ! ( runtime_config. configured_labels( ) , vec![ "default" ] ) ;
511515 }
512516
@@ -525,10 +529,59 @@ mod tests {
525529 [ key_value_store. foo]
526530 type = "spin"
527531 } ;
528- let runtime_config = resolve_toml ( toml) . runtime_config ;
532+ let runtime_config = resolve_toml ( toml, "config.toml" ) . runtime_config ;
529533 assert ! ( [ "default" , "foo" ]
530534 . iter( )
531- . all( |label| { runtime_config. has_store_manager( label) } ) ) ;
535+ . all( |label| runtime_config. has_store_manager( label) ) ) ;
536+ }
537+
538+ #[ tokio:: test( flavor = "multi_thread" , worker_threads = 1 ) ]
539+ async fn custom_spin_key_value_works_with_custom_paths ( ) -> anyhow:: Result < ( ) > {
540+ use spin_world:: v2:: key_value:: HostStore ;
541+ define_test_factor ! ( key_value: KeyValueFactor ) ;
542+ let tmp_dir = tempfile:: TempDir :: with_prefix ( "example" ) ?;
543+ let absolute_path = tmp_dir. path ( ) . join ( "foo/custom.db" ) ;
544+ let relative_path = tmp_dir. path ( ) . join ( "custom.db" ) ;
545+ // Check that the dbs do not exist yet - they will exist by the end of the test
546+ assert ! ( !absolute_path. exists( ) ) ;
547+ assert ! ( !relative_path. exists( ) ) ;
548+
549+ let path_str = absolute_path. to_str ( ) . unwrap ( ) ;
550+ let runtime_config = toml:: toml! {
551+ [ key_value_store. absolute]
552+ type = "spin"
553+ path = path_str
554+
555+ [ key_value_store. relative]
556+ type = "spin"
557+ path = "custom.db"
558+ } ;
559+ let factors = TestFactors {
560+ key_value : KeyValueFactor :: new ( ) ,
561+ } ;
562+ let env = TestEnvironment :: new ( factors)
563+ . extend_manifest ( toml:: toml! {
564+ [ component. test-component]
565+ source = "does-not-exist.wasm"
566+ key_value_stores = [ "absolute" , "relative" ]
567+ } )
568+ . runtime_config (
569+ resolve_toml ( runtime_config, tmp_dir. path ( ) . join ( "runtime-config.toml" ) )
570+ . runtime_config ,
571+ ) ?;
572+ let mut state = env. build_instance_state ( ) . await ?;
573+
574+ // Actually get a key since store creation is lazy
575+ let store = state. key_value . open ( "absolute" . to_owned ( ) ) . await ??;
576+ let _ = state. key_value . get ( store, "foo" . to_owned ( ) ) . await ??;
577+
578+ let store = state. key_value . open ( "relative" . to_owned ( ) ) . await ??;
579+ let _ = state. key_value . get ( store, "foo" . to_owned ( ) ) . await ??;
580+
581+ // Check that the dbs have been created
582+ assert ! ( absolute_path. exists( ) ) ;
583+ assert ! ( relative_path. exists( ) ) ;
584+ Ok ( ( ) )
532585 }
533586
534587 fn toml_resolver ( toml : & toml:: Table ) -> TomlResolver < ' _ > {
0 commit comments