/** * Copyright 2013-2015 Seagate Technology LLC. * * This Source Code Form is subject to the terms of the Mozilla * Public License, v. 2.0. If a copy of the MPL was not * distributed with this file, You can obtain one at * https://mozilla.org/MP:/2.0/. * * This program is distributed in the hope that it will be useful, * but is provided AS-IS, WITHOUT ANY WARRANTY; including without * the implied warranty of MERCHANTABILITY, NON-INFRINGEMENT or * FITNESS FOR A PARTICULAR PURPOSE. See the Mozilla Public * License for more details. * * See www.openkinetic.org for more project information */ package com.seagate.kinetic.simulator.client.p2p; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertTrue; import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; import java.util.logging.Logger; import kinetic.admin.KineticAdminClient; import kinetic.admin.KineticAdminClientFactory; import kinetic.client.Entry; import kinetic.client.KineticException; import kinetic.client.p2p.KineticP2pClient; import kinetic.client.p2p.Operation; import kinetic.client.p2p.Peer; import kinetic.client.p2p.PeerToPeerOperation; import org.testng.AssertJUnit; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.google.common.base.Charsets; import com.seagate.kinetic.AbstractIntegrationTestTarget; import com.seagate.kinetic.IntegrationTestCase; import com.seagate.kinetic.IntegrationTestTargetFactory; import com.seagate.kinetic.proto.Kinetic.Command.Status.StatusCode; /** * P2P operation test. * <p/> * This test case also serves as an example for P2P API usage. * * @author Chiaming Yang */ @Test(groups = { "simulator" }) public class PeerToPeerOperationTest extends IntegrationTestCase { Logger logger = Logger.getLogger(PeerToPeerOperationTest.class.getName()); private AbstractIntegrationTestTarget secondaryTestTarget; private KineticP2pClient secondaryClient; @BeforeMethod public void setUp() throws Exception { secondaryTestTarget = IntegrationTestTargetFactory .createAlternateTestTarget(); KineticAdminClient adminClient = KineticAdminClientFactory .createInstance(secondaryTestTarget.getAdminClientConfig()); adminClient.instantErase(null); adminClient.close(); secondaryClient = secondaryTestTarget.createKineticClient(); } @AfterMethod public void tearDown() throws Exception { secondaryClient.close(); secondaryTestTarget.shutdown(); } @Test(dataProvider = "transportProtocolOptions") public void testP2PPut_WorksOverPlainConnection(String clientName) throws Exception { byte[] key = "an awesome key!".getBytes(Charsets.UTF_8); byte[] value = "an awesome value!".getBytes(Charsets.UTF_8); Entry entry = new Entry(key, value); getClient(clientName).putForced(entry); PeerToPeerOperation p2p = new PeerToPeerOperation(); p2p.setPeer(secondaryTestTarget.getPeer()); Operation op = new Operation(); op.setKey(key); op.setForced(true); p2p.addOperation(op); PeerToPeerOperation p2pResp = getClient(clientName).PeerToPeerPush(p2p); assertTrue(p2pResp.getStatus()); Entry peerEntry = secondaryClient.get(key); assertArrayEquals(value, peerEntry.getValue()); logger.info("validated peer to peer works over plain TCP ..."); } @Test(dataProvider = "transportProtocolOptions") public void testP2PPut_WorksOverTlsConnection(String clientName) throws Exception { byte[] key = "an awesome key!".getBytes(Charsets.UTF_8); byte[] value = "an awesome value!".getBytes(Charsets.UTF_8); Entry entry = new Entry(key, value); getClient(clientName).putForced(entry); PeerToPeerOperation p2p = new PeerToPeerOperation(); p2p.setPeer(secondaryTestTarget.getTlsPeer()); Operation op = new Operation(); op.setKey(key); op.setForced(true); p2p.addOperation(op); PeerToPeerOperation p2pResp = getClient(clientName).PeerToPeerPush(p2p); assertTrue(p2pResp.getStatus()); Entry peerEntry = secondaryClient.get(key); assertArrayEquals(value, peerEntry.getValue()); logger.info("validated peer to peer works over SSL ..."); } @Test(dataProvider = "transportProtocolOptions") public void testP2PPut_Fails_ForVersionMismatch(String clientName) throws Exception { byte[] key = "an awesome key!".getBytes(Charsets.UTF_8); byte[] value = "an awesome value!".getBytes(Charsets.UTF_8); Entry entry = new Entry(key, value); getClient(clientName).putForced(entry); PeerToPeerOperation p2p = new PeerToPeerOperation(); p2p.setPeer(secondaryTestTarget.getTlsPeer()); Operation op = new Operation(); op.setKey(key); op.setVersion(key); p2p.addOperation(op); PeerToPeerOperation p2pResp = getClient(clientName).PeerToPeerPush(p2p); // expect overall status to be false due to version mismatch assertFalse(p2pResp.getStatus()); // expect response op status to set to false assertFalse(p2pResp.getOperationList().get(0).getStatus()); // expect version mis-match due to the version specified does not exist assertTrue("expect version mis-match status code", StatusCode.VERSION_MISMATCH == p2pResp.getOperationList() .get(0).getStatusCode()); logger.info("received expect version mis-match status code: " + StatusCode.VERSION_MISMATCH); } @Test(dataProvider = "transportProtocolOptions") public void testP2PPut_Fails_ForInvalidPeer(String clientName) throws Exception { PeerToPeerOperation p2pop = new PeerToPeerOperation(); Peer peer = new Peer(); peer.setHost("localhost"); peer.setPort(1); p2pop.setPeer(peer); Operation op = new Operation(); op.setKey("foo".getBytes(Charsets.UTF_8)); p2pop.addOperation(op); // the client should surface connection errors in a machine-readable way try { getClient(clientName).PeerToPeerPush(p2pop); AssertJUnit.fail("Should have thrown KineticException"); } catch (KineticException e) { // expected exception should be caught here. logger.info("caught expected exception: " + e.getMessage()); ; } } }