/** * Constructs a {@link Setting} with a specified default value. * * @param name of the setting, e.g. "dbms.transaction.timeout". * @param parser that will convert the string representation to the concrete type T. * @param defaultValue the string representation of the default value. * @param <T> the concrete type of the setting. */ @Nonnull public static <T> Setting<T> setting( @Nonnull final String name, @Nonnull final Function<String,T> parser, @Nullable final String defaultValue ) { return new SettingBuilder<>( name, parser, defaultValue ).build(); }
@Test void testPaths() { File directory = new File( "myDirectory" ); Setting<File> config = buildSetting( "config", PATH, new File( directory, "config.properties" ).getAbsolutePath() ).constraint( isFile ).build(); assertThat( config.apply( map( stringMap() ) ).getAbsolutePath(), equalTo( new File( directory, "config.properties" ).getAbsolutePath() ) ); }
@Test void testInheritOneLevel() { Setting<Integer> root = setting( "root", INTEGER, "4" ); Setting<Integer> setting = buildSetting( "foo", INTEGER ).inherits( root ).build(); // Ok assertThat( setting.apply( map( stringMap( "foo", "1" ) ) ), equalTo( 1 ) ); assertThat( setting.apply( map( stringMap() ) ), equalTo( 4 ) ); }
long memory = buildSetting( ARG_MEMORY, BYTES ).build().apply( arguments::get ); String os = bytesToString( recommendOsMemory( memory ) ); String heap = bytesToString( recommendHeapMemory( memory ) );
/** * Start building a setting with a specified default value. * * @param name of the setting, e.g. "dbms.transaction.timeout". * @param parser that will convert the string representation to the concrete type T. * @param defaultValue the string representation of the default value. * @param <T> the concrete type of the setting. */ @Nonnull public static <T> SettingBuilder<T> buildSetting( @Nonnull final String name, @Nonnull final Function<String,T> parser, @Nullable final String defaultValue ) { return new SettingBuilder<>( name, parser, defaultValue ); }
/** * Constructs a {@link Setting} with a specified default value. * * @param name of the setting, e.g. "dbms.transaction.timeout". * @param parser that will convert the string representation to the concrete type T. * @param defaultValue the string representation of the default value. * @param <T> the concrete type of the setting. */ @Nonnull public static <T> Setting<T> setting( @Nonnull final String name, @Nonnull final Function<String,T> parser, @Nullable final String defaultValue ) { return new SettingBuilder<>( name, parser, defaultValue ).build(); }
long memory = buildSetting( ARG_MEMORY, BYTES ).build().apply( arguments::get ); String os = bytesToString( recommendOsMemory( memory ) ); String heap = bytesToString( recommendHeapMemory( memory ) );
@Test void testInheritHierarchy() { // Test hierarchies Setting<String> a = setting( "A", STRING, "A" ); // A defaults to A Setting<String> b = buildSetting( "B", STRING, "B" ).inherits( a ).build(); // B defaults to B unless A is defined Setting<String> c = buildSetting( "C", STRING, "C" ).inherits( b ).build(); // C defaults to C unless B is defined Setting<String> d = buildSetting( "D", STRING ).inherits( b ).build(); // D defaults to B Setting<String> e = buildSetting( "E", STRING ).inherits( d ).build(); // E defaults to D (hence B) assertThat( c.apply( map( stringMap( "C", "X" ) ) ), equalTo( "X" ) ); assertThat( c.apply( map( stringMap( "B", "X" ) ) ), equalTo( "X" ) ); assertThat( c.apply( map( stringMap( "A", "X" ) ) ), equalTo( "X" ) ); assertThat( c.apply( map( stringMap( "A", "Y", "B", "X" ) ) ), equalTo( "X" ) ); assertThat( d.apply( map( stringMap() ) ), equalTo( "B" ) ); assertThat( e.apply( map( stringMap() ) ), equalTo( "B" ) ); }
/** * Start building a setting with a specified default value. * * @param name of the setting, e.g. "dbms.transaction.timeout". * @param parser that will convert the string representation to the concrete type T. * @param defaultValue the string representation of the default value. * @param <T> the concrete type of the setting. */ @Nonnull public static <T> SettingBuilder<T> buildSetting( @Nonnull final String name, @Nonnull final Function<String,T> parser, @Nullable final String defaultValue ) { return new SettingBuilder<>( name, parser, defaultValue ); }
@Test void badDurationInvalidUnit() { Setting<Duration> setting = buildSetting( "foo.bar", DURATION ).build(); InvalidSettingException exception = assertThrows( InvalidSettingException.class, () -> setting.apply( map( stringMap( "foo.bar", "2gigaseconds" ) ) ) ); assertThat( exception.getMessage(), containsString( "Unrecognized unit 'gigaseconds'" ) ); }
@Test void badDurationMissingNumber() { Setting<Duration> setting = buildSetting( "foo.bar", DURATION ).build(); InvalidSettingException exception = assertThrows( InvalidSettingException.class, () -> setting.apply( map( stringMap( "foo.bar", "ms" ) ) ) ); assertThat( exception.getMessage(), containsString( "Missing numeric value" ) ); }
@Test void testMatches() { Setting<String> setting = buildSetting( "foo", STRING, "abc" ).constraint( matches( "a*b*c*" ) ).build(); // Ok assertThat( setting.apply( map( stringMap( "foo", "aaabbbccc" ) ) ), equalTo( "aaabbbccc" ) ); // Bad assertThrows( InvalidSettingException.class, () -> setting.apply( map( stringMap( "foo", "cba" ) ) ) ); }
@Test void testRange() { Setting<Integer> setting = buildSetting( "foo", INTEGER, "3" ).constraint( range( 2, 5 ) ).build(); // Ok assertThat( setting.apply( map( stringMap( "foo", "4" ) ) ), equalTo( 4 ) ); // Bad assertThrows( InvalidSettingException.class, () -> setting.apply( map( stringMap( "foo", "1" ) ) ) ); assertThrows( InvalidSettingException.class, () -> setting.apply( map( stringMap( "foo", "6" ) ) ) ); }
@Test void testDurationWithBrokenDefault() { // Notice that the default value is less that the minimum Setting<Duration> setting = buildSetting( "foo.bar", DURATION, "1s" ).constraint( min( DURATION.apply( "3s" ) ) ).build(); assertThrows( InvalidSettingException.class, () -> setting.apply( map( stringMap() ) ) ); }
@Test void testMax() { Setting<Integer> setting = buildSetting( "foo", INTEGER, "3" ).constraint( max( 5 ) ).build(); // Ok assertThat( setting.apply( map( stringMap( "foo", "4" ) ) ), equalTo( 4 ) ); // Bad assertThrows( InvalidSettingException.class, () -> setting.apply( map( stringMap( "foo", "7" ) ) ) ); }
@Test void exceptDoesNotAllowForbiddenValues() { Setting<String> restrictedSetting = buildSetting( "foo", STRING, "test" ).constraint( except( "a", "b", "c" ) ).build(); assertEquals( "test", restrictedSetting.apply( map( stringMap() ) ) ); assertEquals( "d", restrictedSetting.apply( map( stringMap( "foo", "d" ) ) ) ); assertThrows( InvalidSettingException.class, () -> restrictedSetting.apply( map( stringMap( "foo", "a" ) ) ) ); assertThrows( InvalidSettingException.class, () -> restrictedSetting.apply( map( stringMap( "foo", "b" ) ) ) ); InvalidSettingException exception = assertThrows( InvalidSettingException.class, () -> restrictedSetting.apply( map( stringMap( "foo", "c" ) ) ) ); assertThat( exception.getMessage(), containsString( "not allowed value is: c" ) ); }
@Test void testDurationWithValueNotWithinConstraint() { Setting<Duration> setting = buildSetting( "foo.bar", DURATION, "3s" ).constraint( min( DURATION.apply( "3s" ) ) ).build(); assertThrows( InvalidSettingException.class, () -> setting.apply( map( stringMap( "foo.bar", "2s" ) ) ) ); }
@Test void testDuration() { Setting<Duration> setting = buildSetting( "foo.bar", DURATION, "3s").constraint( min( DURATION.apply( "3s" ) ) ).build(); assertThat( setting.apply( map( stringMap( "foo.bar", "4s" ) ) ), equalTo( Duration.ofSeconds( 4 ) ) ); }
@Test void testMin() { Setting<Integer> setting = buildSetting( "foo", INTEGER, "3" ).constraint( min( 2 ) ).build(); // Ok assertThat( setting.apply( map( stringMap( "foo", "4" ) ) ), equalTo( 4 ) ); // Bad assertThrows( InvalidSettingException.class, () -> setting.apply( map( stringMap( "foo", "1" ) ) ) ); }