Refactor move tests from ebean-core to ebean-test

This commit is contained in:
rbygrave committed 2021-09-08 22:49:23 +12:00
1 parent 0b00a14fd3
commit eab56d323b
1650 files changed
+185 -147

No files matched your search

@@ -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);
}
}
}
@@ -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));
}
}
@@ -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);
}
}
@@ -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
}
}
}
@@ -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;
}
}
@@ -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);
}
}