You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by br...@apache.org on 2020/08/13 21:18:59 UTC
[cassandra] branch trunk updated: Make TimestampSerializer accept
fractional seconds of varying precision
This is an automated email from the ASF dual-hosted git repository.
brandonwilliams pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/cassandra.git
The following commit(s) were added to refs/heads/trunk by this push:
new 517d3ec Make TimestampSerializer accept fractional seconds of varying precision
517d3ec is described below
commit 517d3ecceee737dffa46c47c351a43092fd4a7ba
Author: Adam Holmberg <ad...@datastax.com>
AuthorDate: Fri Aug 7 13:24:12 2020 -0500
Make TimestampSerializer accept fractional seconds of varying precision
Patch by Adam Holmberg, reviewed by brandonwilliams for CASSANDRA-15976
---
CHANGES.txt | 1 +
.../cassandra/serializers/TimestampSerializer.java | 149 +++++++------
.../cql3/validation/entities/JsonTest.java | 2 +-
.../serializers/TimestampSerializerTest.java | 231 +++++++++++++++++----
4 files changed, 277 insertions(+), 106 deletions(-)
diff --git a/CHANGES.txt b/CHANGES.txt
index 7b4cc98..58239c9 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
4.0-beta2
+ * Make TimestampSerializer accept fractional seconds of varying precision (CASSANDRA-15976)
* Improve cassandra-stress logging when using a profile file that doesn't exist (CASSANDRA-14425)
* Improve logging for socket connection/disconnection (CASSANDRA-15980)
* Throw FSWriteError upon write failures in order to apply DiskFailurePolicy (CASSANDRA-15928)
diff --git a/src/java/org/apache/cassandra/serializers/TimestampSerializer.java b/src/java/org/apache/cassandra/serializers/TimestampSerializer.java
index ac75d4b..49eb603 100644
--- a/src/java/org/apache/cassandra/serializers/TimestampSerializer.java
+++ b/src/java/org/apache/cassandra/serializers/TimestampSerializer.java
@@ -22,100 +22,108 @@ import org.apache.cassandra.utils.ByteBufferUtil;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
-import java.text.ParseException;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
+import java.util.ArrayList;
import java.util.Date;
+import java.util.List;
import java.util.TimeZone;
import java.util.regex.Pattern;
-import org.apache.commons.lang3.time.DateUtils;
public class TimestampSerializer implements TypeSerializer<Date>
{
- //NOTE: This list is used below and if you change the order
- // you need to update the default format and json formats in the code below.
- private static final String[] dateStringPatterns = new String[]
+ private static final List<DateTimeFormatter> dateFormatters = generateFormatters();
+
+ private static List<DateTimeFormatter> generateFormatters()
{
- "yyyy-MM-dd HH:mm",
- "yyyy-MM-dd HH:mm:ss",
- "yyyy-MM-dd HH:mm z",
- "yyyy-MM-dd HH:mm zz",
- "yyyy-MM-dd HH:mm zzz",
- "yyyy-MM-dd HH:mmX",
- "yyyy-MM-dd HH:mmXX", // DEFAULT_FORMAT
- "yyyy-MM-dd HH:mmXXX",
- "yyyy-MM-dd HH:mm:ss",
- "yyyy-MM-dd HH:mm:ss z",
- "yyyy-MM-dd HH:mm:ss zz",
- "yyyy-MM-dd HH:mm:ss zzz",
- "yyyy-MM-dd HH:mm:ssX",
- "yyyy-MM-dd HH:mm:ssXX",
- "yyyy-MM-dd HH:mm:ssXXX",
- "yyyy-MM-dd HH:mm:ss.SSS",
- "yyyy-MM-dd HH:mm:ss.SSS z",
- "yyyy-MM-dd HH:mm:ss.SSS zz",
- "yyyy-MM-dd HH:mm:ss.SSS zzz",
- "yyyy-MM-dd HH:mm:ss.SSSX", // TO_JSON_FORMAT
- "yyyy-MM-dd HH:mm:ss.SSSXX",
- "yyyy-MM-dd HH:mm:ss.SSSXXX",
- "yyyy-MM-dd'T'HH:mm",
- "yyyy-MM-dd'T'HH:mm z",
- "yyyy-MM-dd'T'HH:mm zz",
- "yyyy-MM-dd'T'HH:mm zzz",
- "yyyy-MM-dd'T'HH:mmX",
- "yyyy-MM-dd'T'HH:mmXX",
- "yyyy-MM-dd'T'HH:mmXXX",
- "yyyy-MM-dd'T'HH:mm:ss",
- "yyyy-MM-dd'T'HH:mm:ss z",
- "yyyy-MM-dd'T'HH:mm:ss zz",
- "yyyy-MM-dd'T'HH:mm:ss zzz",
- "yyyy-MM-dd'T'HH:mm:ssX",
- "yyyy-MM-dd'T'HH:mm:ssXX",
- "yyyy-MM-dd'T'HH:mm:ssXXX",
- "yyyy-MM-dd'T'HH:mm:ss.SSS",
- "yyyy-MM-dd'T'HH:mm:ss.SSS z",
- "yyyy-MM-dd'T'HH:mm:ss.SSS zz",
- "yyyy-MM-dd'T'HH:mm:ss.SSS zzz",
- "yyyy-MM-dd'T'HH:mm:ss.SSSX", // UTC_FORMAT
- "yyyy-MM-dd'T'HH:mm:ss.SSSXX",
- "yyyy-MM-dd'T'HH:mm:ss.SSSXXX",
- "yyyy-MM-dd",
- "yyyy-MM-dd z",
- "yyyy-MM-dd zz",
- "yyyy-MM-dd zzz",
- "yyyy-MM-ddX",
- "yyyy-MM-ddXX",
- "yyyy-MM-ddXXX"
- };
+ List<DateTimeFormatter> formatters = new ArrayList<>();
+
+ final String[] dateTimeFormats = new String[]
+ {
+ "yyyy-MM-dd'T'HH:mm[:ss]",
+ "yyyy-MM-dd HH:mm[:ss]"
+ };
+ final String[] offsetFormats = new String[]
+ {
+ " z",
+ "X",
+ " zzzz",
+ "XXX"
+ };
+
+ for (String dateTimeFormat: dateTimeFormats)
+ {
+ // local date time
+ formatters.add(
+ new DateTimeFormatterBuilder()
+ .appendPattern(dateTimeFormat)
+ .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 9, true)
+ .toFormatter()
+ .withZone(ZoneId.systemDefault()));
+ for (String offset : offsetFormats)
+ {
+ formatters.add(
+ new DateTimeFormatterBuilder()
+ .appendPattern(dateTimeFormat)
+ .appendFraction(ChronoField.MILLI_OF_SECOND, 0, 9, true)
+ .appendPattern(offset)
+ .toFormatter()
+ );
+ }
+ }
+
+ for (String offset: offsetFormats)
+ {
+ formatters.add(
+ new DateTimeFormatterBuilder()
+ .appendPattern("yyyy-MM-dd")
+ .appendPattern(offset)
+ .parseDefaulting(ChronoField.NANO_OF_DAY, 0)
+ .toFormatter()
+ );
+ }
+
+ // local date
+ formatters.add(
+ new DateTimeFormatterBuilder()
+ .append(DateTimeFormatter.ISO_DATE)
+ .parseDefaulting(ChronoField.NANO_OF_DAY, 0)
+ .toFormatter().withZone(ZoneId.systemDefault()));
+
+ return formatters;
+ }
- private static final String DEFAULT_FORMAT = dateStringPatterns[6];
private static final Pattern timestampPattern = Pattern.compile("^-?\\d+$");
private static final FastThreadLocal<SimpleDateFormat> FORMATTER = new FastThreadLocal<SimpleDateFormat>()
{
protected SimpleDateFormat initialValue()
{
- return new SimpleDateFormat(DEFAULT_FORMAT);
+ return new SimpleDateFormat("yyyy-MM-dd HH:mmXX");
}
};
- private static final String UTC_FORMAT = dateStringPatterns[40];
private static final FastThreadLocal<SimpleDateFormat> FORMATTER_UTC = new FastThreadLocal<SimpleDateFormat>()
{
protected SimpleDateFormat initialValue()
{
- SimpleDateFormat sdf = new SimpleDateFormat(UTC_FORMAT);
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf;
}
};
- private static final String TO_JSON_FORMAT = dateStringPatterns[19];
private static final FastThreadLocal<SimpleDateFormat> FORMATTER_TO_JSON = new FastThreadLocal<SimpleDateFormat>()
{
protected SimpleDateFormat initialValue()
{
- SimpleDateFormat sdf = new SimpleDateFormat(TO_JSON_FORMAT);
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSX");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
return sdf;
}
@@ -153,15 +161,18 @@ public class TimestampSerializer implements TypeSerializer<Date>
}
}
- // Last chance, attempt to parse as date-time string
- try
+ for (DateTimeFormatter fmt: dateFormatters)
{
- return DateUtils.parseDateStrictly(source, dateStringPatterns).getTime();
- }
- catch (ParseException e1)
- {
- throw new MarshalException(String.format("Unable to coerce '%s' to a formatted date (long)", source), e1);
+ try
+ {
+ return ZonedDateTime.parse(source, fmt).toInstant().toEpochMilli();
+ }
+ catch (DateTimeParseException e)
+ {
+ continue;
+ }
}
+ throw new MarshalException(String.format("Unable to parse a date/time from '%s'", source));
}
public static SimpleDateFormat getJsonDateFormatter()
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java
index 71c1d62..e28e0cb 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/JsonTest.java
@@ -516,7 +516,7 @@ public class JsonTest extends CQLTester
assertInvalidMessage("Expected a long or a datestring representation of a timestamp value, but got a Double",
"INSERT INTO %s (k, timestampval) VALUES (?, fromJson(?))", 0, "123.456");
- assertInvalidMessage("Unable to coerce 'abcd' to a formatted date",
+ assertInvalidMessage("Unable to parse a date/time from 'abcd'",
"INSERT INTO %s (k, timestampval) VALUES (?, fromJson(?))", 0, "\"abcd\"");
// ================ timeuuid ================
diff --git a/test/unit/org/apache/cassandra/serializers/TimestampSerializerTest.java b/test/unit/org/apache/cassandra/serializers/TimestampSerializerTest.java
index d991845..0cb365a 100644
--- a/test/unit/org/apache/cassandra/serializers/TimestampSerializerTest.java
+++ b/test/unit/org/apache/cassandra/serializers/TimestampSerializerTest.java
@@ -17,61 +17,220 @@
* under the License.
*/
package org.apache.cassandra.serializers;
-
+import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import org.junit.Test;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
-
-import org.apache.cassandra.serializers.MarshalException;
-import org.apache.cassandra.serializers.TimestampSerializer;
+import static org.junit.Assert.fail;
public class TimestampSerializerTest
{
- private String dates[] = new String[]
+ public static final long ONE_SECOND = 1000L;
+ public static final long ONE_MINUTE = 60 * ONE_SECOND;
+ public static final long ONE_HOUR = 60 * ONE_MINUTE;
+ public static final long ONE_DAY = 24 * ONE_HOUR;
+ public static final long BASE_OFFSET = TimestampSerializer.dateStringToTimestamp("1970-01-01");
+
+ @Test
+ public void testFormatResults() throws MarshalException
+ {
+ validateStringTimestamp("1970-01-01 00:00", BASE_OFFSET);
+ validateStringTimestamp("1970-01-01 00:01", BASE_OFFSET + ONE_MINUTE);
+ validateStringTimestamp("1970-01-01 01:00", BASE_OFFSET + ONE_HOUR);
+ validateStringTimestamp("1970-01-02 00:00", BASE_OFFSET + ONE_DAY);
+ validateStringTimestamp("1970-01-02 00:00 UTC", ONE_DAY);
+ validateStringTimestamp("1970-01-01 00:01+01", ONE_MINUTE - ONE_HOUR);
+ validateStringTimestamp("1970-01-01 01:00+0100", ONE_HOUR - ONE_HOUR);
+ validateStringTimestamp("1970-01-02 00:00+01:00", ONE_DAY - ONE_HOUR);
+ validateStringTimestamp("1970-01-01 01:00-0200", ONE_HOUR + 2 * ONE_HOUR);
+ validateStringTimestamp("1970-01-01 01:00Z", ONE_HOUR);
+
+ validateStringTimestamp("1970-01-01 00:00:00", BASE_OFFSET);
+ validateStringTimestamp("1970-01-01 00:00:01", BASE_OFFSET + ONE_SECOND);
+ validateStringTimestamp("1970-01-01 00:01:00", BASE_OFFSET + ONE_MINUTE);
+ validateStringTimestamp("1970-01-01 01:00:00", BASE_OFFSET + ONE_HOUR);
+ validateStringTimestamp("1970-01-02 00:00:00", BASE_OFFSET + ONE_DAY);
+ validateStringTimestamp("1970-01-02 00:00:00 UTC", ONE_DAY);
+ validateStringTimestamp("1970-01-01 00:01:00+01", ONE_MINUTE - ONE_HOUR);
+ validateStringTimestamp("1970-01-01 01:00:00+0100", ONE_HOUR - ONE_HOUR);
+ validateStringTimestamp("1970-01-02 00:00:00+01:00", ONE_DAY - ONE_HOUR);
+ validateStringTimestamp("1970-01-01 01:00:00-0200", ONE_HOUR + 2 * ONE_HOUR);
+ validateStringTimestamp("1970-01-01 01:00:00Z", ONE_HOUR);
+
+ validateStringTimestamp("1970-01-01 00:00:00.000", BASE_OFFSET);
+ validateStringTimestamp("1970-01-01 00:00:00.000", BASE_OFFSET);
+ validateStringTimestamp("1970-01-01 00:00:01.000", BASE_OFFSET + ONE_SECOND);
+ validateStringTimestamp("1970-01-01 00:01:00.000", BASE_OFFSET + ONE_MINUTE);
+ validateStringTimestamp("1970-01-01 01:00:00.000", BASE_OFFSET + ONE_HOUR);
+ validateStringTimestamp("1970-01-02 00:00:00.000", BASE_OFFSET + ONE_DAY);
+ validateStringTimestamp("1970-01-02 00:00:00.000 UTC", ONE_DAY);
+ validateStringTimestamp("1970-01-01 00:00:00.100 UTC", 100L);
+ validateStringTimestamp("1970-01-01 00:01:00.001+01", ONE_MINUTE - ONE_HOUR + 1);
+ validateStringTimestamp("1970-01-01 01:00:00.002+0100", ONE_HOUR - ONE_HOUR + 2);
+ validateStringTimestamp("1970-01-02 00:00:00.003+01:00", ONE_DAY - ONE_HOUR + 3);
+ validateStringTimestamp("1970-01-01 01:00:00.004-0200", ONE_HOUR + 2 * ONE_HOUR + 4);
+ validateStringTimestamp("1970-01-01 01:00:00.004Z", ONE_HOUR + 4);
+
+ validateStringTimestamp("1970-01-01T00:00", BASE_OFFSET);
+ validateStringTimestamp("1970-01-01T00:01", BASE_OFFSET + ONE_MINUTE);
+ validateStringTimestamp("1970-01-01T01:00", BASE_OFFSET + ONE_HOUR);
+ validateStringTimestamp("1970-01-02T00:00", BASE_OFFSET + ONE_DAY);
+ validateStringTimestamp("1970-01-02T00:00 UTC", ONE_DAY);
+ validateStringTimestamp("1970-01-01T00:01+01", ONE_MINUTE - ONE_HOUR);
+ validateStringTimestamp("1970-01-01T01:00+0100", ONE_HOUR - ONE_HOUR);
+ validateStringTimestamp("1970-01-02T00:00+01:00", ONE_DAY - ONE_HOUR);
+ validateStringTimestamp("1970-01-01T01:00-0200", ONE_HOUR + 2 * ONE_HOUR);
+ validateStringTimestamp("1970-01-01T01:00Z", ONE_HOUR);
+
+ validateStringTimestamp("1970-01-01T00:00:00", BASE_OFFSET);
+ validateStringTimestamp("1970-01-01T00:00:01", BASE_OFFSET + ONE_SECOND);
+ validateStringTimestamp("1970-01-01T00:01:00", BASE_OFFSET + ONE_MINUTE);
+ validateStringTimestamp("1970-01-01T01:00:00", BASE_OFFSET + ONE_HOUR);
+ validateStringTimestamp("1970-01-02T00:00:00", BASE_OFFSET + ONE_DAY);
+ validateStringTimestamp("1970-01-02T00:00:00 UTC", ONE_DAY);
+ validateStringTimestamp("1970-01-01T00:01:00+01", ONE_MINUTE - ONE_HOUR);
+ validateStringTimestamp("1970-01-01T01:00:00+0100", ONE_HOUR - ONE_HOUR);
+ validateStringTimestamp("1970-01-02T00:00:00+01:00", ONE_DAY - ONE_HOUR);
+ validateStringTimestamp("1970-01-01T01:00:00-0200", ONE_HOUR + 2 * ONE_HOUR);
+ validateStringTimestamp("1970-01-01T01:00:00Z", ONE_HOUR);
+
+ validateStringTimestamp("1970-01-01T00:00:00.000", BASE_OFFSET);
+ validateStringTimestamp("1970-01-01T00:00:00.000", BASE_OFFSET);
+ validateStringTimestamp("1970-01-01T00:00:01.000", BASE_OFFSET + ONE_SECOND);
+ validateStringTimestamp("1970-01-01T00:01:00.000", BASE_OFFSET + ONE_MINUTE);
+ validateStringTimestamp("1970-01-01T01:00:00.000", BASE_OFFSET + ONE_HOUR);
+ validateStringTimestamp("1970-01-02T00:00:00.000", BASE_OFFSET + ONE_DAY);
+ validateStringTimestamp("1970-01-02T00:00:00.000 UTC", ONE_DAY);
+ validateStringTimestamp("1970-01-01T00:00:00.100 UTC", 100L);
+ validateStringTimestamp("1970-01-01T00:01:00.001+01", ONE_MINUTE - ONE_HOUR + 1);
+ validateStringTimestamp("1970-01-01T01:00:00.002+0100", ONE_HOUR - ONE_HOUR + 2);
+ validateStringTimestamp("1970-01-02T00:00:00.003+01:00", ONE_DAY - ONE_HOUR + 3);
+ validateStringTimestamp("1970-01-01T01:00:00.004-0200", ONE_HOUR + 2 * ONE_HOUR + 4);
+ validateStringTimestamp("1970-01-01T01:00:00.004Z", ONE_HOUR + 4);
+
+ validateStringTimestamp("1970-01-01", BASE_OFFSET);
+ validateStringTimestamp("1970-01-02 UTC", ONE_DAY);
+ validateStringTimestamp("1970-01-01+01", -ONE_HOUR);
+ validateStringTimestamp("1970-01-01+0100", -ONE_HOUR);
+ validateStringTimestamp("1970-01-02+01:00", ONE_DAY - ONE_HOUR);
+ validateStringTimestamp("1970-01-01-0200", 2 * ONE_HOUR);
+ validateStringTimestamp("1970-01-01Z", 0L);
+ }
+
+ @Test
+ public void testGeneralTimeZoneFormats()
{
- "2014-04-01",
- "2014-04-01+0000",
- "2014-04-01 20:30",
- "2014-04-01 20:30:35",
- "2014-04-01 20:30:35Z",
- "2014-04-01 20:30+07",
- "2014-04-01 20:30+0700",
- "2014-04-01 20:30+07:00",
- "2014-04-01 20:30:35+07",
- "2014-04-01 20:30:35+0700",
- "2014-04-01 20:30:35+07:00",
- "2014-04-01 20:30:35.898",
- "2014-04-01 20:30:35.898Z",
- "2014-04-01 20:30:35.898+07",
- "2014-04-01 20:30:35.898+0700",
- "2014-04-01 20:30:35.898+07:00",
- "2014-04-01T20:30",
- "2014-04-01T20:30:25",
- "2014-04-01T20:30:35Z",
- "2014-04-01T20:30:35+00:00",
- "2014-04-01T20:30:35+0700",
- "2014-04-01T20:30:35+07:00",
- "2014-04-01T20:30:35.898",
- "2014-04-01T20:30:35.898+00:00"
- };
+ // Central Standard Time; CST, GMT-06:00
+ final long cstOffset = 6 * ONE_HOUR;
+ validateStringTimestamp("1970-01-01 00:00:00 Central Standard Time", cstOffset);
+ validateStringTimestamp("1970-01-01 00:00:00 CST", cstOffset);
+ validateStringTimestamp("1970-01-01T00:00:00 GMT-06:00", cstOffset);
+ }
@Test
- public void testDateStringToTimestamp()
+ public void testVaryingFractionalPrecision() // CASSANDRA-15976
{
- List<String> unparsedDates = new ArrayList<>();
- for (String date: dates)
+ validateStringTimestamp("1970-01-01 00:00:00.10 UTC", 100L);
+ validateStringTimestamp("1970-01-01 00:00:00.1+00", 100L);
+ validateStringTimestamp("1970-01-01T00:00:00.10-0000", 100L);
+ validateStringTimestamp("1970-01-01T00:00:00.1Z", 100L);
+ validateStringTimestamp("1970-01-01 00:00:00.1 Central Standard Time", 6 * ONE_HOUR + 100L);
+ validateStringTimestamp("1970-01-01 00:00:00.10+00:00", 100L);
+ validateStringTimestamp("1970-01-01T00:00:00.1", BASE_OFFSET + 100L);
+ validateStringTimestamp("1970-01-01T00:00:00.10-00:00", 100L);
+ }
+
+ @Test
+ public void testInvalidTimezones()
+ {
+ List<String> timestamps = new ArrayList<String>(
+ Arrays.asList(
+ "1970-01-01 00:00:00 xentral Standard Time",
+ "1970-01-01 00:00:00-060"
+ )
+ );
+ expectStringTimestampsExcept(timestamps);
+ }
+
+ @Test
+ public void testInvalidFormat()
+ {
+ List<String> timestamps = new ArrayList<String>(
+ Arrays.asList(
+ "1970-01-01 00:00:00andsomeextra",
+ "prefix1970-01-01 00:00:00",
+ "1970-01-01 00.56",
+ "1970-01-0100:00:00"
+ )
+ );
+ expectStringTimestampsExcept(timestamps);
+ }
+
+ @Test
+ public void testNumeric()
+ {
+ // now (positive
+ final long now = System.currentTimeMillis();
+ assertEquals(now, TimestampSerializer.dateStringToTimestamp(Long.toString(now)));
+
+ // negative
+ final long then = -11234L;
+ assertEquals(then, TimestampSerializer.dateStringToTimestamp(Long.toString(then)));
+
+ // overflows
+ for (Long l: Arrays.asList(Long.MAX_VALUE, Long.MIN_VALUE))
{
try
{
- long millis = TimestampSerializer.dateStringToTimestamp(date);
+ TimestampSerializer.dateStringToTimestamp(Long.toString(l) + "1");
+ fail("Expected exception was not raised while parsing overflowed long.");
}
catch (MarshalException e)
{
- unparsedDates.add(date);
+ continue;
}
}
- assertTrue("Unable to parse: " + unparsedDates, unparsedDates.isEmpty());
+ }
+
+ @Test
+ public void testNow()
+ {
+ final long threshold = 5;
+ final long now = System.currentTimeMillis();
+ final long parsed = TimestampSerializer.dateStringToTimestamp("now");
+ assertTrue("'now' timestamp not within expected tolerance.", now <= parsed && parsed <= now + threshold);
+ }
+
+ private void validateStringTimestamp(String s, long expected)
+ {
+ try
+ {
+ long ts = TimestampSerializer.dateStringToTimestamp(s);
+ assertEquals( "Failed to parse expected timestamp value from " + s, expected, ts);
+ }
+ catch (MarshalException e)
+ {
+ fail(String.format("Failed to parse \"%s\" as timestamp.", s));
+ }
+ }
+
+ private void expectStringTimestampsExcept(List<String> timeStrings)
+ {
+ for (String s: timeStrings)
+ {
+ try
+ {
+ TimestampSerializer.dateStringToTimestamp(s);
+ fail(String.format("Parsing succeeded while expecting failure from \"%s\"", s));
+ }
+ catch(MarshalException e)
+ {
+ continue;
+ }
+
+ }
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org