mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-11-12 22:41:35 +00:00
Refactor move tests from ebean-core to ebean-test
This commit is contained in:
1 parent
0b00a14fd3
commit
eab56d323b
1650 files changed
+185
-147
No files matched your search
+263
@@ -0,0 +1,263 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import io.ebean.bean.PersistenceContext;
|
||||
import io.ebeaninternal.server.deploy.PersistenceContextUtil;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.Car;
|
||||
import org.tests.model.basic.Contact;
|
||||
import org.tests.model.basic.Customer;
|
||||
import org.tests.model.basic.Product;
|
||||
import org.tests.model.basic.Vehicle;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class DefaultPersistenceContextTest {
|
||||
|
||||
private final Customer customer42;
|
||||
|
||||
private final Car car1;
|
||||
|
||||
public DefaultPersistenceContextTest() {
|
||||
customer42 = new Customer();
|
||||
customer42.setId(42);
|
||||
car1 = new Car();
|
||||
car1.setId(1);
|
||||
}
|
||||
|
||||
private DefaultPersistenceContext pc() {
|
||||
return new DefaultPersistenceContext();
|
||||
}
|
||||
|
||||
private DefaultPersistenceContext pcWith42() {
|
||||
DefaultPersistenceContext pc = pc();
|
||||
pc.put(Customer.class, 42, customer42);
|
||||
return pc;
|
||||
}
|
||||
|
||||
Class<?> root(Class<?> cls) {
|
||||
return PersistenceContextUtil.root(cls);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void put_get_withInheritance() {
|
||||
|
||||
PersistenceContext pc = pc();
|
||||
pc.put(root(Vehicle.class), 1, car1);
|
||||
|
||||
Object found = pc.get(root(Car.class), 1);
|
||||
assertThat(found).isSameAs(car1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void put_get() {
|
||||
|
||||
PersistenceContext pc = pc();
|
||||
pc.put(Customer.class, customer42.getId(), customer42);
|
||||
|
||||
Object found = pc.get(Customer.class, 42);
|
||||
assertThat(found).isSameAs(customer42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putIfAbsent_when_absent() {
|
||||
|
||||
PersistenceContext pc = pc();
|
||||
Object existing = pc.putIfAbsent(Customer.class, customer42.getId(), customer42);
|
||||
|
||||
assertThat(existing).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putIfAbsent_when_notAbsent() {
|
||||
|
||||
PersistenceContext pc = pcWith42();
|
||||
Object existing = pc.putIfAbsent(Customer.class, customer42.getId(), new Customer());
|
||||
|
||||
assertThat(existing).isSameAs(customer42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_when_empty() {
|
||||
PersistenceContext pc = pc();
|
||||
Object found = pc.get(Customer.class, 42);
|
||||
assertThat(found).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void get_when_there() {
|
||||
PersistenceContext pc = pcWith42();
|
||||
Object found = pc.get(Customer.class, 42);
|
||||
assertThat(found).isSameAs(customer42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWithOption_when_empty() {
|
||||
|
||||
PersistenceContext pc = pc();
|
||||
PersistenceContext.WithOption withOption = pc.getWithOption(Customer.class, 42);
|
||||
assertThat(withOption).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWithOption_when_there() {
|
||||
|
||||
PersistenceContext pc = pcWith42();
|
||||
|
||||
PersistenceContext.WithOption withOption = pc.getWithOption(Customer.class, 42);
|
||||
assertThat(withOption.getBean()).isSameAs(customer42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getWithOption_when_deleted() {
|
||||
|
||||
PersistenceContext pc = pcWith42();
|
||||
pc.deleted(Customer.class, 42);
|
||||
|
||||
PersistenceContext.WithOption withOption = pc.getWithOption(Customer.class, 42);
|
||||
assertThat(withOption.isDeleted()).isTrue();
|
||||
assertThat(withOption.getBean()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void size_when_empty() {
|
||||
|
||||
PersistenceContext pc = pc();
|
||||
assertThat(pc.size(Customer.class)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void size_when_some() {
|
||||
|
||||
PersistenceContext pc = pcWith42();
|
||||
assertThat(pc.size(Customer.class)).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clear() {
|
||||
|
||||
PersistenceContext pc = pcWith42();
|
||||
pc.clear();
|
||||
assertThat(pc.size(Customer.class)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearClass() {
|
||||
|
||||
PersistenceContext pc = pcWith42();
|
||||
pc.clear(Customer.class);
|
||||
assertThat(pc.size(Customer.class)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void clearClassAndId() {
|
||||
|
||||
PersistenceContext pc = pcWith42();
|
||||
pc.put(Customer.class, 43, new Customer());
|
||||
|
||||
pc.clear(Customer.class, 42);
|
||||
assertThat(pc.size(Customer.class)).isEqualTo(1);
|
||||
|
||||
pc.clear(Customer.class, 43);
|
||||
assertThat(pc.size(Customer.class)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forIterate() {
|
||||
final DefaultPersistenceContext pc = pcWith42();
|
||||
final Object origCustomer42 = pc.get(Customer.class, 42);
|
||||
|
||||
// act
|
||||
final PersistenceContext pcIterate = pc.forIterate();
|
||||
assertThat(pc).isNotSameAs(pcIterate);
|
||||
assertThat(pcIterate.size(Customer.class)).isEqualTo(1);
|
||||
|
||||
// assert same instance (bean effectively transferred to iterator persistence context
|
||||
final Object customer42 = pcIterate.get(Customer.class, 42);
|
||||
assertThat(customer42).isSameAs(origCustomer42);
|
||||
final PersistenceContext.WithOption option = pcIterate.getWithOption(Customer.class, 42);
|
||||
assertThat(option.getBean()).isSameAs(origCustomer42);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forIterate_many() {
|
||||
DefaultPersistenceContext pc = new DefaultPersistenceContext();
|
||||
addCustomers(pc, 1, 100);
|
||||
addContacts(pc, 1, 1010);
|
||||
assertThat(pc.size(Customer.class)).isEqualTo(100);
|
||||
assertThat(pc.size(Contact.class)).isEqualTo(1010);
|
||||
|
||||
// act
|
||||
final PersistenceContext pcIterate = pc.forIterate();
|
||||
assertThat(pcIterate.size(Customer.class)).isEqualTo(100);
|
||||
assertThat(pcIterate.size(Contact.class)).isEqualTo(1010);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void forIterate_resetLimit_forIterateReset() {
|
||||
DefaultPersistenceContext initialPc = new DefaultPersistenceContext();
|
||||
addCustomers(initialPc, 1, 100);
|
||||
addContacts(initialPc, 1, 1010);
|
||||
|
||||
final PersistenceContext pcIterate = initialPc.forIterate();
|
||||
assertFalse(pcIterate.resetLimit());
|
||||
|
||||
// added 900 NEW contact beans
|
||||
addContacts(pcIterate, 2000, 900);
|
||||
assertThat(pcIterate.size(Contact.class)).isEqualTo(1910);
|
||||
assertFalse(pcIterate.resetLimit());
|
||||
|
||||
// boundary, added 1000 NEW contact beans (still false)
|
||||
addContacts(pcIterate, 3000, 100);
|
||||
assertFalse(pcIterate.resetLimit());
|
||||
|
||||
addContacts(pcIterate, 4000, 1);
|
||||
addProducts(pcIterate, 1, 100);
|
||||
// ACT - over 1000 added beans boundary for contacts so returns true
|
||||
assertTrue(pcIterate.resetLimit());
|
||||
|
||||
assertThat(pcIterate.size(Contact.class)).isEqualTo(2011);
|
||||
assertThat(pcIterate.size(Customer.class)).isEqualTo(100);
|
||||
assertThat(pcIterate.size(Product.class)).isEqualTo(100);
|
||||
|
||||
// ACT - obtain new PC forIterateReset
|
||||
PersistenceContext pcReset = pcIterate.forIterateReset();
|
||||
|
||||
// keeps original customer beans as no new added beans there
|
||||
assertThat(pcReset.size(Customer.class)).isEqualTo(100); // customers didn't change
|
||||
// added beans to contacts and products so those where reset
|
||||
assertThat(pcReset.size(Contact.class)).isEqualTo(0);
|
||||
assertThat(pcReset.size(Product.class)).isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toString_sillyTest() {
|
||||
DefaultPersistenceContext pc = pcWith42();
|
||||
assertThat(pc.toString()).contains("org.tests.model.basic.Customer");
|
||||
}
|
||||
|
||||
private void addCustomers(PersistenceContext pc, int start, int loop) {
|
||||
for (int i = start; i < start + loop; i++) {
|
||||
Customer bean = new Customer();
|
||||
bean.setId(i);
|
||||
pc.put(Customer.class, i, bean);
|
||||
}
|
||||
}
|
||||
|
||||
private void addContacts(PersistenceContext pc, int start, int loop) {
|
||||
for (int i = start; i < start + loop; i++) {
|
||||
Contact bean = new Contact();
|
||||
bean.setId(i);
|
||||
pc.put(Contact.class, i, bean);
|
||||
}
|
||||
}
|
||||
|
||||
private void addProducts(PersistenceContext pc, int start, int loop) {
|
||||
for (int i = start; i < start + loop; i++) {
|
||||
Product bean = new Product();
|
||||
bean.setId(i);
|
||||
pc.put(Product.class, i, bean);
|
||||
}
|
||||
}
|
||||
}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
public class DefaultProfileHandlerTest {
|
||||
|
||||
@Test
|
||||
public void createProfileStream() {
|
||||
|
||||
// ProfilingConfig profilingConfig = new ProfilingConfig();
|
||||
// profilingConfig.setDirectory("target/profiling");
|
||||
//
|
||||
// DefaultProfileHandler handler = new DefaultProfileHandler(profilingConfig);
|
||||
//
|
||||
// assertNotNull(handler.createProfileStream(12));
|
||||
// assertNull(handler.createProfileStream(0));
|
||||
}
|
||||
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Database;
|
||||
import io.ebean.DatabaseFactory;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.annotation.ForPlatform;
|
||||
import io.ebean.annotation.Platform;
|
||||
import io.ebean.config.DatabaseConfig;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.EBasicVer;
|
||||
import org.tests.model.basic.UTDetail;
|
||||
import org.tests.model.basic.UTMaster;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertSame;
|
||||
|
||||
public class DefaultTransactionThreadLocalTest extends BaseTestCase {
|
||||
|
||||
@ForPlatform({Platform.H2})
|
||||
@Test
|
||||
public void get() {
|
||||
DB.execute(() -> {
|
||||
SpiTransaction txn = getInScopeTransaction();
|
||||
assertNotNull(txn);
|
||||
});
|
||||
|
||||
// thread local should be set to null
|
||||
assertNull(getInScopeTransaction());
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.H2})
|
||||
@Test
|
||||
public void tryWithResources_expect_scopeCleanup() {
|
||||
|
||||
try (Transaction transaction = DB.beginTransaction()) {
|
||||
assertNotNull(transaction);
|
||||
SpiTransaction txn = getInScopeTransaction();
|
||||
assertSame(txn, transaction);
|
||||
|
||||
try (Transaction nested = DB.beginTransaction()) {
|
||||
assertNotNull(nested);
|
||||
SpiTransaction txnNested = getInScopeTransaction();
|
||||
assertSame(txnNested, nested);
|
||||
}
|
||||
|
||||
assertNotNull(getInScopeTransaction());
|
||||
}
|
||||
|
||||
assertNull(getInScopeTransaction());
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.H2})
|
||||
@Test
|
||||
public void afterCommit_expect_scopeCleanup() {
|
||||
|
||||
try (Transaction transaction = DB.beginTransaction()) {
|
||||
transaction.commit();
|
||||
assertNull(getInScopeTransaction());
|
||||
}
|
||||
assertNull(getInScopeTransaction());
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.H2})
|
||||
@Test
|
||||
public void afterRollback_expect_scopeCleanup() {
|
||||
|
||||
try (Transaction transaction = DB.beginTransaction()) {
|
||||
|
||||
transaction.rollback();
|
||||
assertNull(getInScopeTransaction());
|
||||
}
|
||||
assertNull(getInScopeTransaction());
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.H2})
|
||||
@Test
|
||||
public void end_withoutActiveTransaction_isFine() {
|
||||
|
||||
assertNull(DB.currentTransaction());
|
||||
DB.endTransaction();
|
||||
}
|
||||
|
||||
@ForPlatform({Platform.H2})
|
||||
@Test
|
||||
public void multi_database_threadlocals() {
|
||||
|
||||
Database db = DB.getDefault();
|
||||
Database otherDb = createOtherDatabase();
|
||||
try {
|
||||
try (Transaction dbTxn = db.beginTransaction()) {
|
||||
try (Transaction otherDbTxn = otherDb.beginTransaction()) {
|
||||
assertThat(dbTxn).isNotSameAs(otherDbTxn);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
otherDb.shutdown(true, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ForPlatform(Platform.H2)
|
||||
@Test
|
||||
public void usingDatabase() {
|
||||
// setup
|
||||
Database otherDb = createOtherDatabase();
|
||||
try {
|
||||
EBasicVer bean = new EBasicVer("TestUsingDatabase");
|
||||
otherDb.save(bean);
|
||||
|
||||
// act
|
||||
final EBasicVer foundOtherDb = DB.find(EBasicVer.class)
|
||||
.usingDatabase(otherDb)
|
||||
.where().eq("name", "TestUsingDatabase")
|
||||
.findOne();
|
||||
|
||||
assertNotNull(foundOtherDb);
|
||||
assertThat(foundOtherDb.getId()).isEqualTo(bean.getId());
|
||||
|
||||
final EBasicVer foundDefaultDb = DB.find(EBasicVer.class)
|
||||
.where().eq("name", "TestUsingDatabase")
|
||||
.findOne();
|
||||
|
||||
assertNull(foundDefaultDb);
|
||||
|
||||
otherDb.delete(bean);
|
||||
} finally {
|
||||
otherDb.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private Database createOtherDatabase() {
|
||||
|
||||
DatabaseConfig config = new DatabaseConfig();
|
||||
config.setName("h2ebasicver");
|
||||
config.loadFromProperties();
|
||||
config.setDdlGenerate(true);
|
||||
config.setDdlRun(true);
|
||||
config.setDdlExtra(false);
|
||||
|
||||
config.setRegister(false);
|
||||
config.setDefaultServer(false);
|
||||
config.getClasses().add(EBasicVer.class);
|
||||
config.getClasses().add(UTMaster.class);
|
||||
config.getClasses().add(UTDetail.class);
|
||||
|
||||
return DatabaseFactory.create(config);
|
||||
}
|
||||
}
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.TransactionCallbackAdapter;
|
||||
import io.ebean.cache.ServerCache;
|
||||
import io.ebean.cache.ServerCacheManager;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.tests.model.basic.Contact;
|
||||
import org.tests.model.basic.Customer;
|
||||
import org.tests.model.basic.EBasic;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class JdbcTransactionTest {
|
||||
|
||||
@Test
|
||||
public void isSkipCache() {
|
||||
|
||||
try (Transaction transaction = DB.beginTransaction()) {
|
||||
// implicitly skip false due to query only at this point
|
||||
assertThat(transaction.isSkipCache()).isFalse();
|
||||
|
||||
EBasic basic = new EBasic("b1");
|
||||
DB.save(basic);
|
||||
|
||||
// implicitly skip true due to save
|
||||
assertThat(transaction.isSkipCache()).isTrue();
|
||||
|
||||
Customer.find.byId(1);
|
||||
|
||||
// explicit control
|
||||
transaction.setSkipCache(false);
|
||||
assertThat(transaction.isSkipCache()).isFalse();
|
||||
|
||||
transaction.setSkipCache(true);
|
||||
assertThat(transaction.isSkipCache()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void skipCacheAfterSave() {
|
||||
|
||||
ServerCacheManager cacheManager = DB.getDefault().cacheManager();
|
||||
ServerCache customerBeanCache = cacheManager.beanCache(Customer.class);
|
||||
ServerCache contactNatKeyCache = cacheManager.naturalKeyCache(Contact.class);
|
||||
|
||||
try (Transaction transaction = DB.beginTransaction()) {
|
||||
customerBeanCache.statistics(true);
|
||||
contactNatKeyCache.statistics(true);
|
||||
|
||||
Customer.find.byId(19898989);
|
||||
DB.find(Contact.class).where().eq("email", "junk@foo.com").findOne();
|
||||
|
||||
assertThat(customerBeanCache.statistics(true).getMissCount()).isEqualTo(1);
|
||||
assertThat(contactNatKeyCache.statistics(true).getMissCount()).isEqualTo(1);
|
||||
|
||||
EBasic basic = new EBasic("b1");
|
||||
DB.save(basic);
|
||||
|
||||
// these don't hit L2 cache due to the save of b1
|
||||
Customer.find.byId(29898989);
|
||||
DB.find(Contact.class).where().eq("email", "junk2@foo.com").findOne();
|
||||
|
||||
assertThat(customerBeanCache.statistics(true).getMissCount()).isEqualTo(0);
|
||||
assertThat(contactNatKeyCache.statistics(true).getMissCount()).isEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void postNestedCallback() {
|
||||
// test both pre-commit and post-commit to ensure callbacks don't disappear and new ones can be added
|
||||
AtomicInteger preCommitCallCount = new AtomicInteger();
|
||||
AtomicInteger postCommitCallCount = new AtomicInteger();
|
||||
|
||||
try (Transaction transaction = DB.beginTransaction()) {
|
||||
DB.currentTransaction().register(
|
||||
new TransactionCallbackAdapter() {
|
||||
@Override
|
||||
public void postCommit() {
|
||||
postCommitCallCount.incrementAndGet();
|
||||
DB.currentTransaction().register(
|
||||
new TransactionCallbackAdapter() {
|
||||
@Override
|
||||
public void postCommit() {
|
||||
postCommitCallCount.incrementAndGet();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preCommit() {
|
||||
preCommitCallCount.incrementAndGet();
|
||||
}
|
||||
}
|
||||
);
|
||||
EBasic basic = new EBasic("b1");
|
||||
DB.save(basic);
|
||||
transaction.commit(); // transaction will fail if recursive post-commit is failing
|
||||
|
||||
assertThat(preCommitCallCount.get()).isEqualTo(1); // precommit executed once
|
||||
assertThat(postCommitCallCount.get()).isEqualTo(2); // postcommit executed twice
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import io.ebeaninternal.server.cache.RemoteCacheEvent;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class RemoteTransactionEventTest {
|
||||
|
||||
@Test
|
||||
public void isEmpty_when_remoteCacheEvent_expect_false() {
|
||||
|
||||
RemoteTransactionEvent event = new RemoteTransactionEvent("db");
|
||||
RemoteCacheEvent remote = new RemoteCacheEvent(true);
|
||||
event.addRemoteCacheEvent(remote);
|
||||
|
||||
assertThat(event.isEmpty()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isEmpty_when_remoteTableMod_expect_false() {
|
||||
|
||||
RemoteTransactionEvent event = new RemoteTransactionEvent("db");
|
||||
RemoteTableMod remote = new RemoteTableMod(new HashSet<>(Collections.singletonList("junk")));
|
||||
event.addRemoteTableMod(remote);
|
||||
|
||||
assertThat(event.isEmpty()).isFalse();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class TableModStateTest {
|
||||
|
||||
private TableModState tableModState = new TableModState();
|
||||
|
||||
@Test
|
||||
public void isValid() {
|
||||
|
||||
long before = System.nanoTime();
|
||||
|
||||
tableModState.touch(setOf("one", "two", "three"));
|
||||
|
||||
long after = System.nanoTime();
|
||||
|
||||
// empty
|
||||
assertTrue(tableModState.isValid(Collections.emptySet(), 12L));
|
||||
|
||||
// no entry
|
||||
assertTrue(tableModState.isValid(setOf("noEntry"), 12L));
|
||||
|
||||
// later timestamp
|
||||
assertTrue(tableModState.isValid(setOf("one"), after));
|
||||
assertTrue(tableModState.isValid(setOf("one", "two", "noEntry"), after));
|
||||
|
||||
// invalid
|
||||
assertFalse(tableModState.isValid(setOf("one"), before));
|
||||
assertFalse(tableModState.isValid(setOf("one", "two"), before));
|
||||
assertFalse(tableModState.isValid(setOf("three", "two"), before));
|
||||
|
||||
}
|
||||
|
||||
private Set<String> setOf(String... tables) {
|
||||
Set<String> touched = new HashSet<>();
|
||||
Collections.addAll(touched, tables);
|
||||
return touched;
|
||||
}
|
||||
}
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
package io.ebeaninternal.server.transaction;
|
||||
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.DB;
|
||||
import io.ebean.Transaction;
|
||||
import io.ebean.TxScope;
|
||||
import io.ebeaninternal.api.ScopedTransaction;
|
||||
import io.ebeaninternal.api.SpiEbeanServer;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
import io.ebeaninternal.api.SpiTransactionManager;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.tests.model.basic.Customer;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.SQLException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TransactionManagerTest extends BaseTestCase {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(TransactionManagerTest.class);
|
||||
|
||||
@Test
|
||||
public void beginExternalTransaction() throws SQLException {
|
||||
|
||||
SpiEbeanServer server = spiEbeanServer();
|
||||
|
||||
SpiTransactionManager transactionManager = server.transactionManager();
|
||||
|
||||
DataSource dataSource = transactionManager.getDataSource();
|
||||
Connection connection = dataSource.getConnection();
|
||||
try {
|
||||
SpiTransaction externalTxn = new ExternalJdbcTransaction("external0", true, connection, null);
|
||||
|
||||
// push an externally managed transaction onto scope
|
||||
ScopedTransaction scopedTransaction = transactionManager.externalBeginTransaction(externalTxn, TxScope.required());
|
||||
|
||||
Transaction current = Transaction.current();
|
||||
assertThat(current).as("external transaction is in scope").isSameAs(scopedTransaction);
|
||||
|
||||
Customer.find.byName("In external");
|
||||
|
||||
log.info("inner begin");
|
||||
Transaction inner = DB.beginTransaction();
|
||||
try {
|
||||
|
||||
current = Transaction.current();
|
||||
assertThat(current).as("still using external transaction, nested transaction pushed").isSameAs(scopedTransaction);
|
||||
|
||||
Customer.find.byName("In inner");
|
||||
log.info("inner commit");
|
||||
inner.commit();
|
||||
} finally {
|
||||
log.info("inner end");
|
||||
inner.end();
|
||||
}
|
||||
|
||||
current = Transaction.current();
|
||||
assertThat(current).as("external transaction still in scope").isSameAs(scopedTransaction);
|
||||
|
||||
Customer.find.byName("external still active");
|
||||
|
||||
|
||||
log.info("external transaction ends with commit and remove");
|
||||
connection.commit();
|
||||
// remove externally managed transaction out of scope
|
||||
transactionManager.externalRemoveTransaction();
|
||||
|
||||
|
||||
current = Transaction.current();
|
||||
assertThat(current).as("external transaction out of scope").isNull();
|
||||
} finally {
|
||||
connection.close();
|
||||
}
|
||||
|
||||
Customer.find.byNameStatus("New implicit transaction", Customer.Status.ACTIVE);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user