View Javadoc
1   package org.dbunit.assertion.comparer.value;
2   
3   import static org.junit.Assert.assertNotNull;
4   
5   import java.sql.Timestamp;
6   
7   import org.dbunit.DatabaseUnitException;
8   import org.dbunit.dataset.ITable;
9   import org.dbunit.dataset.datatype.DataType;
10  import org.slf4j.Logger;
11  import org.slf4j.LoggerFactory;
12  
13  /**
14   * {@link ValueComparer} implementation for {@link Timestamp}s that verifies
15   * actual value is within a low and high milliseconds tolerance range of
16   * expected value.
17   *
18   * Note: If actual and expected values are both null, the comparison passes.
19   *
20   * @author jjensen
21   * @since 2.6.0
22   */
23  public class IsActualWithinToleranceOfExpectedTimestampValueComparer
24          extends ValueComparerTemplateBase
25  {
26      private final Logger log = LoggerFactory.getLogger(getClass());
27  
28      public static final long ONE_SECOND_IN_MILLIS = 1000;
29      public static final long TWO_SECONDS_IN_MILLIS = ONE_SECOND_IN_MILLIS * 2;
30      public static final long THREE_SECONDS_IN_MILLIS = ONE_SECOND_IN_MILLIS * 3;
31      public static final long FOUR_SECONDS_IN_MILLIS = ONE_SECOND_IN_MILLIS * 4;
32      public static final long FIVE_SECONDS_IN_MILLIS = ONE_SECOND_IN_MILLIS * 5;
33  
34      public static final long ONE_MINUTE_IN_MILLIS = ONE_SECOND_IN_MILLIS * 60;
35      public static final long TWO_MINUTES_IN_MILLIS = ONE_MINUTE_IN_MILLIS * 2;
36      public static final long THREE_MINUTES_IN_MILLIS = ONE_MINUTE_IN_MILLIS * 3;
37      public static final long FOUR_MINUTES_IN_MILLIS = ONE_MINUTE_IN_MILLIS * 4;
38      public static final long FIVE_MINUTES_IN_MILLIS = ONE_MINUTE_IN_MILLIS * 5;
39      public static final long TEN_MINUTES_IN_MILLIS = ONE_MINUTE_IN_MILLIS * 10;
40  
41      private long lowToleranceValueInMillis;
42      private long highToleranceValueInMillis;
43  
44      /**
45       * Create instance specifying the allowed actual time difference range from
46       * expected.
47       *
48       * @param lowToleranceValueInMillis
49       *            The minimum time difference allowed.
50       * @param highToleranceValueInMillis
51       *            The maximum time difference allowed.
52       */
53      public IsActualWithinToleranceOfExpectedTimestampValueComparer(
54              final long lowToleranceValueInMillis,
55              final long highToleranceValueInMillis)
56      {
57          this.lowToleranceValueInMillis = lowToleranceValueInMillis;
58          this.highToleranceValueInMillis = highToleranceValueInMillis;
59      }
60  
61      @Override
62      protected boolean isExpected(final ITable expectedTable,
63              final ITable actualTable, final int rowNum, final String columnName,
64              final DataType dataType, final Object expectedValue,
65              final Object actualValue) throws DatabaseUnitException
66      {
67          final boolean isExpected;
68  
69          // handle nulls: prevent NPE and isExpected=true when both null
70          if (expectedValue == null || actualValue == null)
71          {
72              isExpected = isExpectedWithNull(expectedValue, actualValue);
73          } else
74          {
75              isExpected = isExpectedWithoutNull(expectedValue, actualValue);
76          }
77  
78          return isExpected;
79      }
80  
81      /** Since one is a known null, isExpected=true when they equal. */
82      protected boolean isExpectedWithNull(final Object expectedValue,
83              final Object actualValue)
84      {
85          final boolean isExpected;
86  
87          if (expectedValue == actualValue)
88          {
89              isExpected = true;
90          } else
91          {
92              isExpected = false;
93          }
94  
95          log.debug("isExpectedWithNull: {}, actualValue={}, expectedValue={}",
96                  isExpected, actualValue, expectedValue);
97  
98          return isExpected;
99      }
100 
101     /** Neither is null so compare values with tolerance. */
102     protected boolean isExpectedWithoutNull(final Object expectedValue,
103             final Object actualValue)
104     {
105         assertNotNull("expectedValue is null.", expectedValue);
106         assertNotNull("actualValue is null.", actualValue);
107 
108         final long actualTime = convertValueToTimeInMillis(actualValue);
109         final long expectedTime = convertValueToTimeInMillis(expectedValue);
110 
111         final long diffTime = calcTimeDifference(actualTime, expectedTime);
112         return isTolerant(diffTime);
113     }
114 
115     protected boolean isTolerant(final long diffTime)
116     {
117         final boolean isLowTolerant = diffTime >= lowToleranceValueInMillis;
118         final boolean isHighTolerant = diffTime <= highToleranceValueInMillis;
119         final boolean isTolerant = isLowTolerant && isHighTolerant;
120 
121         log.debug(
122                 "isTolerant: {},"
123                         + " diffTime={}, lowToleranceValueInMillis={},"
124                         + " highToleranceValueInMillis={}",
125                 isTolerant, diffTime, lowToleranceValueInMillis,
126                 highToleranceValueInMillis);
127 
128         return isTolerant;
129     }
130 
131     protected long convertValueToTimeInMillis(final Object timestampValue)
132     {
133         final Timestamp timestamp = (Timestamp) timestampValue;
134         return timestamp.getTime();
135     }
136 
137     protected long calcTimeDifference(final long actualTimeInMillis,
138             final long expectedTimeInMillis)
139     {
140         final long diffTime = actualTimeInMillis - expectedTimeInMillis;
141         final long diffTimeAbs = Math.abs(diffTime);
142         log.debug(
143                 "calcTimeDifference: "
144                         + "actualTimeInMillis={}, expectedTimeInMillis={},"
145                         + " diffInMillisTime={}, diffTimeInMillisAbs={}",
146                 actualTimeInMillis, expectedTimeInMillis, diffTime,
147                 diffTimeAbs);
148 
149         return diffTimeAbs;
150     }
151 
152     @Override
153     protected String getFailPhrase()
154     {
155         return "not within tolerance range of " + lowToleranceValueInMillis
156                 + " - " + highToleranceValueInMillis + " milliseconds of";
157     }
158 }