diff options
author | 2018-11-30 19:02:00 -0500 | |
---|---|---|
committer | 2019-01-15 18:03:58 -0500 | |
commit | 111c1795a31f3dc619242c1f13fc6f7812779118 (patch) | |
tree | 94053ee484bf4a1f67bb8b3b840c177d05a1fd52 /mdbc-server/src/test/java/org/onap/music | |
parent | bde93d748fd26d3f0447a434b92009aa9f24ba7e (diff) |
Dag, Ownership and Checkpoint (ignore some tests)
Change-Id: Ia720ba45b4f9c8687f5eac5b0d64fd2be19fedaa
Issue-ID: MUSIC-269
Signed-off-by: Enrique Saurez <enrique.saurez@gmail.com>
Diffstat (limited to 'mdbc-server/src/test/java/org/onap/music')
6 files changed, 798 insertions, 97 deletions
diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/MdbcConnectionTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/MdbcConnectionTest.java index 2250b90..6842ed5 100644 --- a/mdbc-server/src/test/java/org/onap/music/mdbc/MdbcConnectionTest.java +++ b/mdbc-server/src/test/java/org/onap/music/mdbc/MdbcConnectionTest.java @@ -20,8 +20,6 @@ package org.onap.music.mdbc; -import static org.junit.Assert.*; - import org.junit.Test; public class MdbcConnectionTest { diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/MySQLMixinTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/MySQLMixinTest.java index 458f70f..5c50b6d 100644 --- a/mdbc-server/src/test/java/org/onap/music/mdbc/MySQLMixinTest.java +++ b/mdbc-server/src/test/java/org/onap/music/mdbc/MySQLMixinTest.java @@ -17,9 +17,10 @@ * limitations under the License. * ============LICENSE_END====================================================== */ + package org.onap.music.mdbc; -import static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; import java.sql.Connection; import java.sql.DriverManager; diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/TestUtils.java b/mdbc-server/src/test/java/org/onap/music/mdbc/TestUtils.java index 85220d4..8c45c2e 100755 --- a/mdbc-server/src/test/java/org/onap/music/mdbc/TestUtils.java +++ b/mdbc-server/src/test/java/org/onap/music/mdbc/TestUtils.java @@ -22,8 +22,12 @@ package org.onap.music.mdbc; import com.datastax.driver.core.*; import com.datastax.driver.core.exceptions.QueryExecutionException; import com.datastax.driver.core.exceptions.SyntaxError; +import org.onap.music.exceptions.MDBCServiceException; +import org.onap.music.exceptions.MusicLockingException; import org.onap.music.lockingservice.cassandra.CassaLockStore; +import org.onap.music.lockingservice.cassandra.MusicLockState; import org.onap.music.logging.EELFLoggerDelegate; +import org.onap.music.main.MusicCore; import org.onap.music.main.MusicUtil; import java.io.FileInputStream; @@ -31,6 +35,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.util.*; +import org.onap.music.mdbc.mixins.MusicInterface; +import org.onap.music.mdbc.tables.MusicRangeInformationRow; import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.fail; @@ -41,6 +47,31 @@ public class TestUtils { private static EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(TestUtils.class); + public static DatabasePartition createBasicRow(Range range, MusicInterface mixin, String mdbcServerName){ + final UUID uuid = MDBCUtils.generateTimebasedUniqueKey(); + List<Range> ranges = new ArrayList<>(); + ranges.add(range); + DatabasePartition dbPartition = new DatabasePartition(ranges,uuid,null); + MusicRangeInformationRow newRow = new MusicRangeInformationRow(uuid,dbPartition, new ArrayList<>(), "", + mdbcServerName, true); + DatabasePartition partition=null; + try { + partition = mixin.createMusicRangeInformation(newRow); + } catch (MDBCServiceException e) { + fail("failure when creating new row"); + } + return partition; + } + + public static void unlockRow(String keyspace, String mriTableName, DatabasePartition partition){ + String fullyQualifiedMriKey = keyspace+"."+ mriTableName+"."+partition.getMRIIndex().toString(); + try { + MusicLockState musicLockState = MusicCore.voluntaryReleaseLock(fullyQualifiedMriKey, partition.getLockId()); + } catch (MusicLockingException e) { + fail("failure when releasing lock"); + } + } + public static void createKeyspace(String keyspace, Session session) { String queryOp = "CREATE KEYSPACE " + keyspace + diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/mixins/MusicMixinTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/mixins/MusicMixinTest.java index e4facc7..0b2bb57 100644 --- a/mdbc-server/src/test/java/org/onap/music/mdbc/mixins/MusicMixinTest.java +++ b/mdbc-server/src/test/java/org/onap/music/mdbc/mixins/MusicMixinTest.java @@ -20,18 +20,19 @@ package org.onap.music.mdbc.mixins; +import static java.util.concurrent.TimeUnit.MILLISECONDS; import static org.junit.Assert.*; import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Session; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; -import java.util.UUID; + +import java.util.*; + import org.cassandraunit.utils.EmbeddedCassandraServerHelper; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; import org.junit.ClassRule; import org.junit.Ignore; @@ -47,7 +48,11 @@ import org.onap.music.lockingservice.cassandra.CassaLockStore; import org.onap.music.lockingservice.cassandra.MusicLockState; import org.onap.music.main.MusicCore; import org.onap.music.mdbc.DatabasePartition; +import org.onap.music.mdbc.MDBCUtils; import org.onap.music.mdbc.Range; +import org.onap.music.mdbc.TestUtils; +import org.onap.music.mdbc.ownership.Dag; +import org.onap.music.mdbc.ownership.DagNode; import org.onap.music.mdbc.tables.MusicRangeInformationRow; import org.onap.music.mdbc.tables.MusicTxDigestId; import org.onap.music.service.impl.MusicCassaCore; @@ -82,6 +87,18 @@ public class MusicMixinTest { MusicDataStoreHandle.mDstoreHandle = new MusicDataStore(cluster, session); CassaLockStore store = new CassaLockStore(MusicDataStoreHandle.mDstoreHandle); assertNotNull("Invalid configuration for music", store); + } + + @AfterClass + public static void close() throws MusicServiceException, MusicQueryException { + //TODO: shutdown cassandra + session.close(); + cluster.close(); + } + + @Before + public void initTest(){ + session.execute("DROP KEYSPACE IF EXISTS "+keyspace); try { Properties properties = new Properties(); properties.setProperty(MusicMixin.KEY_MUSIC_NAMESPACE,keyspace); @@ -90,127 +107,121 @@ public class MusicMixinTest { } catch (MDBCServiceException e) { fail("error creating music mixin"); } - } - @AfterClass - public static void close() throws MusicServiceException, MusicQueryException { - //TODO: shutdown cassandra - session.close(); - cluster.close(); } @Test(timeout=1000) public void own() { - final UUID uuid = mixin.generateUniqueKey(); + Range range = new Range("table1"); List<Range> ranges = new ArrayList<>(); - ranges.add(new Range("table1")); - DatabasePartition dbPartition = new DatabasePartition(ranges,uuid,null); - MusicRangeInformationRow newRow = new MusicRangeInformationRow(dbPartition, new ArrayList<>(), "", mdbcServerName); - DatabasePartition partition=null; - try { - partition = mixin.createMusicRangeInformation(newRow); - } catch (MDBCServiceException e) { - fail("failure when creating new row"); - } - String fullyQualifiedMriKey = keyspace+"."+ mriTableName+"."+partition.getMRIIndex().toString(); - try { - MusicLockState musicLockState = MusicCore.voluntaryReleaseLock(fullyQualifiedMriKey, partition.getLockId()); - } catch (MusicLockingException e) { - fail("failure when releasing lock"); - } - DatabasePartition newPartition = new DatabasePartition(mixin.generateUniqueKey()); + ranges.add(range); + final DatabasePartition partition = TestUtils.createBasicRow(range, mixin, mdbcServerName); + TestUtils.unlockRow(keyspace,mriTableName,partition); + + DatabasePartition currentPartition = new DatabasePartition(MDBCUtils.generateTimebasedUniqueKey()); try { - mixin.own(ranges,newPartition); + mixin.own(ranges,currentPartition, MDBCUtils.generateTimebasedUniqueKey()); } catch (MDBCServiceException e) { fail("failure when running own function"); } } - @Test(timeout=1000) - @Ignore //TODO: Fix this. it is breaking because of previous test^ - public void own2() { - final UUID uuid = mixin.generateUniqueKey(); - final UUID uuid2 = mixin.generateUniqueKey(); - List<Range> ranges = new ArrayList<>(); - List<Range> ranges2 = new ArrayList<>(); - ranges.add(new Range("table2")); - ranges2.add(new Range("table3")); + private DatabasePartition addRow(List<Range> ranges,boolean isLatest){ + final UUID uuid = MDBCUtils.generateTimebasedUniqueKey(); DatabasePartition dbPartition = new DatabasePartition(ranges,uuid,null); - DatabasePartition dbPartition2 = new DatabasePartition(ranges2,uuid2,null); - MusicRangeInformationRow newRow = new MusicRangeInformationRow(dbPartition, new ArrayList<>(), "", mdbcServerName); - MusicRangeInformationRow newRow2 = new MusicRangeInformationRow(dbPartition2, new ArrayList<>(), "", mdbcServerName); + MusicRangeInformationRow newRow = new MusicRangeInformationRow(uuid,dbPartition, new ArrayList<>(), "", + mdbcServerName, isLatest); DatabasePartition partition=null; - DatabasePartition partition2=null; try { partition = mixin.createMusicRangeInformation(newRow); - partition2 = mixin.createMusicRangeInformation(newRow2); } catch (MDBCServiceException e) { fail("failure when creating new row"); } String fullyQualifiedMriKey = keyspace+"."+ mriTableName+"."+partition.getMRIIndex().toString(); - String fullyQualifiedMriKey2 = keyspace+"."+ mriTableName+"."+partition2.getMRIIndex().toString(); try { MusicLockState musicLockState = MusicCore.voluntaryReleaseLock(fullyQualifiedMriKey, partition.getLockId()); - MusicLockState musicLockState2 = MusicCore.voluntaryReleaseLock(fullyQualifiedMriKey2, partition2.getLockId()); } catch (MusicLockingException e) { fail("failure when releasing lock"); } - DatabasePartition blankPartition = new DatabasePartition(mixin.generateUniqueKey()); - DatabasePartition newPartition=null; + return partition; + } + + @Test(timeout=1000) + public void own2() throws InterruptedException, MDBCServiceException { + List<Range> range12 = new ArrayList<>( Arrays.asList( + new Range("range1"), + new Range("range2") + )); + List<Range> range34 = new ArrayList<>( Arrays.asList( + new Range("range3"), + new Range("range4") + )); + List<Range> range24 = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range4") + )); + List<Range> range123 = new ArrayList<>( Arrays.asList( + new Range("range1"), + new Range("range2"), + new Range("range3") + )); + DatabasePartition db1 = addRow(range12, false); + DatabasePartition db2 = addRow(range34, false); + MILLISECONDS.sleep(10); + DatabasePartition db3 = addRow(range12, true); + DatabasePartition db4 = addRow(range34, true); + MILLISECONDS.sleep(10); + DatabasePartition db5 = addRow(range24, true); + DatabasePartition currentPartition = new DatabasePartition(MDBCUtils.generateTimebasedUniqueKey()); + MusicInterface.OwnershipReturn own = null; try { - List<Range> ownRanges = new ArrayList<>(); - ownRanges.add(new Range("table2")); - ownRanges.add(new Range("table3")); - newPartition = mixin.own(ownRanges, blankPartition); + own = mixin.own(range123, currentPartition, MDBCUtils.generateTimebasedUniqueKey()); } catch (MDBCServiceException e) { fail("failure when running own function"); } - assertEquals(2,newPartition.getOldMRIIds().size()); - assertEquals(newPartition.getLockId(),blankPartition.getLockId()); - assertTrue(newPartition.getOldMRIIds().get(0).equals(partition.getMRIIndex())|| - newPartition.getOldMRIIds().get(1).equals(partition.getMRIIndex())); - assertTrue(newPartition.getOldMRIIds().get(0).equals(partition2.getMRIIndex())|| - newPartition.getOldMRIIds().get(1).equals(partition2.getMRIIndex())); - String finalfullyQualifiedMriKey = keyspace+"."+ mriTableName+"."+blankPartition.getMRIIndex().toString(); - try { - List<String> lockQueue = MusicCassaCore.getLockingServiceHandle().getLockQueue(keyspace, mriTableName, - blankPartition.getMRIIndex().toString()); - assertEquals(1,lockQueue.size()); - assertEquals(lockQueue.get(0),blankPartition.getLockId()); - } catch (MusicServiceException|MusicQueryException|MusicLockingException e) { - fail("failure on getting queue"); - } - MusicRangeInformationRow musicRangeInformation=null; - try { - musicRangeInformation= mixin.getMusicRangeInformation(blankPartition.getMRIIndex()); - } catch (MDBCServiceException e) { - fail("fail to retrieve row"); - } - assertEquals(2,musicRangeInformation.getDBPartition().getSnapshot().size()); - assertEquals(0,musicRangeInformation.getRedoLog().size()); - assertEquals(blankPartition.getLockId(),musicRangeInformation.getOwnerId()); - assertEquals(mdbcServerName,musicRangeInformation.getMetricProcessId()); - List<Range> snapshot = musicRangeInformation.getDBPartition().getSnapshot(); - boolean containsTable1=false; - Range table1Range = new Range("table2"); - for(Range r:snapshot){ - if(r.overlaps(table1Range)){ - containsTable1=true; - break; - } - } - assertTrue(containsTable1); - boolean containsTable2=false; - Range table2Range = new Range("table3"); - for(Range r:snapshot){ - if(r.overlaps(table2Range)){ - containsTable2=true; - break; - } - } - assertTrue(containsTable2); + Dag dag = own.getDag(); + + DagNode node4 = dag.getNode(db4.getMRIIndex()); + assertFalse(node4.hasNotIncomingEdges()); + List<DagNode> outgoingEdges = new ArrayList<>(node4.getOutgoingEdges()); + assertEquals(1,outgoingEdges.size()); + + DagNode missing = outgoingEdges.get(0); + Set<Range> missingRanges = missing.getRangeSet(); + assertEquals(2,missingRanges.size()); + assertTrue(missingRanges.contains(new Range("range1"))); + assertTrue(missingRanges.contains(new Range("range3"))); + List<DagNode> outgoingEdges1 = missing.getOutgoingEdges(); + assertEquals(1,outgoingEdges1.size()); + + DagNode finalNode = outgoingEdges1.get(0); + assertFalse(finalNode.hasNotIncomingEdges()); + Set<Range> finalSet = finalNode.getRangeSet(); + assertEquals(3,finalSet.size()); + assertTrue(finalSet.contains(new Range("range1"))); + assertTrue(finalSet.contains(new Range("range2"))); + assertTrue(finalSet.contains(new Range("range3"))); + + DagNode node5 = dag.getNode(db5.getMRIIndex()); + List<DagNode> toRemoveOutEdges = node5.getOutgoingEdges(); + assertEquals(1,toRemoveOutEdges.size()); + toRemoveOutEdges.remove(finalNode); + assertEquals(0,toRemoveOutEdges.size()); + + MusicRangeInformationRow row = mixin.getMusicRangeInformation(own.getRangeId()); + assertTrue(row.getIsLatest()); + DatabasePartition dbPartition = row.getDBPartition(); + List<Range> snapshot = dbPartition.getSnapshot(); + assertEquals(3,snapshot.size()); + MusicRangeInformationRow node5row = mixin.getMusicRangeInformation(node5.getId()); + assertFalse(node5row.getIsLatest()); + MusicRangeInformationRow node4Row = mixin.getMusicRangeInformation(db4.getMRIIndex()); + assertFalse(node4Row.getIsLatest()); + MusicRangeInformationRow node3Row = mixin.getMusicRangeInformation(db3.getMRIIndex()); + assertFalse(node3Row.getIsLatest()); } + @Test public void relinquish() { } diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/DagTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/DagTest.java new file mode 100644 index 0000000..85e31cd --- /dev/null +++ b/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/DagTest.java @@ -0,0 +1,423 @@ +/* + * ============LICENSE_START==================================================== + * org.onap.music.mdbc + * ============================================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ============================================================================= + * Licensed 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. + * ============LICENSE_END====================================================== + */ + +package org.onap.music.mdbc.ownership; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; +import org.apache.commons.lang3.tuple.Pair; +import org.junit.Test; +import org.onap.music.exceptions.MDBCServiceException; +import org.onap.music.mdbc.DatabasePartition; +import org.onap.music.mdbc.MDBCUtils; +import org.onap.music.mdbc.Range; +import org.onap.music.mdbc.tables.MusicRangeInformationRow; +import org.onap.music.mdbc.tables.MusicTxDigestId; + +import static java.util.concurrent.TimeUnit.*; +import static org.junit.Assert.*; + +public class DagTest { + + private MusicRangeInformationRow createNewRow(List<Range> ranges, String lockid, boolean isLatest){ + List<MusicTxDigestId> redoLog = new ArrayList<>(); + return createNewRow(ranges,lockid,isLatest,redoLog); + } + + private MusicRangeInformationRow createNewRow(List<Range> ranges, String lockid, boolean isLatest, + List<MusicTxDigestId> redoLog) { + UUID id = MDBCUtils.generateTimebasedUniqueKey(); + DatabasePartition dbPartition = new DatabasePartition(ranges, id, lockid); + return new MusicRangeInformationRow(id, dbPartition, redoLog, lockid, "id", isLatest); + } + + @Test + public void getDag() throws InterruptedException, MDBCServiceException { + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range1") + )); + rows.add(createNewRow(new ArrayList<>(ranges),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",true)); + Dag dag = Dag.getDag(rows, ranges); + DagNode node1 = dag.getNode(rows.get(0).getPartitionIndex()); + DagNode node2 = dag.getNode(rows.get(1).getPartitionIndex()); + DagNode node3 = dag.getNode(rows.get(2).getPartitionIndex()); + List<DagNode> outgoingEdges1 = node1.getOutgoingEdges(); + assertTrue(node1.hasNotIncomingEdges()); + assertEquals(outgoingEdges1.size(),1); + assertEquals(outgoingEdges1.get(0),node2); + List<DagNode> outgoingEdges2 = node2.getOutgoingEdges(); + assertEquals(outgoingEdges2.size(),1); + assertEquals(outgoingEdges2.get(0),node3); + assertFalse(node2.hasNotIncomingEdges()); + List<DagNode> outgoingEdges3 = node3.getOutgoingEdges(); + assertEquals(outgoingEdges3.size(),0); + assertFalse(node3.hasNotIncomingEdges()); + } + + @Test + public void getDag2() throws InterruptedException, MDBCServiceException { + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> range1 = new ArrayList<>( Arrays.asList( + new Range("range1") + )); + List<Range> range2 = new ArrayList<>( Arrays.asList( + new Range("range2") + )); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range1") + )); + rows.add(createNewRow(new ArrayList<>(range1),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",true)); + Dag dag = Dag.getDag(rows, ranges); + DagNode node1 = dag.getNode(rows.get(0).getPartitionIndex()); + DagNode node2 = dag.getNode(rows.get(1).getPartitionIndex()); + DagNode node3 = dag.getNode(rows.get(2).getPartitionIndex()); + List<DagNode> outgoingEdges1 = node1.getOutgoingEdges(); + assertTrue(node1.hasNotIncomingEdges()); + assertEquals(outgoingEdges1.size(),1); + assertEquals(outgoingEdges1.get(0),node3); + List<DagNode> outgoingEdges2 = node2.getOutgoingEdges(); + assertEquals(outgoingEdges2.size(),1); + assertEquals(outgoingEdges2.get(0),node3); + assertTrue(node2.hasNotIncomingEdges()); + List<DagNode> outgoingEdges3 = node3.getOutgoingEdges(); + assertEquals(outgoingEdges3.size(),0); + assertFalse(node3.hasNotIncomingEdges()); + } + + + @Test + public void nextToOwn() throws InterruptedException, MDBCServiceException { + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range1") + )); + rows.add(createNewRow(new ArrayList<>(ranges),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",true)); + Dag dag = Dag.getDag(rows, ranges); + int counter = 0; + while(dag.hasNextToOwn()){ + DagNode node = dag.nextToOwn(); + MusicRangeInformationRow row = node.getRow(); + UUID uuid = row.getPartitionIndex(); + assertEquals(rows.get(counter).getPartitionIndex(),uuid); + dag.setOwn(node); + counter++; + assertNotEquals(4,counter); + } + assertEquals(3,counter); + assertTrue(dag.isOwned()); + } + + @Test + public void nextToApply() throws InterruptedException { + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range1") + )); + List<MusicTxDigestId> redo1 = new ArrayList<>(Arrays.asList( + new MusicTxDigestId(MDBCUtils.generateUniqueKey(),0) + )); + rows.add(createNewRow(new ArrayList<>(ranges),"",false,redo1)); + MILLISECONDS.sleep(10); + List<MusicTxDigestId> redo2 = new ArrayList<>(Arrays.asList( + new MusicTxDigestId(MDBCUtils.generateUniqueKey(),0) + )); + rows.add(createNewRow(new ArrayList<>(ranges),"",false,redo2)); + MILLISECONDS.sleep(10); + List<MusicTxDigestId> redo3 = new ArrayList<>(Arrays.asList( + new MusicTxDigestId(MDBCUtils.generateUniqueKey(),0) + )); + rows.add(createNewRow(new ArrayList<>(ranges),"",true,redo3)); + Dag dag = Dag.getDag(rows, ranges); + int nodeCounter = 0; + HashSet<Range> rangesSet = new HashSet<>(ranges); + while(!dag.applied()){ + DagNode node = dag.nextToApply(ranges); + Pair<MusicTxDigestId, List<Range>> pair = node.nextNotAppliedTransaction(rangesSet); + int transactionCounter = 0; + while(pair!=null) { + assertNotEquals(1,transactionCounter); + MusicRangeInformationRow row = rows.get(nodeCounter); + MusicTxDigestId id = row.getRedoLog().get(transactionCounter); + assertEquals(id,pair.getKey()); + assertEquals(0,pair.getKey().index); + List<Range> value = pair.getValue(); + assertEquals(1,value.size()); + assertEquals(new Range("range1"),value.get(0)); + pair = node.nextNotAppliedTransaction(rangesSet); + transactionCounter++; + } + assertEquals(1,transactionCounter); + nodeCounter++; + } + assertEquals(3,nodeCounter); + } + + @Test + public void nextToApply2() throws InterruptedException, MDBCServiceException { + Map<Range, Pair<MusicRangeInformationRow, Integer>> alreadyApplied = new HashMap<>(); + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range1") + )); + List<MusicTxDigestId> redo1 = new ArrayList<>(Arrays.asList( + new MusicTxDigestId(MDBCUtils.generateUniqueKey(),0) + )); + rows.add(createNewRow(new ArrayList<>(ranges),"",false,redo1)); + MILLISECONDS.sleep(10); + List<MusicTxDigestId> redo2 = new ArrayList<>(Arrays.asList( + new MusicTxDigestId(MDBCUtils.generateUniqueKey(),0), + new MusicTxDigestId(MDBCUtils.generateUniqueKey(),1) + )); + MusicRangeInformationRow newRow = createNewRow(new ArrayList<>(ranges), "", false, redo2); + alreadyApplied.put(new Range("range1"),Pair.of(newRow, 0)); + rows.add(newRow); + MILLISECONDS.sleep(10); + List<MusicTxDigestId> redo3 = new ArrayList<>(Arrays.asList( + new MusicTxDigestId(MDBCUtils.generateUniqueKey(),0) + )); + rows.add(createNewRow(new ArrayList<>(ranges),"",true,redo3)); + Dag dag = Dag.getDag(rows, ranges); + HashSet<Range> rangesSet = new HashSet<>(ranges); + dag.setAlreadyApplied(alreadyApplied, rangesSet); + int nodeCounter = 1; + while(!dag.applied()){ + DagNode node = dag.nextToApply(ranges); + Pair<MusicTxDigestId, List<Range>> pair = node.nextNotAppliedTransaction(rangesSet); + int transactionCounter = 0; + while(pair!=null) { + assertNotEquals(1,transactionCounter); + MusicRangeInformationRow row = rows.get(nodeCounter); + MusicTxDigestId id = row.getRedoLog().get(2-nodeCounter); + assertEquals(id,pair.getKey()); + assertEquals(2-nodeCounter,pair.getKey().index); + List<Range> value = pair.getValue(); + assertEquals(1,value.size()); + assertEquals(new Range("range1"),value.get(0)); + pair = node.nextNotAppliedTransaction(rangesSet); + transactionCounter++; + } + assertEquals(1,transactionCounter); + nodeCounter++; + } + assertEquals(3,nodeCounter); + } + + @Test + public void isDifferent() throws InterruptedException { + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> range1 = new ArrayList<>( Arrays.asList( + new Range("range1") + )); + List<Range> range2 = new ArrayList<>( Arrays.asList( + new Range("range2") + )); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range1") + )); + rows.add(createNewRow(new ArrayList<>(range1),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",true)); + List<MusicRangeInformationRow> rows2 = new ArrayList<>(rows); + List<MusicRangeInformationRow> rows3 = new ArrayList<>(rows); + MILLISECONDS.sleep(10); + rows3.add(createNewRow(new ArrayList<>(ranges),"",true)); + Dag dag = Dag.getDag(rows, ranges); + Dag dag2 = Dag.getDag(rows2, new ArrayList<>(ranges)); + Dag dag3 = Dag.getDag(rows3, new ArrayList<>(ranges)); + assertFalse(dag.isDifferent(dag2)); + assertFalse(dag2.isDifferent(dag)); + assertTrue(dag.isDifferent(dag3)); + assertTrue(dag3.isDifferent(dag)); + assertTrue(dag2.isDifferent(dag3)); + assertTrue(dag3.isDifferent(dag2)); + } + + @Test + public void getOldestDoubles() throws InterruptedException, MDBCServiceException { + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> range1 = new ArrayList<>( Arrays.asList( + new Range("range1") + )); + List<Range> range2 = new ArrayList<>( Arrays.asList( + new Range("range2") + )); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range1") + )); + rows.add(createNewRow(new ArrayList<>(range1),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range1),"",true)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",true)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",true)); + Dag dag = Dag.getDag(rows, ranges); + List<DagNode> oldestDoubles = dag.getOldestDoubles(); + assertTrue(oldestDoubles.contains(dag.getNode(rows.get(2).getPartitionIndex()))); + assertTrue(oldestDoubles.contains(dag.getNode(rows.get(3).getPartitionIndex()))); + assertEquals(2,oldestDoubles.size()); + } + + @Test + public void getIncompleteRangesAndDependents() throws InterruptedException, MDBCServiceException { + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> range1 = new ArrayList<>( Arrays.asList( + new Range("range1") + )); + List<Range> range2 = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range3") + )); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range1") + )); + rows.add(createNewRow(new ArrayList<>(range1),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range1),"",true)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",true)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",true)); + Dag dag = Dag.getDag(rows, ranges); + Pair<List<Range>, Set<DagNode>> incompleteRangesAndDependents = dag.getIncompleteRangesAndDependents(); + List<Range> incomplete = incompleteRangesAndDependents.getKey(); + Set<DagNode> dependents = incompleteRangesAndDependents.getValue(); + assertEquals(1,incomplete.size()); + assertTrue(incomplete.contains(new Range("range3"))); + assertEquals(1,dependents.size()); + assertTrue(dependents.contains(dag.getNode(rows.get(3).getPartitionIndex()))); + } + + @Test + public void getIncompleteRangesAndDependents2() throws InterruptedException, MDBCServiceException { + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> range1 = new ArrayList<>( Arrays.asList( + new Range("range1"), + new Range("range4") + )); + List<Range> range2 = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range3") + )); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range1") + )); + rows.add(createNewRow(new ArrayList<>(range1),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range1),"",true)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",true)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",true)); + Dag dag = Dag.getDag(rows, ranges); + Pair<List<Range>, Set<DagNode>> incompleteRangesAndDependents = dag.getIncompleteRangesAndDependents(); + List<Range> incomplete = incompleteRangesAndDependents.getKey(); + Set<DagNode> dependents = incompleteRangesAndDependents.getValue(); + assertEquals(2,incomplete.size()); + assertTrue(incomplete.contains(new Range("range3"))); + assertTrue(incomplete.contains(new Range("range4"))); + assertEquals(2,dependents.size()); + assertTrue(dependents.contains(dag.getNode(rows.get(3).getPartitionIndex()))); + assertTrue(dependents.contains(dag.getNode(rows.get(2).getPartitionIndex()))); + } + + @Test + public void addNewNodeWithSearch() throws InterruptedException, MDBCServiceException { + List<MusicRangeInformationRow> rows = new ArrayList<>(); + List<Range> range1 = new ArrayList<>( Arrays.asList( + new Range("range1") + )); + List<Range> range2 = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range3") + )); + List<Range> ranges = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range1") + )); + List<Range> allRanges = new ArrayList<>( Arrays.asList( + new Range("range2"), + new Range("range3"), + new Range("range1") + )); + rows.add(createNewRow(new ArrayList<>(range1),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",false)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range1),"",true)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(range2),"",true)); + MILLISECONDS.sleep(10); + rows.add(createNewRow(new ArrayList<>(ranges),"",true)); + Dag dag = Dag.getDag(rows, ranges); + MusicRangeInformationRow newRow = createNewRow(new ArrayList<>(allRanges), "", true); + dag.addNewNodeWithSearch(newRow,allRanges); + DagNode newNode = dag.getNode(newRow.getPartitionIndex()); + DagNode node = dag.getNode(rows.get(4).getPartitionIndex()); + List<DagNode> outgoingEdges = node.getOutgoingEdges(); + assertEquals(1,outgoingEdges.size()); + assertEquals(newNode,outgoingEdges.get(0)); + DagNode oNode = dag.getNode(rows.get(3).getPartitionIndex()); + outgoingEdges = node.getOutgoingEdges(); + assertEquals(1,outgoingEdges.size()); + assertEquals(newNode,outgoingEdges.get(0)); + DagNode node0 = dag.getNode(rows.get(0).getPartitionIndex()); + outgoingEdges = node0.getOutgoingEdges(); + assertEquals(1,outgoingEdges.size()); + DagNode node1 = dag.getNode(rows.get(1).getPartitionIndex()); + outgoingEdges = node1.getOutgoingEdges(); + assertEquals(1,outgoingEdges.size()); + DagNode node2 = dag.getNode(rows.get(2).getPartitionIndex()); + outgoingEdges = node1.getOutgoingEdges(); + assertEquals(1,outgoingEdges.size()); + } +}
\ No newline at end of file diff --git a/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpointTest.java b/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpointTest.java new file mode 100644 index 0000000..0e7b030 --- /dev/null +++ b/mdbc-server/src/test/java/org/onap/music/mdbc/ownership/OwnershipAndCheckpointTest.java @@ -0,0 +1,237 @@ +/* + * ============LICENSE_START==================================================== + * org.onap.music.mdbc + * ============================================================================= + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ============================================================================= + * Licensed 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. + * ============LICENSE_END====================================================== + */ + +package org.onap.music.mdbc.ownership; + +import static org.junit.Assert.*; + +import ch.vorburger.exec.ManagedProcessException; +import ch.vorburger.mariadb4j.DB; +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.Session; + +import java.sql.*; +import java.util.*; + +import org.cassandraunit.utils.EmbeddedCassandraServerHelper; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Ignore; +import org.junit.Test; +import org.onap.music.datastore.MusicDataStore; +import org.onap.music.datastore.MusicDataStoreHandle; +import org.onap.music.exceptions.MDBCServiceException; +import org.onap.music.exceptions.MusicQueryException; +import org.onap.music.exceptions.MusicServiceException; +import org.onap.music.lockingservice.cassandra.CassaLockStore; +import org.onap.music.mdbc.DatabasePartition; +import org.onap.music.mdbc.MDBCUtils; +import org.onap.music.mdbc.Range; +import org.onap.music.mdbc.TestUtils; +import org.onap.music.mdbc.mixins.LockResult; +import org.onap.music.mdbc.mixins.MusicInterface.OwnershipReturn; +import org.onap.music.mdbc.mixins.MusicMixin; +import org.onap.music.mdbc.mixins.MySQLMixin; +import org.onap.music.mdbc.tables.MusicRangeInformationRow; +import org.onap.music.mdbc.tables.StagingTable; +import org.onap.music.mdbc.tables.TxCommitProgress; + +public class OwnershipAndCheckpointTest { + final private static int sqlPort = 13350; + final private static String keyspace="metricmusictest"; + final private static String mriTableName = "musicrangeinformation"; + final private static String mtdTableName = "musictxdigest"; + final private static String mdbcServerName = "name"; + public static final String DATABASE = "mdbcTest"; + public static final String TABLE= "Persons"; + public static final String CREATE_TABLE = "CREATE TABLE IF NOT EXISTS " + TABLE + " (\n" + + " PersonID int,\n" + + " LastName varchar(255),\n" + + " FirstName varchar(255),\n" + + " Address varchar(255),\n" + + " City varchar(255),\n" + + " PRIMARY KEY (PersonID,LastName)" + + ");"; + public static final String DROP_TABLE = "DROP TABLE IF EXISTS " + TABLE + ";"; + //Properties used to connect to music + private static Cluster cluster; + private static Session session; + private static String cassaHost = "localhost"; + private static MusicMixin musicMixin = null; + private static DB db; + Connection conn; + MySQLMixin mysqlMixin; + + @BeforeClass + public static void init() throws MusicServiceException, ClassNotFoundException, ManagedProcessException { + try { + EmbeddedCassandraServerHelper.startEmbeddedCassandra(); + } catch (Exception e) { + fail(e.getMessage()); + } + cluster = new Cluster.Builder().addContactPoint(cassaHost).withPort(9142).build(); + cluster.getConfiguration().getSocketOptions().setReadTimeoutMillis(20000); + assertNotNull("Invalid configuration for cassandra", cluster); + session = cluster.connect(); + assertNotNull("Invalid configuration for cassandra", session); + Class.forName("org.mariadb.jdbc.Driver"); + MusicDataStoreHandle.mDstoreHandle = new MusicDataStore(cluster, session); + CassaLockStore store = new CassaLockStore(MusicDataStoreHandle.mDstoreHandle); + assertNotNull("Invalid configuration for music", store); + //start embedded mariadb + db = DB.newEmbeddedDB(sqlPort); + db.start(); + db.createDB(DATABASE); + } + + @AfterClass + public static void close() throws MusicServiceException, MusicQueryException, ManagedProcessException { + //TODO: shutdown cassandra + session.close(); + cluster.close(); + db.stop(); + } + + private void dropTable() throws SQLException { + final Statement dropStatement = this.conn.createStatement(); + dropStatement.execute(DROP_TABLE); + dropStatement.close(); + } + + private void createTable() throws SQLException { + final Statement createStatement = this.conn.createStatement(); + createStatement.execute(CREATE_TABLE); + createStatement.close(); + } + + private void dropAndCreateTable() throws SQLException { + mysqlMixin.dropSQLTriggers(TABLE); + dropTable(); + createTable(); + mysqlMixin.createSQLTriggers(TABLE); + } + + @Before + public void initTest() throws SQLException { + session.execute("DROP KEYSPACE IF EXISTS "+keyspace); + try { + Properties properties = new Properties(); + properties.setProperty(MusicMixin.KEY_MY_ID,mdbcServerName); + properties.setProperty(MusicMixin.KEY_MUSIC_NAMESPACE,keyspace); + musicMixin =new MusicMixin(mdbcServerName,properties); + } catch (MDBCServiceException e) { + fail("error creating music musicMixin"); + } + this.conn = DriverManager.getConnection("jdbc:mariadb://localhost:"+sqlPort+"/"+DATABASE, "root", ""); + this.mysqlMixin = new MySQLMixin(musicMixin, "localhost:"+sqlPort+"/"+DATABASE, conn, null); + dropAndCreateTable(); + } + + private void initDatabase(Range range) throws MDBCServiceException, SQLException { + final DatabasePartition partition = TestUtils.createBasicRow(range, musicMixin, mdbcServerName); + String sqlOperation = "INSERT INTO "+TABLE+" (PersonID,LastName,FirstName,Address,City) VALUES "+ + "(1,'SAUREZ','ENRIQUE','GATECH','ATLANTA');"; + HashMap<Range, StagingTable> stagingTable = new HashMap<>(); + final Statement executeStatement = this.conn.createStatement(); + executeStatement.execute(sqlOperation); + this.conn.commit(); + mysqlMixin.postStatementHook(sqlOperation,stagingTable); + executeStatement.close(); + String id = MDBCUtils.generateUniqueKey().toString(); + TxCommitProgress progressKeeper = new TxCommitProgress(); + progressKeeper.createNewTransactionTracker(id ,this.conn); + musicMixin.commitLog(partition, stagingTable, id, progressKeeper); + TestUtils.unlockRow(keyspace,mriTableName,partition); + } + + private OwnershipReturn cleanAndOwnPartition(List<Range> ranges, UUID ownOpId) throws SQLException { + dropAndCreateTable(); + DatabasePartition currentPartition = new DatabasePartition(MDBCUtils.generateTimebasedUniqueKey()); + + OwnershipReturn own=null; + try { + own = musicMixin.own(ranges, currentPartition, ownOpId); + } catch (MDBCServiceException e) { + fail("failure when running own function"); + } + return own; + } + + public void checkData() throws SQLException { + Statement statement = this.conn.createStatement(); + ResultSet rs = statement.executeQuery("SELECT * FROM " + TABLE + ";"); + int counter = 0; + while (rs.next()) { + int personId = rs.getInt("PersonID"); + assertEquals(1,personId); + String lastname = rs.getString("LastName"); + assertEquals("SAUREZ",lastname); + String firstname = rs.getString("FirstName"); + assertEquals("ENRIQUE",firstname); + String address = rs.getString("Address"); + assertEquals("GATECH",address); + String city = rs.getString("City"); + assertEquals("ATLANTA",city); + counter++; + } + assertEquals(1,counter); + } + + @Test + @Ignore + public void checkpoint() throws MDBCServiceException, SQLException { + Range range = new Range(TABLE); + OwnershipAndCheckpoint ownAndCheck = musicMixin.getOwnAndCheck(); + initDatabase(range); + + List<Range> ranges = new ArrayList<>(); + ranges.add(range); + UUID ownOpId = MDBCUtils.generateTimebasedUniqueKey(); + OwnershipReturn own = cleanAndOwnPartition(ranges,ownOpId); + + Map<MusicRangeInformationRow, LockResult> locks = new HashMap<>(); + locks.put(own.getDag().getNode(own.getRangeId()).getRow(),new LockResult(own.getRangeId(),own.getOwnerId(),true, + ranges)); + ownAndCheck.checkpoint(musicMixin,mysqlMixin,own.getDag(),ranges,locks, ownOpId); + + checkData(); + } + + @Test + @Ignore + public void warmup() throws MDBCServiceException, SQLException { + Range range = new Range(TABLE); + OwnershipAndCheckpoint ownAndCheck = musicMixin.getOwnAndCheck(); + initDatabase(range); + + List<Range> ranges = new ArrayList<>(); + ranges.add(range); + UUID ownOpId = MDBCUtils.generateTimebasedUniqueKey(); + OwnershipReturn own = cleanAndOwnPartition(ranges,ownOpId); + + Map<MusicRangeInformationRow, LockResult> locks = new HashMap<>(); + locks.put(own.getDag().getNode(own.getRangeId()).getRow(),new LockResult(own.getRangeId(),own.getOwnerId(),true, + ranges)); + ownAndCheck.warmup(musicMixin,mysqlMixin,ranges); + + checkData(); + } +}
\ No newline at end of file |