@Test public void testV1CodecV2Compat() throws Exception { long now = System.currentTimeMillis(); // NOTE: set visibilityUpperBound to 0 as this is expected default for decoding older version // that doesn't store it TreeMap<Long, TransactionManager.InProgressTx> inProgress = Maps.newTreeMap( ImmutableSortedMap.of( 16L, new TransactionManager.InProgressTx(0L, now + 1000), 17L, new TransactionManager.InProgressTx(0L, now + 1000))); TransactionSnapshot snapshot = new TransactionSnapshot( now, 15, 18, Lists.newArrayList(5L, 7L), inProgress, ImmutableMap.<Long, Set<ChangeId>>of( 17L, Sets.newHashSet( new ChangeId(Bytes.toBytes("ch1")), new ChangeId(Bytes.toBytes("ch2")))), ImmutableMap.<Long, Set<ChangeId>>of( 16L, Sets.newHashSet( new ChangeId(Bytes.toBytes("ch2")), new ChangeId(Bytes.toBytes("ch3"))))); Configuration configV1 = HBaseConfiguration.create(); configV1.setStrings( TxConstants.Persist.CFG_TX_SNAPHOT_CODEC_CLASSES, SnapshotCodecV1.class.getName()); SnapshotCodecProvider codecV1 = new SnapshotCodecProvider(configV1); // encoding with codec of v1 ByteArrayOutputStream out = new ByteArrayOutputStream(); try { codecV1.encode(out, snapshot); } finally { out.close(); } // decoding Configuration configV1V2 = HBaseConfiguration.create(); configV1V2.setStrings( TxConstants.Persist.CFG_TX_SNAPHOT_CODEC_CLASSES, SnapshotCodecV1.class.getName(), SnapshotCodecV2.class.getName()); SnapshotCodecProvider codecV1V2 = new SnapshotCodecProvider(configV1V2); TransactionSnapshot decoded = codecV1V2.decode(new ByteArrayInputStream(out.toByteArray())); assertEquals(snapshot, decoded); }
/** * In-progress LONG transactions written with DefaultSnapshotCodec will not have the type * serialized as part of the data. Since these transactions also contain a non-negative * expiration, we need to ensure we reset the type correctly when the snapshot is loaded. */ @Test public void testV2ToTephraV3Compatibility() throws Exception { long now = System.currentTimeMillis(); long nowWritePointer = now * TxConstants.MAX_TX_PER_MS; /* * Snapshot consisting of transactions at: */ long tInvalid = nowWritePointer - 5; // t1 - invalid long readPtr = nowWritePointer - 4; // t2 - here and earlier committed long tLong = nowWritePointer - 3; // t3 - in-progress LONG long tCommitted = nowWritePointer - 2; // t4 - committed, changeset (r1, r2) long tShort = nowWritePointer - 1; // t5 - in-progress SHORT, canCommit called, changeset (r3, r4) TreeMap<Long, TransactionManager.InProgressTx> inProgress = Maps.newTreeMap( ImmutableSortedMap.of( tLong, new TransactionManager.InProgressTx( readPtr, TransactionManager.getTxExpirationFromWritePointer( tLong, TxConstants.Manager.DEFAULT_TX_LONG_TIMEOUT), TransactionType.LONG), tShort, new TransactionManager.InProgressTx( readPtr, now + 1000, TransactionType.SHORT))); TransactionSnapshot snapshot = new TransactionSnapshot( now, readPtr, nowWritePointer, Lists.newArrayList(tInvalid), // invalid inProgress, ImmutableMap.<Long, Set<ChangeId>>of( tShort, Sets.newHashSet( new ChangeId(new byte[] {'r', '3'}), new ChangeId(new byte[] {'r', '4'}))), ImmutableMap.<Long, Set<ChangeId>>of( tCommitted, Sets.newHashSet( new ChangeId(new byte[] {'r', '1'}), new ChangeId(new byte[] {'r', '2'})))); Configuration conf1 = new Configuration(); conf1.set(TxConstants.Persist.CFG_TX_SNAPHOT_CODEC_CLASSES, SnapshotCodecV2.class.getName()); SnapshotCodecProvider provider1 = new SnapshotCodecProvider(conf1); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { provider1.encode(out, snapshot); } finally { out.close(); } TransactionSnapshot snapshot2 = provider1.decode(new ByteArrayInputStream(out.toByteArray())); assertEquals(snapshot.getReadPointer(), snapshot2.getReadPointer()); assertEquals(snapshot.getWritePointer(), snapshot2.getWritePointer()); assertEquals(snapshot.getInvalid(), snapshot2.getInvalid()); // in-progress transactions will have missing types assertNotEquals(snapshot.getInProgress(), snapshot2.getInProgress()); assertEquals(snapshot.getCommittingChangeSets(), snapshot2.getCommittingChangeSets()); assertEquals(snapshot.getCommittedChangeSets(), snapshot2.getCommittedChangeSets()); // after fixing in-progress, full snapshot should match Map<Long, TransactionManager.InProgressTx> fixedInProgress = TransactionManager.txnBackwardsCompatCheck( TxConstants.Manager.DEFAULT_TX_LONG_TIMEOUT, 10000L, snapshot2.getInProgress()); assertEquals(snapshot.getInProgress(), fixedInProgress); assertEquals(snapshot, snapshot2); }