Return-Path: X-Original-To: apmail-cassandra-commits-archive@www.apache.org Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id BD47817333 for ; Mon, 9 Mar 2015 17:28:28 +0000 (UTC) Received: (qmail 7930 invoked by uid 500); 9 Mar 2015 17:28:19 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 7885 invoked by uid 500); 9 Mar 2015 17:28:19 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 7873 invoked by uid 99); 9 Mar 2015 17:28:19 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 09 Mar 2015 17:28:19 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 15C55E1808; Mon, 9 Mar 2015 17:28:19 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: jmckenzie@apache.org To: commits@cassandra.apache.org Date: Mon, 09 Mar 2015 17:28:19 -0000 Message-Id: <647f065d935b4e65a9853cc374e21143@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/2] cassandra git commit: Add date and time types Repository: cassandra Updated Branches: refs/heads/cassandra-2.1 2e3a28777 -> 107545b39 http://git-wip-us.apache.org/repos/asf/cassandra/blob/107545b3/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java b/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java new file mode 100644 index 0000000..4c0751f --- /dev/null +++ b/test/unit/org/apache/cassandra/serializers/SimpleDateSerializerTest.java @@ -0,0 +1,155 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cassandra.serializers; + +import org.apache.cassandra.db.marshal.SimpleDateType; +import org.apache.cassandra.utils.Pair; +import org.junit.Test; + +import java.nio.ByteBuffer; +import java.sql.Timestamp; +import java.text.SimpleDateFormat; +import java.util.*; + +public class SimpleDateSerializerTest +{ + private static final long millisPerDay = 1000 * 60 * 60 * 24; + + private String dates[] = new String[] + { + "1970-01-01", + "1970-01-02", + "1969-12-31", + "-0001-01-02", + "-5877521-01-02", + "2014-01-01", + "5881580-01-10", + "1920-12-01", + "1582-10-19" + }; + + private static GregorianCalendar testCalendar = new GregorianCalendar(); + private static SimpleDateFormat dateFormatUTC = new SimpleDateFormat("yyyy-MM-dd"); + + { + testCalendar.setGregorianChange(new Date(Long.MIN_VALUE)); + testCalendar.setTimeZone(TimeZone.getTimeZone("UTC")); + dateFormatUTC.setCalendar(testCalendar); + dateFormatUTC.setLenient(false); + } + + @Test + public void testDateStringToTimestamp() + { + List unparsedDates = new ArrayList<>(); + List badParseResults = new ArrayList<>(); + for (String date : dates) + { + try + { + Integer days = SimpleDateSerializer.dateStringToDays(date); + ByteBuffer value = SimpleDateSerializer.instance.serialize(days); + Integer deserialized = SimpleDateSerializer.instance.deserialize(value); + + String toStringValue = SimpleDateSerializer.instance.toString(deserialized); + if (!date.equals(toStringValue)) { + badParseResults.add(String.format("Failed to parse date correctly. Expected %s, got %s\n", date, toStringValue)); + } + } + catch (MarshalException e) + { + System.err.println("Got an exception: " + e); + unparsedDates.add(date); + } + } + assert unparsedDates.isEmpty() : "Unable to parse: " + unparsedDates; + assert badParseResults.isEmpty() : "Incorrect parse results: " + badParseResults; + } + + @Test + public void testDaysStringToInt() + { + Integer value = SimpleDateSerializer.dateStringToDays("12345"); + assert value.compareTo(12345) == 0 : String.format("Failed to parse integer based date. Expected %s, got %s", + 12345, + value); + } + + @Test + public void testProlepticRange() + { + for (int i = 1; i < 31; ++i) + { + String date = "1582-10-"; + if (i < 10) date += "0"; + date += i; + + Integer days = SimpleDateSerializer.dateStringToDays(date); + + ByteBuffer value = SimpleDateType.instance.fromString(days.toString()); + Integer deserialized = SimpleDateSerializer.instance.deserialize(value); + + // Serialized values are unsigned int, unwrap bits w/overflow + deserialized -= Integer.MIN_VALUE; + + Timestamp ts = new Timestamp(deserialized * millisPerDay); + testCalendar.setTime(ts); + + Date newDate = testCalendar.getTime(); + assert (dateFormatUTC.format(newDate)).equals(date) : + String.format("Expected [%s], got [%s]", date, dateFormatUTC.format(newDate).toString()); + } + } + + @Test (expected=MarshalException.class) + public void testOutOfBoundsLow() + { + Integer days = SimpleDateSerializer.dateStringToDays(new Date(Integer.MIN_VALUE * millisPerDay - millisPerDay).toString()); + } + + @Test (expected=MarshalException.class) + public void testOutOfBoundsHigh() + { + Integer days = SimpleDateSerializer.dateStringToDays(new Date(Integer.MAX_VALUE * millisPerDay + millisPerDay).toString()); + } + + @Test (expected=MarshalException.class) + public void testBadInput() + { + Integer days = SimpleDateSerializer.dateStringToDays("12A-01-01"); + } + + @Test (expected=MarshalException.class) + public void testBadMonth() + { + Integer days = SimpleDateSerializer.dateStringToDays("1000-13-01"); + } + + @Test (expected=MarshalException.class) + public void testBadDay() + { + Integer days = SimpleDateSerializer.dateStringToDays("1000-12-32"); + } + + @Test (expected=MarshalException.class) + public void testBadDayToMonth() + { + Integer days = SimpleDateSerializer.dateStringToDays("1000-09-31"); + } +} http://git-wip-us.apache.org/repos/asf/cassandra/blob/107545b3/test/unit/org/apache/cassandra/serializers/TimeSerializerTest.java ---------------------------------------------------------------------- diff --git a/test/unit/org/apache/cassandra/serializers/TimeSerializerTest.java b/test/unit/org/apache/cassandra/serializers/TimeSerializerTest.java new file mode 100644 index 0000000..f8af48c --- /dev/null +++ b/test/unit/org/apache/cassandra/serializers/TimeSerializerTest.java @@ -0,0 +1,242 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.cassandra.serializers; + +import org.junit.Test; + +import java.nio.ByteBuffer; +import java.util.concurrent.TimeUnit; + +public class TimeSerializerTest +{ + @Test + public void testSerializerFromString() + { + // nano + long expected = 5; + Long time = TimeSerializer.timeStringToLong("00:00:00.000000005"); + assert time == expected : String.format("Failed nano conversion. Expected %s, got %s", expected, time); + + // usec + expected = TimeUnit.MICROSECONDS.toNanos(123); + time = TimeSerializer.timeStringToLong("00:00:00.000123000"); + assert time == expected : String.format("Failed usec conversion. Expected %s, got %s", expected, time); + + // milli + expected = TimeUnit.MILLISECONDS.toNanos(123); + time = TimeSerializer.timeStringToLong("00:00:00.123000"); + assert time == expected : String.format("Failed milli conversion. Expected %s, got %s", expected, time); + + // sec + expected = TimeUnit.SECONDS.toNanos(15); + time = TimeSerializer.timeStringToLong("00:00:15.000"); + assert time == expected : String.format("Failed sec conversion. Expected %s, got %s", expected, time); + + // min + expected = TimeUnit.MINUTES.toNanos(13); + time = TimeSerializer.timeStringToLong("00:13:00.000"); + assert time == expected : String.format("Failed min conversion. Expected %s, got %s", expected, time); + + // hour + expected = TimeUnit.HOURS.toNanos(2); + time = TimeSerializer.timeStringToLong("02:0:00.000"); + assert time == expected : String.format("Failed min conversion. Expected %s, got %s", expected, time); + + // complex + expected = buildExpected(4, 31, 12, 123, 456, 789); + time = TimeSerializer.timeStringToLong("4:31:12.123456789"); + assert time == expected : String.format("Failed complex conversion. Expected %s, got %s", expected, time); + + // upper bound + expected = buildExpected(23, 59, 59, 999, 999, 999); + time = TimeSerializer.timeStringToLong("23:59:59.999999999"); + assert time == expected : String.format("Failed upper bounds conversion. Expected %s, got %s", expected, time); + + // Test partial nano + expected = buildExpected(12, 13, 14, 123, 654, 120); + time = TimeSerializer.timeStringToLong("12:13:14.12365412"); + assert time == expected : String.format("Failed partial nano timestring. Expected %s, got %s", expected, time); + + // Test raw long value + expected = 10; + time = TimeSerializer.timeStringToLong("10"); + assert time == expected : String.format("Failed long conversion. Expected %s, got %s", expected, time); + + // Test 0 long + expected = 0; + time = TimeSerializer.timeStringToLong("0"); + assert time == expected : String.format("Failed long conversion. Expected %s, got %s", expected, time); + } + + private long buildExpected(int hour, int minute, int second, int milli, int micro, int nano) + { + return TimeUnit.HOURS.toNanos(hour) + + TimeUnit.MINUTES.toNanos(minute) + + TimeUnit.SECONDS.toNanos(second) + + TimeUnit.MILLISECONDS.toNanos(milli) + + TimeUnit.MICROSECONDS.toNanos(micro) + + nano; + } + + @Test + public void testSerializerToString() + { + String source = "00:00:00.000000011"; + Long time = TimeSerializer.timeStringToLong(source); + assert(source.equals(TimeSerializer.instance.toString(time))); + + source = "00:00:00.000012311"; + time = TimeSerializer.timeStringToLong(source); + assert(source.equals(TimeSerializer.instance.toString(time))); + + source = "00:00:00.123000000"; + time = TimeSerializer.timeStringToLong(source); + assert(source.equals(TimeSerializer.instance.toString(time))); + + source = "00:00:12.123450000"; + time = TimeSerializer.timeStringToLong(source); + assert(source.equals(TimeSerializer.instance.toString(time))); + + source = "00:34:12.123450000"; + time = TimeSerializer.timeStringToLong(source); + assert(source.equals(TimeSerializer.instance.toString(time))); + + source = "15:00:12.123450000"; + time = TimeSerializer.timeStringToLong(source); + assert(source.equals(TimeSerializer.instance.toString(time))); + + // boundaries + source = "00:00:00.000000000"; + time = TimeSerializer.timeStringToLong(source); + assert(source.equals(TimeSerializer.instance.toString(time))); + + source = "23:59:59.999999999"; + time = TimeSerializer.timeStringToLong(source); + assert(source.equals(TimeSerializer.instance.toString(time))); + + // truncated + source = "01:14:18.12"; + time = TimeSerializer.timeStringToLong(source); + String result = TimeSerializer.instance.toString(time); + assert(result.equals("01:14:18.120000000")); + + source = "01:14:18.1201"; + time = TimeSerializer.timeStringToLong(source); + result = TimeSerializer.instance.toString(time); + assert(result.equals("01:14:18.120100000")); + + source = "01:14:18.1201098"; + time = TimeSerializer.timeStringToLong(source); + result = TimeSerializer.instance.toString(time); + assert(result.equals("01:14:18.120109800")); + } + + @Test public void testSerialization() + { + String source = "01:01:01.123123123"; + Long nt = TimeSerializer.timeStringToLong(source); + + ByteBuffer buf = TimeSerializer.instance.serialize(nt); + TimeSerializer.instance.validate(buf); + + Long result = TimeSerializer.instance.deserialize(buf); + String strResult = TimeSerializer.instance.toString(result); + + assert(strResult.equals(source)); + } + + @Test (expected=MarshalException.class) + public void testBadHourLow() + { + Long time = TimeSerializer.timeStringToLong("-1:0:0.123456789"); + } + + @Test (expected=MarshalException.class) + public void testBadHourHigh() + { + Long time = TimeSerializer.timeStringToLong("24:0:0.123456789"); + } + + @Test (expected=MarshalException.class) + public void testBadMinuteLow() + { + Long time = TimeSerializer.timeStringToLong("23:-1:0.123456789"); + } + + @Test (expected=MarshalException.class) + public void testBadMinuteHigh() + { + Long time = TimeSerializer.timeStringToLong("23:60:0.123456789"); + } + + @Test (expected=MarshalException.class) + public void testEmpty() + { + Long time = TimeSerializer.timeStringToLong(""); + } + + @Test (expected=MarshalException.class) + public void testBadSecondLow() + { + Long time = TimeSerializer.timeStringToLong("23:59:-1.123456789"); + } + + @Test (expected=MarshalException.class) + public void testBadSecondHigh() + { + Long time = TimeSerializer.timeStringToLong("23:59:60.123456789"); + } + + @Test (expected=MarshalException.class) + public void testBadSecondHighNoMilli() + { + Long time = TimeSerializer.timeStringToLong("23:59:60"); + } + + @Test (expected=MarshalException.class) + public void testBadNanoLow() + { + Long time = TimeSerializer.timeStringToLong("23:59:59.-123456789"); + } + + @Test (expected=MarshalException.class) + public void testBadNanoHigh() + { + Long time = TimeSerializer.timeStringToLong("23:59:59.1234567899"); + } + + @Test (expected=MarshalException.class) + public void testBadNanoCharacter() + { + Long time = TimeSerializer.timeStringToLong("23:59:59.12345A789"); + } + + @Test (expected=MarshalException.class) + public void testNegativeLongTime() + { + Long time = TimeSerializer.timeStringToLong("-10"); + } + + @Test (expected=MarshalException.class) + public void testRawLongOverflow() + { + Long input = TimeUnit.DAYS.toNanos(1) + 1; + Long time = TimeSerializer.timeStringToLong(input.toString()); + } +}