blob: 30ba831366555efbe5fe7d7a9b0282bbb6d05041 [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.geode.management.internal.cli.commands;
import static org.apache.geode.management.internal.i18n.CliStrings.IMPORT_SHARED_CONFIG;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Collections;
import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.apache.geode.distributed.DistributedMember;
import org.apache.geode.distributed.internal.InternalConfigurationPersistenceService;
import org.apache.geode.management.internal.cli.GfshParseResult;
import org.apache.geode.management.internal.configuration.domain.Configuration;
import org.apache.geode.test.junit.rules.GfshParserRule;
public class ImportClusterConfigurationCommandTest {
@ClassRule
public static GfshParserRule gfsh = new GfshParserRule();
@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
private ImportClusterConfigurationCommand command;
private File xmlFile;
private InternalConfigurationPersistenceService ccService;
private String commandWithFile;
private Configuration configuration;
@Before
public void setUp() throws Exception {
command = spy(ImportClusterConfigurationCommand.class);
ccService = mock(InternalConfigurationPersistenceService.class);
xmlFile = tempFolder.newFile("my.xml");
commandWithFile = IMPORT_SHARED_CONFIG + " --xml-file=" + xmlFile.getAbsolutePath() + " ";
doReturn(true).when(command).isSharedConfigurationRunning();
doReturn(ccService).when(command).getConfigurationPersistenceService();
doNothing().when(command).backupTheOldConfig(ccService);
doReturn(Collections.emptySet()).when(command).findMembers(any());
doReturn(xmlFile).when(command).getUploadedFile();
configuration = new Configuration("group");
}
@Test
public void autoComplete() {
GfshParserRule.CommandCandidate commandCandidate =
gfsh.complete(IMPORT_SHARED_CONFIG + " --action=");
assertThat(commandCandidate.getCandidates()).hasSize(2);
assertThat(commandCandidate.getFirstCandidate())
.isEqualTo(IMPORT_SHARED_CONFIG + " --action=APPLY");
}
@Test
public void mandatory() {
gfsh.executeAndAssertThat(command, IMPORT_SHARED_CONFIG).statusIsError()
.containsOutput("Either a zip file or a xml file is required");
gfsh.executeAndAssertThat(command, IMPORT_SHARED_CONFIG + " --xml-file=''").statusIsError()
.containsOutput("Either a zip file or a xml file is required");
}
@Test
public void defaultValue() {
GfshParseResult parseResult = gfsh.parse(IMPORT_SHARED_CONFIG + " --xml-file=my.xml");
assertThat(parseResult.getParamValue("group")).isEqualTo("cluster");
assertThat(parseResult.getParamValue("xml-file")).isEqualTo("my.xml");
assertThat(parseResult.getParamValue("action").toString()).isEqualTo("APPLY");
parseResult = gfsh.parse(IMPORT_SHARED_CONFIG + " --group=''");
assertThat(parseResult.getParamValue("group")).isEqualTo("cluster");
}
@Test
public void preValidation() {
gfsh.executeAndAssertThat(command, IMPORT_SHARED_CONFIG + " --xml-file=abc").statusIsError()
.containsOutput("Invalid file type");
gfsh.executeAndAssertThat(command, IMPORT_SHARED_CONFIG + " --zip-file-name=b.zip")
.statusIsError().containsOutput("'b.zip' not found");
gfsh.executeAndAssertThat(command, IMPORT_SHARED_CONFIG + " --xml-file=a.xml").statusIsError()
.containsOutput("'a.xml' not found");
gfsh.executeAndAssertThat(command, commandWithFile + " --group='group1,group2'").statusIsError()
.containsOutput("Only a single group name is supported");
gfsh.executeAndAssertThat(command,
IMPORT_SHARED_CONFIG + " --zip-file-name=b.zip --group=group1").statusIsError()
.containsOutput("zip file can not be imported with a specific group");
gfsh.executeAndAssertThat(command, IMPORT_SHARED_CONFIG + " --zip-file-name=b.zip")
.statusIsError().containsOutput("'b.zip' not found");
gfsh.executeAndAssertThat(command, IMPORT_SHARED_CONFIG + " --xml-file=a.xml").statusIsError()
.containsOutput("'a.xml' not found");
gfsh.executeAndAssertThat(command, commandWithFile + " --zip-file-name=b.zip").statusIsError()
.containsOutput("Zip file and xml File can't both be specified");
gfsh.executeAndAssertThat(command,
IMPORT_SHARED_CONFIG + " --zip-file-name=b.zip --group=group1").statusIsError()
.containsOutput("zip file can not be imported with a specific group");
}
@Test
public void clusterConfigurationNotRunning() {
doReturn(false).when(command).isSharedConfigurationRunning();
gfsh.executeAndAssertThat(command, commandWithFile).statusIsError()
.containsOutput("Cluster configuration service is not running");
}
@Test
public void noMemberFound() throws IOException {
String xmlContent = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><cache/>";
FileUtils.write(xmlFile, xmlContent, Charset.defaultCharset());
when(ccService.getConfiguration(any())).thenReturn(configuration);
gfsh.executeAndAssertThat(command, commandWithFile).statusIsSuccess()
.containsOutput("Successfully set the 'cluster' configuration to the content of");
assertThat(configuration.getCacheXmlContent()).isEqualTo(xmlContent);
}
@Test
public void invalidXml() throws IOException {
String xmlContent =
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?><cache><region></cache>";
FileUtils.write(xmlFile, xmlContent, Charset.defaultCharset());
when(ccService.getConfiguration(any())).thenReturn(configuration);
gfsh.executeAndAssertThat(command, commandWithFile).statusIsError()
.containsOutput("Error while processing command ");
}
@Test
public void existingMembersWithoutStaging() {
doReturn(Collections.singleton(mock(DistributedMember.class))).when(command).findMembers(any());
when(ccService.hasXmlConfiguration()).thenReturn(true);
gfsh.executeAndAssertThat(command, commandWithFile).statusIsError()
.containsOutput("Can not configure servers that are already configured");
}
@Test
public void existingMembersWithBounce() {
doReturn(Collections.singleton(mock(DistributedMember.class))).when(command).findMembers(any());
when(ccService.hasXmlConfiguration()).thenReturn(true);
gfsh.executeAndAssertThat(command, commandWithFile + "--action=APPLY").statusIsError()
.containsOutput("Can not configure servers that are already configured");
}
@Test
public void existingMembersWithIgnore() {
doReturn(Collections.singleton(mock(DistributedMember.class))).when(command).findMembers(any());
when(ccService.getConfiguration(any())).thenReturn(configuration);
gfsh.executeAndAssertThat(command, commandWithFile + "--action=STAGE").statusIsSuccess()
.containsOutput("Successfully set the 'cluster' configuration to the content of")
.containsOutput("Existing servers are not affected with this configuration change");
}
}