blob: 341a0e83ecee31a8d93f496e52ef6727c8e6c048 [file] [log] [blame]
/*
* 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.
*/
package org.apache.cassandra.config;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;
import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Test;
import static org.apache.cassandra.config.CassandraRelevantProperties.ALLOW_DUPLICATE_CONFIG_KEYS;
import static org.apache.cassandra.config.CassandraRelevantProperties.ALLOW_NEW_OLD_CONFIG_KEYS;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class FailStartupDuplicateParamsTest
{
private static final List<String> baseConfig = ImmutableList.of(
"cluster_name: Test Cluster",
"commitlog_sync: batch",
"commitlog_directory: build/test/cassandra/commitlog",
"hints_directory: build/test/cassandra/hints",
"partitioner: org.apache.cassandra.dht.ByteOrderedPartitioner",
"saved_caches_directory: build/test/cassandra/saved_caches",
"data_file_directories:",
" - build/test/cassandra/data",
"seed_provider:" ,
" - class_name: org.apache.cassandra.locator.SimpleSeedProvider",
"parameters:",
" - seeds: \"127.0.0.1:7012\"",
"endpoint_snitch: org.apache.cassandra.locator.SimpleSnitch");
@Before
public void before()
{
ALLOW_DUPLICATE_CONFIG_KEYS.setBoolean(true);
ALLOW_NEW_OLD_CONFIG_KEYS.setBoolean(false);
}
@Test
public void testDuplicateParamThrows() throws IOException
{
ALLOW_DUPLICATE_CONFIG_KEYS.setBoolean(false);
testYaml("found duplicate key endpoint_snitch", true,
"endpoint_snitch: org.apache.cassandra.locator.RackInferringSnitch");
}
@Test
public void testReplacementDupesOldFirst() throws IOException
{
testYaml("[enable_user_defined_functions -> user_defined_functions_enabled]", true,
"enable_user_defined_functions: true",
"user_defined_functions_enabled: false");
testYaml("[enable_user_defined_functions -> user_defined_functions_enabled]", true,
"enable_user_defined_functions: true",
"user_defined_functions_enabled: true");
}
@Test
public void testReplacementDupesNewFirst() throws IOException
{
testYaml("[enable_user_defined_functions -> user_defined_functions_enabled]", true,
"user_defined_functions_enabled: false",
"enable_user_defined_functions: true");
}
@Test
public void testReplacementDupesMultiReplace() throws IOException
{
/*
@Replaces(oldName = "internode_socket_send_buffer_size_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
@Replaces(oldName = "internode_send_buff_size_in_bytes", converter = Converters.BYTES_DATASTORAGE, deprecated = true)
public DataStorageSpec internode_socket_send_buffer_size = new DataStorageSpec("0B");
*/
Predicate<String> predicate = (s) -> s.contains("[internode_send_buff_size_in_bytes -> internode_socket_send_buffer_size]") &&
s.contains("[internode_socket_send_buffer_size_in_bytes -> internode_socket_send_buffer_size]");
String message = " does not contain both [internode_send_buff_size_in_bytes] and [internode_socket_send_buffer_size_in_bytes]";
testYaml(predicate, true,
message,
"internode_send_buff_size_in_bytes: 3",
"internode_socket_send_buffer_size_in_bytes: 2",
"internode_socket_send_buffer_size: 5B");
// and new first:
testYaml(predicate, true,
message,
"internode_socket_send_buffer_size: 5B",
"internode_socket_send_buffer_size_in_bytes: 2",
"internode_send_buff_size_in_bytes: 3");
}
private static void testYaml(String expected, boolean expectFailure, String ... toAdd) throws IOException
{
testYaml((s) -> s.contains(expected), expectFailure, "does not contain [" + expected + ']', toAdd);
}
private static void testYaml(Predicate<String> exceptionMsgPredicate, boolean expectFailure, String message, String ... toAdd) throws IOException
{
Path p = Files.createTempFile("config_dupes",".yaml");
try
{
List<String> lines = new ArrayList<>(baseConfig);
Collections.addAll(lines, toAdd);
Files.write(p, lines);
loadConfig(p.toUri().toURL(), message, exceptionMsgPredicate, expectFailure);
}
finally
{
Files.delete(p);
}
}
private static void loadConfig(URL config, String message, Predicate<String> exceptionMsgPredicate, boolean expectFailure)
{
try
{
new YamlConfigurationLoader().loadConfig(config);
}
catch (Exception e)
{
assertTrue(expectFailure);
e.printStackTrace(System.out);
Throwable t = e;
do
{
if (exceptionMsgPredicate.test(t.getMessage()))
return;
t = t.getCause();
} while (t != null);
fail("Message\n["+e.getMessage()+ "]\n"+message);
}
assertFalse(expectFailure);
}
}