package com.redhat.lightblue.migrator.facade; import java.math.BigDecimal; import java.sql.Timestamp; import java.util.Arrays; import java.util.Date; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.togglz.junit.TogglzRule; import com.redhat.lightblue.migrator.facade.model.Country; import com.redhat.lightblue.migrator.facade.model.CountryInCountry; import com.redhat.lightblue.migrator.facade.model.CountryWithBigDecimal; import com.redhat.lightblue.migrator.facade.model.CountryWithDate; import com.redhat.lightblue.migrator.facade.model.ExtendedCountry; import com.redhat.lightblue.migrator.facade.model.VeryExtendedCountry; import com.redhat.lightblue.migrator.facade.sharedstore.SharedStoreSetter; import com.redhat.lightblue.migrator.features.LightblueMigrationFeatures; @RunWith(MockitoJUnitRunner.class) public class ConsistencyCheckTest { private Logger inconsistencyLog = Mockito.spy(LoggerFactory.getLogger(ConsistencyChecker.class)); @Rule public TogglzRule togglzRule = TogglzRule.allDisabled(LightblueMigrationFeatures.class); CountryDAO legacyDAO = Mockito.mock(CountryDAO.class, Mockito.withSettings().extraInterfaces(SharedStoreSetter.class)); CountryDAO lightblueDAO = Mockito.mock(CountryDAO.class, Mockito.withSettings().extraInterfaces(SharedStoreSetter.class)); ConsistencyChecker consistencyChecker; @Before public void setup() throws InstantiationException, IllegalAccessException { consistencyChecker = new ConsistencyChecker(CountryDAO.class.getSimpleName()); consistencyChecker.setInconsistencyLog(inconsistencyLog); } @After public void after() { // no errors logged to inconsistency log Mockito.verify(inconsistencyLog, Mockito.never()).error(Mockito.anyString()); } @Test public void testConsistencyWithIgnoredFiled() { Country pl1 = new Country(1l, "PL"); pl1.setName("Poland1"); Country pl2 = new Country(1l, "PL"); pl2.setName("Poland2"); Assert.assertTrue(consistencyChecker.checkConsistency(pl1, pl2)); } @Test public void testConsistencyWithNull() { Assert.assertTrue(consistencyChecker.checkConsistency(null, null)); // no log Assert.assertFalse(consistencyChecker.checkConsistency(null, new Country())); Assert.assertFalse(consistencyChecker.checkConsistency(new Country(), null)); Country c1 = new Country(1l, null); Country c2 = new Country(1l, null); Assert.assertTrue(consistencyChecker.checkConsistency(c1, c2)); Assert.assertTrue(consistencyChecker.checkConsistency(null, null)); Assert.assertFalse(consistencyChecker.checkConsistency(c1, null)); Assert.assertFalse(consistencyChecker.checkConsistency(null, c1)); // 4 inconsistencies means 4 warnings Mockito.verify(inconsistencyLog, Mockito.times(4)).warn(Mockito.anyString()); } @Test public void testConsistencyWithPrimitives() { Assert.assertTrue(consistencyChecker.checkConsistency("string", "string")); // no log Assert.assertTrue(consistencyChecker.checkConsistency(12, 12)); // no log Assert.assertTrue(consistencyChecker.checkConsistency(12.0d, 12.0d)); // no log Assert.assertTrue(consistencyChecker.checkConsistency(12l, 12l)); // no log Assert.assertTrue(consistencyChecker.checkConsistency(true, true)); Assert.assertTrue(consistencyChecker.checkConsistency(false, false)); // In some cases, this is not a type safe check. That's fine. Assert.assertTrue(consistencyChecker.checkConsistency(12, 12l)); Assert.assertTrue(consistencyChecker.checkConsistency(new Integer(12), 12)); Assert.assertTrue(consistencyChecker.checkConsistency(new Boolean(false), false)); // inconsistencies Assert.assertFalse(consistencyChecker.checkConsistency("foo", "bar")); Assert.assertFalse(consistencyChecker.checkConsistency(true, false)); Assert.assertFalse(consistencyChecker.checkConsistency(false, true)); Assert.assertFalse(consistencyChecker.checkConsistency(true, null)); Assert.assertFalse(consistencyChecker.checkConsistency(null, false)); Assert.assertFalse(consistencyChecker.checkConsistency(12, 13)); Assert.assertFalse(consistencyChecker.checkConsistency(new Boolean(true), null)); // 7 inconsistencies means 7 warnings Mockito.verify(inconsistencyLog, Mockito.times(7)).warn(Mockito.anyString()); } @Test public void testInconsistency() { Country pl1 = new Country(1l, "PL"); Country pl2 = new Country(2l, "PL"); Assert.assertFalse(consistencyChecker.checkConsistency(pl1, pl2)); } @Test public void testConsistencyList() { Country[] cArr1 = new Country[]{new Country(1l, "PL"), new Country(2l, "CA")}; Country[] cArr2 = new Country[]{new Country(1l, "PL"), new Country(2l, "CA")}; Assert.assertTrue(consistencyChecker.checkConsistency(Arrays.asList(cArr1), Arrays.asList(cArr2))); } @Test public void testInconsistencyList() { Country[] cArr1 = new Country[]{new Country(1l, "PL"), new Country(2l, "CA")}; Country[] cArr2 = new Country[]{new Country(3l, "PL"), new Country(2l, "CA")}; Assert.assertFalse(consistencyChecker.checkConsistency(Arrays.asList(cArr1), Arrays.asList(cArr2))); Country[] cArr3 = new Country[]{new Country(2l, "CA"), new Country(1l, "PL")}; Country[] cArr4 = new Country[]{new Country(1l, "PL"), new Country(2l, "CA")}; Assert.assertTrue(consistencyChecker.checkConsistency(Arrays.asList(cArr3), Arrays.asList(cArr4))); } @Test public void testConsistencyArray() { Country[] cArr1 = new Country[]{new Country(1l, "PL"), new Country(2l, "CA")}; Country[] cArr2 = new Country[]{new Country(1l, "PL"), new Country(2l, "CA")}; Assert.assertTrue(consistencyChecker.checkConsistency(cArr1, cArr2)); } @Test public void testInconsistencyArray() { Country[] cArr1 = new Country[]{new Country(1l, "PL"), new Country(2l, "CA")}; Country[] cArr2 = new Country[]{new Country(3l, "PL"), new Country(2l, "CA")}; Assert.assertFalse(consistencyChecker.checkConsistency(cArr1, cArr2)); Country[] cArr3 = new Country[]{new Country(2l, "CA"), new Country(1l, "PL")}; Country[] cArr4 = new Country[]{new Country(1l, "PL"), new Country(2l, "CA")}; Assert.assertTrue(consistencyChecker.checkConsistency(cArr3, cArr4)); } @Test public void testConsistencyCheckAnnotationInheritence() { Country pl1 = new ExtendedCountry(1l, "PL"); pl1.setName("Poland1"); Country pl2 = new ExtendedCountry(1l, "PL"); pl2.setName("Poland2"); Assert.assertTrue(consistencyChecker.checkConsistency(pl1, pl2)); } // NOT using Lenient /*@Test public void testTypeMismatch() { Country pl1 = new ExtendedCountry(1l, "PL"); Country pl2 = new Country(1l, "PL"); Assert.assertFalse(consistencyChecker.checkConsistency(pl1, pl2)); // We are using compare mode = Lenient, which means object 2 can have additional data Assert.assertTrue(consistencyChecker.checkConsistency(pl2, pl1)); }*/ @Test public void testInaccessibleReqField_IsIgnored() { Country pl1 = new VeryExtendedCountry(1l, "PL", "foo"); Country pl2 = new VeryExtendedCountry(1l, "PL", "bar"); Assert.assertTrue(consistencyChecker.checkConsistency(pl1, pl2)); } @Test public void testCountryInCountry_IsVerifiedForConsistency() { Country inner1 = new Country(2l, "CA"); Country inner2 = new Country(2l, "CA2"); Country pl1 = new CountryInCountry(1l, "PL", inner1); Country pl2 = new CountryInCountry(1l, "PL", inner2); Assert.assertFalse(consistencyChecker.checkConsistency(pl1, pl2)); Assert.assertTrue(consistencyChecker.checkConsistency(pl1, new CountryInCountry(1l, "PL", new Country(2l, "CA")))); } @Test public void testSqlTimestamp() { Date date = new Date(1434638750978l); Timestamp timestamp = new Timestamp(date.getTime()); CountryWithDate pl1 = new CountryWithDate(date); CountryWithDate pl2 = new CountryWithDate(timestamp); Assert.assertTrue(consistencyChecker.checkConsistency(pl1, pl2)); Assert.assertTrue(consistencyChecker.checkConsistency(pl2, pl1)); } @Test public void testSqlTimestampWithNanos() { Date date = new Date(1434638750978l); Timestamp timestamp = new Timestamp(date.getTime()); timestamp.setNanos(timestamp.getNanos() + 125300); // higher precision, difference in nano Assert.assertEquals(date.getTime(), timestamp.getTime()); CountryWithDate pl1 = new CountryWithDate(date); CountryWithDate pl2 = new CountryWithDate(timestamp); Assert.assertTrue(consistencyChecker.checkConsistency(pl1, pl2)); Assert.assertTrue(consistencyChecker.checkConsistency(pl2, pl1)); } @Test public void testBigDecimalWithDifferentScale() { BigDecimal value1 = new BigDecimal(5000); BigDecimal value2 = new BigDecimal(5000.00); CountryWithBigDecimal pl1 = new CountryWithBigDecimal(value1); CountryWithBigDecimal pl2 = new CountryWithBigDecimal(value2); Assert.assertTrue(consistencyChecker.checkConsistency(pl1, pl2)); Assert.assertTrue(consistencyChecker.checkConsistency(pl2, pl1)); } // removed method inclusion implementation, it was slow // @Test // public void testWithMethodInclusion() { // Person p1 = new Person("John", "Doe", 35, "British"); // Person p2 = new Person("John", "Doe", 35, "German"); // Assert.assertTrue(consistencyChecker.checkConsistency(p1, p2, "getPerson", null)); // Assert.assertFalse(consistencyChecker.checkConsistency(p1, p2, "getPerson2", null)); // // p1 = new Person("John", "Doe", 35, "British"); // p2 = new Person("John", "Doe", 30, "British"); // Assert.assertFalse(consistencyChecker.checkConsistency(p1, p2, "getPerson", null)); // Assert.assertTrue(consistencyChecker.checkConsistency(p1, p2, "getPerson2", null)); // } @Test public void testWithSimpleObjects() throws InterruptedException { Assert.assertTrue(consistencyChecker.checkConsistency("Test", "Test", "savePerson", null)); Assert.assertFalse(consistencyChecker.checkConsistency("Test", "Test2", "savePerson", null)); Assert.assertTrue(consistencyChecker.checkConsistency(true, true, "savePerson", null)); Assert.assertFalse(consistencyChecker.checkConsistency(true, false, "savePerson", null)); Assert.assertTrue(consistencyChecker.checkConsistency(100, 100, "savePerson", null)); Assert.assertFalse(consistencyChecker.checkConsistency(100, 101, "savePerson", null)); Date d = new Date(); Assert.assertTrue(consistencyChecker.checkConsistency(d, d, "savePerson", null)); Thread.sleep(10); // make sure dates below are inconsistent Assert.assertFalse(consistencyChecker.checkConsistency(d, new Date(), "savePerson", null)); } }