blob: 34945cd28d013e4008e6e5b6387baf68ec2dcd37 [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.
*/
#include <boost/test/unit_test.hpp>
#include "ignite/ignition.h"
#include "ignite/test_utils.h"
using namespace ignite;
using namespace ignite::transactions;
using namespace ignite::cache;
using namespace boost::unit_test;
/*
* Test setup fixture.
*/
struct TransactionsTestSuiteFixture {
Ignite grid;
/*
* Constructor.
*/
TransactionsTestSuiteFixture()
{
#ifdef IGNITE_TESTS_32
grid = ignite_test::StartNode("cache-test-32.xml", "txTest");
#else
grid = ignite_test::StartNode("cache-test.xml", "txTest");
#endif
}
/*
* Destructor.
*/
~TransactionsTestSuiteFixture()
{
Ignition::Stop(grid.GetName(), true);
grid = Ignite();
}
};
BOOST_FIXTURE_TEST_SUITE(TransactionsTestSuite, TransactionsTestSuiteFixture)
BOOST_AUTO_TEST_CASE(TransactionsMetrics)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
Transactions transactions = grid.GetTransactions();
TransactionMetrics metrics = transactions.GetMetrics();
BOOST_REQUIRE(metrics.IsValid());
BOOST_CHECK_EQUAL(0, metrics.GetCommits());
BOOST_CHECK_EQUAL(0, metrics.GetRollbacks());
}
BOOST_AUTO_TEST_CASE(TransactionCommit)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart();
BOOST_REQUIRE(transactions.GetTx().IsValid());
cache.Put(1, 1);
cache.Put(2, 2);
tx.Commit();
BOOST_CHECK_EQUAL(1, cache.Get(1));
BOOST_CHECK_EQUAL(2, cache.Get(2));
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionRollback)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
cache.Put(1, 1);
cache.Put(2, 2);
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart();
BOOST_REQUIRE(transactions.GetTx().IsValid());
cache.Put(1, 10);
cache.Put(2, 20);
tx.Rollback();
BOOST_CHECK_EQUAL(1, cache.Get(1));
BOOST_CHECK_EQUAL(2, cache.Get(2));
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionClose)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
cache.Put(1, 1);
cache.Put(2, 2);
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart();
BOOST_REQUIRE(transactions.GetTx().IsValid());
cache.Put(1, 10);
cache.Put(2, 20);
tx.Close();
BOOST_CHECK_EQUAL(1, cache.Get(1));
BOOST_CHECK_EQUAL(2, cache.Get(2));
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionRollbackOnly)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
cache.Put(1, 1);
cache.Put(2, 2);
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.TxStart();
cache.Put(1, 10);
cache.Put(2, 20);
BOOST_CHECK(!tx.IsRollbackOnly());
tx.SetRollbackOnly();
BOOST_CHECK(tx.IsRollbackOnly());
try
{
tx.Commit();
BOOST_FAIL("Commit must fail for rollback-only transaction.");
}
catch (IgniteError& error)
{
// Expected exception.
BOOST_CHECK(error.GetCode() != IgniteError::IGNITE_SUCCESS);
}
tx.Close();
BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());
BOOST_CHECK(tx.IsRollbackOnly());
BOOST_CHECK_EQUAL(1, cache.Get(1));
BOOST_CHECK_EQUAL(2, cache.Get(2));
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionAttributes)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart(TransactionConcurrency::OPTIMISTIC,
TransactionIsolation::SERIALIZABLE, 1000, 100);
BOOST_REQUIRE(transactions.GetTx().IsValid());
BOOST_CHECK_EQUAL(TransactionConcurrency::OPTIMISTIC, tx.GetConcurrency());
BOOST_CHECK_EQUAL(TransactionIsolation::SERIALIZABLE, tx.GetIsolation());
BOOST_CHECK_EQUAL(1000, tx.GetTimeout());
BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());
tx.Commit();
BOOST_CHECK_EQUAL(TransactionState::COMMITTED, tx.GetState());
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
tx = transactions.TxStart(TransactionConcurrency::PESSIMISTIC,
TransactionIsolation::READ_COMMITTED, 2000, 10);
BOOST_REQUIRE(transactions.GetTx().IsValid());
BOOST_CHECK_EQUAL(TransactionConcurrency::PESSIMISTIC, tx.GetConcurrency());
BOOST_CHECK_EQUAL(TransactionIsolation::READ_COMMITTED, tx.GetIsolation());
BOOST_CHECK_EQUAL(2000, tx.GetTimeout());
BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());
tx.Rollback();
BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
tx = transactions.TxStart(TransactionConcurrency::OPTIMISTIC,
TransactionIsolation::REPEATABLE_READ, 3000, 0);
BOOST_REQUIRE(transactions.GetTx().IsValid());
BOOST_CHECK_EQUAL(TransactionConcurrency::OPTIMISTIC, tx.GetConcurrency());
BOOST_CHECK_EQUAL(TransactionIsolation::REPEATABLE_READ, tx.GetIsolation());
BOOST_CHECK_EQUAL(3000, tx.GetTimeout());
BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());
tx.Close();
BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(CrossCacheCommit)
{
Cache<int, int> cache1 = grid.GetCache<int, int>("partitioned");
Cache<int, int> cache2 = grid.GetCache<int, int>("partitioned2");
cache1.Put(1, 1);
cache1.Put(2, 1);
cache2.Put(1, 2);
cache2.Put(2, 2);
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart();
BOOST_REQUIRE(transactions.GetTx().IsValid());
cache1.Put(1, 10);
cache1.Put(2, 10);
cache2.Put(1, 20);
cache2.Put(2, 20);
tx.Commit();
BOOST_CHECK_EQUAL(10, cache1.Get(1));
BOOST_CHECK_EQUAL(10, cache1.Get(2));
BOOST_CHECK_EQUAL(20, cache2.Get(1));
BOOST_CHECK_EQUAL(20, cache2.Get(2));
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(CrossCacheRollback)
{
Cache<int, int> cache1 = grid.GetCache<int, int>("partitioned");
Cache<int, int> cache2 = grid.GetCache<int, int>("partitioned2");
cache1.Put(1, 1);
cache1.Put(2, 1);
cache2.Put(1, 2);
cache2.Put(2, 2);
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart();
BOOST_REQUIRE(transactions.GetTx().IsValid());
cache1.Put(1, 10);
cache1.Put(2, 10);
cache2.Put(1, 20);
cache2.Put(2, 20);
tx.Rollback();
BOOST_CHECK_EQUAL(1, cache1.Get(1));
BOOST_CHECK_EQUAL(1, cache1.Get(2));
BOOST_CHECK_EQUAL(2, cache2.Get(1));
BOOST_CHECK_EQUAL(2, cache2.Get(2));
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionsMetricsNe)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
Transactions transactions = grid.GetTransactions();
IgniteError err;
TransactionMetrics metrics = transactions.GetMetrics(err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_REQUIRE(metrics.IsValid());
BOOST_CHECK_EQUAL(0, metrics.GetCommits());
BOOST_CHECK_EQUAL(0, metrics.GetRollbacks());
}
BOOST_AUTO_TEST_CASE(TransactionCommitNe)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
Transactions transactions = grid.GetTransactions();
IgniteError err;
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart(err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_REQUIRE(transactions.GetTx().IsValid());
cache.Put(1, 1, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
cache.Put(2, 2, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
tx.Commit(err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_CHECK_EQUAL(1, cache.Get(1, err));
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_CHECK_EQUAL(2, cache.Get(2, err));
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionRollbackNe)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
IgniteError err;
cache.Put(1, 1, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
cache.Put(2, 2, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart(err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_REQUIRE(transactions.GetTx().IsValid());
cache.Put(1, 10, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
cache.Put(2, 20, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
tx.Rollback(err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_CHECK_EQUAL(1, cache.Get(1, err));
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_CHECK_EQUAL(2, cache.Get(2, err));
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionCloseNe)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
IgniteError err;
cache.Put(1, 1, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
cache.Put(2, 2, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart(err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_REQUIRE(transactions.GetTx().IsValid());
cache.Put(1, 10, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
cache.Put(2, 20, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
tx.Close(err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_CHECK_EQUAL(1, cache.Get(1, err));
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_CHECK_EQUAL(2, cache.Get(2, err));
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionRollbackOnlyNe)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
IgniteError err;
cache.Put(1, 1);
cache.Put(2, 2);
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.TxStart();
cache.Put(1, 10);
cache.Put(2, 20);
BOOST_CHECK(!tx.IsRollbackOnly());
tx.SetRollbackOnly(err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_CHECK(tx.IsRollbackOnly());
tx.Commit(err);
BOOST_REQUIRE(err.GetCode() != IgniteError::IGNITE_SUCCESS);
tx.Close(err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());
BOOST_CHECK(tx.IsRollbackOnly());
BOOST_CHECK_EQUAL(1, cache.Get(1));
BOOST_CHECK_EQUAL(2, cache.Get(2));
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionAttributesNe)
{
Cache<int, int> cache = grid.GetCache<int, int>("partitioned");
IgniteError err;
Transactions transactions = grid.GetTransactions();
Transaction tx = transactions.GetTx();
BOOST_REQUIRE(!tx.IsValid());
tx = transactions.TxStart(TransactionConcurrency::OPTIMISTIC,
TransactionIsolation::SERIALIZABLE, 1000, 100, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_REQUIRE(transactions.GetTx().IsValid());
BOOST_CHECK_EQUAL(TransactionConcurrency::OPTIMISTIC, tx.GetConcurrency());
BOOST_CHECK_EQUAL(TransactionIsolation::SERIALIZABLE, tx.GetIsolation());
BOOST_CHECK_EQUAL(1000, tx.GetTimeout());
BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());
tx.Commit();
BOOST_CHECK_EQUAL(TransactionState::COMMITTED, tx.GetState());
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
tx = transactions.TxStart(TransactionConcurrency::PESSIMISTIC,
TransactionIsolation::READ_COMMITTED, 2000, 10, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_REQUIRE(transactions.GetTx().IsValid());
BOOST_CHECK_EQUAL(TransactionConcurrency::PESSIMISTIC, tx.GetConcurrency());
BOOST_CHECK_EQUAL(TransactionIsolation::READ_COMMITTED, tx.GetIsolation());
BOOST_CHECK_EQUAL(2000, tx.GetTimeout());
BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());
tx.Rollback();
BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
tx = transactions.TxStart(TransactionConcurrency::OPTIMISTIC,
TransactionIsolation::REPEATABLE_READ, 3000, 0, err);
if (err.GetCode() != IgniteError::IGNITE_SUCCESS)
BOOST_ERROR(err.GetText());
BOOST_REQUIRE(transactions.GetTx().IsValid());
BOOST_CHECK_EQUAL(TransactionConcurrency::OPTIMISTIC, tx.GetConcurrency());
BOOST_CHECK_EQUAL(TransactionIsolation::REPEATABLE_READ, tx.GetIsolation());
BOOST_CHECK_EQUAL(3000, tx.GetTimeout());
BOOST_CHECK_EQUAL(TransactionState::ACTIVE, tx.GetState());
tx.Close();
BOOST_CHECK_EQUAL(TransactionState::ROLLED_BACK, tx.GetState());
tx = transactions.GetTx();
BOOST_CHECK(!tx.IsValid());
}
BOOST_AUTO_TEST_CASE(TransactionSetTxTimeoutOnPartitionMapExchange)
{
cluster::IgniteCluster cluster = grid.GetCluster();
BOOST_CHECK_NO_THROW(cluster.SetTxTimeoutOnPartitionMapExchange(10000));
BOOST_CHECK_THROW(cluster.SetTxTimeoutOnPartitionMapExchange(-1), IgniteError);
}
BOOST_AUTO_TEST_SUITE_END()