/*
* 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.distributed.internal.membership.gms.locator;
import org.apache.geode.DataSerializer;
import org.apache.geode.InternalGemFireException;
import org.apache.geode.distributed.Locator;
import org.apache.geode.distributed.internal.*;
import org.apache.geode.distributed.internal.membership.DistributedMembershipListener;
import org.apache.geode.distributed.internal.membership.MemberFactory;
import org.apache.geode.distributed.internal.membership.MembershipManager;
import org.apache.geode.distributed.internal.membership.NetView;
import org.apache.geode.internal.AvailablePortHelper;
import org.apache.geode.internal.net.SocketCreator;
import org.apache.geode.internal.Version;
import org.apache.geode.internal.admin.remote.RemoteTransportConfig;
import org.apache.geode.test.junit.categories.IntegrationTest;
import org.apache.geode.test.junit.categories.MembershipTest;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.util.Properties;
import static org.apache.geode.distributed.ConfigurationProperties.*;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
@Category({IntegrationTest.class, MembershipTest.class})
public class GMSLocatorRecoveryJUnitTest {
File tempStateFile = null;
GMSLocator locator = null;
@Before
public void setUp() throws Exception {
tempStateFile = new File("GMSLocatorJUnitTest_locator.dat");
if (tempStateFile.exists()) {
tempStateFile.delete();
}
locator = new GMSLocator(null, tempStateFile, null, false, false, new LocatorStats(), "");
// System.out.println("temp state file: " + tempStateFile);
}
@After
public void tearDown() throws Exception {
if (tempStateFile.exists()) {
tempStateFile.delete();
}
}
private void populateStateFile(File file, int fileStamp, int ordinal, Object object)
throws Exception {
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file))) {
oos.writeInt(fileStamp);
oos.writeInt(ordinal);
DataSerializer.writeObject(object, oos);
oos.flush();
}
}
@Test
public void testRecoverFromFileWithNonExistFile() throws Exception {
tempStateFile.delete();
assertFalse(tempStateFile.exists());
assertFalse(locator.recoverFromFile(tempStateFile));
}
@Test
public void testRecoverFromFileWithNormalFile() throws Exception {
NetView view = new NetView();
populateStateFile(tempStateFile, GMSLocator.LOCATOR_FILE_STAMP, Version.CURRENT_ORDINAL, view);
assertTrue(locator.recoverFromFile(tempStateFile));
}
@Test
public void testRecoverFromFileWithWrongFileStamp() throws Exception {
// add 1 to file stamp to make it invalid
populateStateFile(tempStateFile, GMSLocator.LOCATOR_FILE_STAMP + 1, Version.CURRENT_ORDINAL, 1);
assertFalse(locator.recoverFromFile(tempStateFile));
}
@Test
public void testRecoverFromFileWithWrongOrdinal() throws Exception {
// add 1 to ordinal to make it wrong
populateStateFile(tempStateFile, GMSLocator.LOCATOR_FILE_STAMP, Version.CURRENT_ORDINAL + 1, 1);
try {
locator.recoverFromFile(tempStateFile);
fail("expected an InternalGemFireException to be thrown");
} catch (InternalGemFireException e) {
// success
}
}
@Test
public void testRecoverFromFileWithInvalidViewObject() throws Exception {
populateStateFile(tempStateFile, GMSLocator.LOCATOR_FILE_STAMP, Version.CURRENT_ORDINAL, 1);
try {
locator.recoverFromFile(tempStateFile);
fail("should catch InternalGemFileException");
} catch (InternalGemFireException e) {
assertTrue(e.getMessage().startsWith("Unable to recover previous membership view from"));
}
}
@Test
public void testRecoverFromOther() throws Exception {
MembershipManager m1 = null, m2 = null;
Locator l = null;
try {
// boot up a locator
int port = AvailablePortHelper.getRandomAvailableTCPPort();
InetAddress localHost = SocketCreator.getLocalHost();
// this locator will hook itself up with the first MembershipManager
// to be created
// l = Locator.startLocator(port, new File(""), localHost);
l = InternalLocator.startLocator(port, new File(""), null, null, null, localHost, false,
new Properties(), null);
// create configuration objects
Properties nonDefault = new Properties();
nonDefault.put(DISABLE_TCP, "true");
nonDefault.put(MCAST_PORT, "0");
nonDefault.put(LOG_FILE, "");
nonDefault.put(LOG_LEVEL, "fine");
nonDefault.put(LOCATORS, localHost.getHostAddress() + '[' + port + ']');
nonDefault.put(BIND_ADDRESS, localHost.getHostAddress());
DistributionConfigImpl config = new DistributionConfigImpl(nonDefault);
RemoteTransportConfig transport =
new RemoteTransportConfig(config, DistributionManager.NORMAL_DM_TYPE);
// start the first membership manager
DistributedMembershipListener listener1 = mock(DistributedMembershipListener.class);
DMStats stats1 = mock(DMStats.class);
m1 = MemberFactory.newMembershipManager(listener1, config, transport, stats1);
// hook up the locator to the membership manager
((InternalLocator) l).getLocatorHandler().setMembershipManager(m1);
GMSLocator l2 = new GMSLocator(SocketCreator.getLocalHost(), new File("l2.dat"),
m1.getLocalMember().getHost() + "[" + port + "]", true, true, new LocatorStats(), "");
l2.init(null);
assertTrue("expected view to contain " + m1.getLocalMember() + ": " + l2.getMembers(),
l2.getMembers().contains(m1.getLocalMember()));
} finally {
if (m1 != null) {
m1.shutdown();
}
if (l != null) {
l.stop();
}
}
}
}