Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(615)

Side by Side Diff: base/time/time_unittest.cc

Issue 1250453004: Revert of Base: Make TimeDelta constructors deal with overflow. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/time/time.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/time/time.h" 5 #include "base/time/time.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 #include <time.h> 8 #include <time.h>
9 #include <limits> 9 #include <limits>
10 #include <string> 10 #include <string>
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
477 // Should be 1970-01-01 00:00:01 1 millisecond. 477 // Should be 1970-01-01 00:00:01 1 millisecond.
478 EXPECT_EQ(kUnixEpochYear, exploded.year); 478 EXPECT_EQ(kUnixEpochYear, exploded.year);
479 EXPECT_EQ(1, exploded.month); 479 EXPECT_EQ(1, exploded.month);
480 EXPECT_EQ(1, exploded.day_of_month); 480 EXPECT_EQ(1, exploded.day_of_month);
481 EXPECT_EQ(0, exploded.hour); 481 EXPECT_EQ(0, exploded.hour);
482 EXPECT_EQ(0, exploded.minute); 482 EXPECT_EQ(0, exploded.minute);
483 EXPECT_EQ(1, exploded.second); 483 EXPECT_EQ(1, exploded.second);
484 EXPECT_EQ(1, exploded.millisecond); 484 EXPECT_EQ(1, exploded.millisecond);
485 } 485 }
486 486
487 TEST_F(TimeTest, TimeDeltaMax) {
488 TimeDelta max = TimeDelta::Max();
489 EXPECT_TRUE(max.is_max());
490 EXPECT_EQ(max, TimeDelta::Max());
491 EXPECT_GT(max, TimeDelta::FromDays(100 * 365));
492 EXPECT_GT(max, TimeDelta());
493 }
494
495 TEST_F(TimeTest, TimeDeltaMaxConversions) {
496 TimeDelta t = TimeDelta::Max();
497 EXPECT_EQ(std::numeric_limits<int64>::max(), t.ToInternalValue());
498
499 EXPECT_EQ(std::numeric_limits<int>::max(), t.InDays());
500 EXPECT_EQ(std::numeric_limits<int>::max(), t.InHours());
501 EXPECT_EQ(std::numeric_limits<int>::max(), t.InMinutes());
502 EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InSecondsF());
503 EXPECT_EQ(std::numeric_limits<int64>::max(), t.InSeconds());
504 EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InMillisecondsF());
505 EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMilliseconds());
506 EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMillisecondsRoundedUp());
507
508 t = TimeDelta::FromDays(std::numeric_limits<int>::max());
509 EXPECT_TRUE(t.is_max());
510
511 t = TimeDelta::FromHours(std::numeric_limits<int>::max());
512 EXPECT_TRUE(t.is_max());
513
514 t = TimeDelta::FromMinutes(std::numeric_limits<int>::max());
515 EXPECT_TRUE(t.is_max());
516
517 t = TimeDelta::FromSeconds(std::numeric_limits<int64>::max());
518 EXPECT_TRUE(t.is_max());
519
520 t = TimeDelta::FromMilliseconds(std::numeric_limits<int64>::max());
521 EXPECT_TRUE(t.is_max());
522
523 t = TimeDelta::FromSecondsD(std::numeric_limits<double>::infinity());
524 EXPECT_TRUE(t.is_max());
525
526 t = TimeDelta::FromMillisecondsD(std::numeric_limits<double>::infinity());
527 EXPECT_TRUE(t.is_max());
528
529 t = TimeDelta::FromMicroseconds(std::numeric_limits<int64>::max());
530 EXPECT_TRUE(t.is_max());
531 }
532
487 TEST_F(TimeTest, Max) { 533 TEST_F(TimeTest, Max) {
488 Time max = Time::Max(); 534 Time max = Time::Max();
489 EXPECT_TRUE(max.is_max()); 535 EXPECT_TRUE(max.is_max());
490 EXPECT_EQ(max, Time::Max()); 536 EXPECT_EQ(max, Time::Max());
491 EXPECT_GT(max, Time::Now()); 537 EXPECT_GT(max, Time::Now());
492 EXPECT_GT(max, Time()); 538 EXPECT_GT(max, Time());
493 } 539 }
494 540
495 TEST_F(TimeTest, MaxConversions) { 541 TEST_F(TimeTest, MaxConversions) {
496 Time t = Time::Max(); 542 Time t = Time::Max();
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 EXPECT_EQ(13, TimeDelta::FromMinutes(13).InMinutes()); 788 EXPECT_EQ(13, TimeDelta::FromMinutes(13).InMinutes());
743 EXPECT_EQ(13, TimeDelta::FromSeconds(13).InSeconds()); 789 EXPECT_EQ(13, TimeDelta::FromSeconds(13).InSeconds());
744 EXPECT_EQ(13.0, TimeDelta::FromSeconds(13).InSecondsF()); 790 EXPECT_EQ(13.0, TimeDelta::FromSeconds(13).InSecondsF());
745 EXPECT_EQ(13, TimeDelta::FromMilliseconds(13).InMilliseconds()); 791 EXPECT_EQ(13, TimeDelta::FromMilliseconds(13).InMilliseconds());
746 EXPECT_EQ(13.0, TimeDelta::FromMilliseconds(13).InMillisecondsF()); 792 EXPECT_EQ(13.0, TimeDelta::FromMilliseconds(13).InMillisecondsF());
747 EXPECT_EQ(13, TimeDelta::FromSecondsD(13.1).InSeconds()); 793 EXPECT_EQ(13, TimeDelta::FromSecondsD(13.1).InSeconds());
748 EXPECT_EQ(13.1, TimeDelta::FromSecondsD(13.1).InSecondsF()); 794 EXPECT_EQ(13.1, TimeDelta::FromSecondsD(13.1).InSecondsF());
749 EXPECT_EQ(13, TimeDelta::FromMillisecondsD(13.3).InMilliseconds()); 795 EXPECT_EQ(13, TimeDelta::FromMillisecondsD(13.3).InMilliseconds());
750 EXPECT_EQ(13.3, TimeDelta::FromMillisecondsD(13.3).InMillisecondsF()); 796 EXPECT_EQ(13.3, TimeDelta::FromMillisecondsD(13.3).InMillisecondsF());
751 EXPECT_EQ(13, TimeDelta::FromMicroseconds(13).InMicroseconds()); 797 EXPECT_EQ(13, TimeDelta::FromMicroseconds(13).InMicroseconds());
752 EXPECT_EQ(3.456, TimeDelta::FromMillisecondsD(3.45678).InMillisecondsF());
753 } 798 }
754 799
755 #if defined(OS_POSIX) 800 #if defined(OS_POSIX)
756 TEST(TimeDelta, TimeSpecConversion) { 801 TEST(TimeDelta, TimeSpecConversion) {
757 struct timespec result = TimeDelta::FromSeconds(0).ToTimeSpec(); 802 struct timespec result = TimeDelta::FromSeconds(0).ToTimeSpec();
758 EXPECT_EQ(result.tv_sec, 0); 803 EXPECT_EQ(result.tv_sec, 0);
759 EXPECT_EQ(result.tv_nsec, 0); 804 EXPECT_EQ(result.tv_nsec, 0);
760 805
761 result = TimeDelta::FromSeconds(1).ToTimeSpec(); 806 result = TimeDelta::FromSeconds(1).ToTimeSpec();
762 EXPECT_EQ(result.tv_sec, 1); 807 EXPECT_EQ(result.tv_sec, 1);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
816 TimeDelta::FromMicroseconds(negative_one).magnitude()); 861 TimeDelta::FromMicroseconds(negative_one).magnitude());
817 862
818 const int64 max_int64_minus_one = std::numeric_limits<int64>::max() - 1; 863 const int64 max_int64_minus_one = std::numeric_limits<int64>::max() - 1;
819 const int64 min_int64_plus_two = std::numeric_limits<int64>::min() + 2; 864 const int64 min_int64_plus_two = std::numeric_limits<int64>::min() + 2;
820 EXPECT_EQ(TimeDelta::FromMicroseconds(max_int64_minus_one), 865 EXPECT_EQ(TimeDelta::FromMicroseconds(max_int64_minus_one),
821 TimeDelta::FromMicroseconds(max_int64_minus_one).magnitude()); 866 TimeDelta::FromMicroseconds(max_int64_minus_one).magnitude());
822 EXPECT_EQ(TimeDelta::FromMicroseconds(max_int64_minus_one), 867 EXPECT_EQ(TimeDelta::FromMicroseconds(max_int64_minus_one),
823 TimeDelta::FromMicroseconds(min_int64_plus_two).magnitude()); 868 TimeDelta::FromMicroseconds(min_int64_plus_two).magnitude());
824 } 869 }
825 870
826 TEST(TimeDelta, Max) {
827 TimeDelta max = TimeDelta::Max();
828 EXPECT_TRUE(max.is_max());
829 EXPECT_EQ(max, TimeDelta::Max());
830 EXPECT_GT(max, TimeDelta::FromDays(100 * 365));
831 EXPECT_GT(max, TimeDelta());
832 }
833
834 bool IsMin(TimeDelta delta) {
835 return (-delta).is_max();
836 }
837
838 TEST(TimeDelta, MaxConversions) {
839 TimeDelta t = TimeDelta::Max();
840 EXPECT_EQ(std::numeric_limits<int64>::max(), t.ToInternalValue());
841
842 EXPECT_EQ(std::numeric_limits<int>::max(), t.InDays());
843 EXPECT_EQ(std::numeric_limits<int>::max(), t.InHours());
844 EXPECT_EQ(std::numeric_limits<int>::max(), t.InMinutes());
845 EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InSecondsF());
846 EXPECT_EQ(std::numeric_limits<int64>::max(), t.InSeconds());
847 EXPECT_EQ(std::numeric_limits<double>::infinity(), t.InMillisecondsF());
848 EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMilliseconds());
849 EXPECT_EQ(std::numeric_limits<int64>::max(), t.InMillisecondsRoundedUp());
850
851 t = TimeDelta::FromDays(std::numeric_limits<int>::max());
852 EXPECT_TRUE(t.is_max());
853
854 t = TimeDelta::FromHours(std::numeric_limits<int>::max());
855 EXPECT_TRUE(t.is_max());
856
857 t = TimeDelta::FromMinutes(std::numeric_limits<int>::max());
858 EXPECT_TRUE(t.is_max());
859
860 int64 max_int = std::numeric_limits<int64>::max();
861
862 t = TimeDelta::FromSeconds(max_int / Time::kMicrosecondsPerSecond + 1);
863 EXPECT_TRUE(t.is_max());
864
865 t = TimeDelta::FromMilliseconds(max_int / Time::kMillisecondsPerSecond + 1);
866 EXPECT_TRUE(t.is_max());
867
868 t = TimeDelta::FromMicroseconds(max_int);
869 EXPECT_TRUE(t.is_max());
870
871 t = TimeDelta::FromSeconds(-max_int / Time::kMicrosecondsPerSecond - 1);
872 EXPECT_TRUE(IsMin(t));
873
874 t = TimeDelta::FromMilliseconds(-max_int / Time::kMillisecondsPerSecond - 1);
875 EXPECT_TRUE(IsMin(t));
876
877 t = TimeDelta::FromMicroseconds(-max_int);
878 EXPECT_TRUE(IsMin(t));
879
880 t = -TimeDelta::FromMicroseconds(std::numeric_limits<int64>::min());
881 EXPECT_FALSE(IsMin(t));
882
883 t = TimeDelta::FromSecondsD(std::numeric_limits<double>::infinity());
884 EXPECT_TRUE(t.is_max());
885
886 double max_d = max_int;
887
888 t = TimeDelta::FromSecondsD(max_d / Time::kMicrosecondsPerSecond + 1);
889 EXPECT_TRUE(t.is_max());
890
891 t = TimeDelta::FromMillisecondsD(std::numeric_limits<double>::infinity());
892 EXPECT_TRUE(t.is_max());
893
894 t = TimeDelta::FromMillisecondsD(max_d / Time::kMillisecondsPerSecond * 2);
895 EXPECT_TRUE(t.is_max());
896
897 t = TimeDelta::FromSecondsD(-max_d / Time::kMicrosecondsPerSecond - 1);
898 EXPECT_TRUE(IsMin(t));
899
900 t = TimeDelta::FromMillisecondsD(-max_d / Time::kMillisecondsPerSecond * 2);
901 EXPECT_TRUE(IsMin(t));
902 }
903 871
904 TEST(TimeDelta, NumericOperators) { 872 TEST(TimeDelta, NumericOperators) {
905 double d = 0.5; 873 double d = 0.5;
906 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 874 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
907 TimeDelta::FromMilliseconds(1000) * d); 875 TimeDelta::FromMilliseconds(1000) * d);
908 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 876 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
909 TimeDelta::FromMilliseconds(1000) / d); 877 TimeDelta::FromMilliseconds(1000) / d);
910 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 878 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
911 TimeDelta::FromMilliseconds(1000) *= d); 879 TimeDelta::FromMilliseconds(1000) *= d);
912 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 880 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
913 TimeDelta::FromMilliseconds(1000) /= d); 881 TimeDelta::FromMilliseconds(1000) /= d);
914 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 882 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
915 d * TimeDelta::FromMilliseconds(1000)); 883 d * TimeDelta::FromMilliseconds(1000));
916 884
917 float f = 0.5; 885 float f = 0.5;
918 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 886 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
919 TimeDelta::FromMilliseconds(1000) * f); 887 TimeDelta::FromMilliseconds(1000) * f);
920 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 888 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
921 TimeDelta::FromMilliseconds(1000) / f); 889 TimeDelta::FromMilliseconds(1000) / f);
922 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 890 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
923 TimeDelta::FromMilliseconds(1000) *= f); 891 TimeDelta::FromMilliseconds(1000) *= f);
924 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 892 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
925 TimeDelta::FromMilliseconds(1000) /= f); 893 TimeDelta::FromMilliseconds(1000) /= f);
926 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 894 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
927 f * TimeDelta::FromMilliseconds(1000)); 895 f * TimeDelta::FromMilliseconds(1000));
928 896
897
929 int i = 2; 898 int i = 2;
930 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 899 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
931 TimeDelta::FromMilliseconds(1000) * i); 900 TimeDelta::FromMilliseconds(1000) * i);
932 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 901 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
933 TimeDelta::FromMilliseconds(1000) / i); 902 TimeDelta::FromMilliseconds(1000) / i);
934 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 903 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
935 TimeDelta::FromMilliseconds(1000) *= i); 904 TimeDelta::FromMilliseconds(1000) *= i);
936 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 905 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
937 TimeDelta::FromMilliseconds(1000) /= i); 906 TimeDelta::FromMilliseconds(1000) /= i);
938 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 907 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
939 i * TimeDelta::FromMilliseconds(1000)); 908 i * TimeDelta::FromMilliseconds(1000));
940 909
941 int64_t i64 = 2; 910 int64_t i64 = 2;
942 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 911 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
943 TimeDelta::FromMilliseconds(1000) * i64); 912 TimeDelta::FromMilliseconds(1000) * i64);
944 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 913 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
945 TimeDelta::FromMilliseconds(1000) / i64); 914 TimeDelta::FromMilliseconds(1000) / i64);
946 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 915 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
947 TimeDelta::FromMilliseconds(1000) *= i64); 916 TimeDelta::FromMilliseconds(1000) *= i64);
948 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 917 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
949 TimeDelta::FromMilliseconds(1000) /= i64); 918 TimeDelta::FromMilliseconds(1000) /= i64);
950 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 919 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
951 i64 * TimeDelta::FromMilliseconds(1000)); 920 i64 * TimeDelta::FromMilliseconds(1000));
952 921
922
953 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 923 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
954 TimeDelta::FromMilliseconds(1000) * 0.5); 924 TimeDelta::FromMilliseconds(1000) * 0.5);
955 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 925 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
956 TimeDelta::FromMilliseconds(1000) / 0.5); 926 TimeDelta::FromMilliseconds(1000) / 0.5);
957 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 927 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
958 TimeDelta::FromMilliseconds(1000) *= 0.5); 928 TimeDelta::FromMilliseconds(1000) *= 0.5);
959 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 929 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
960 TimeDelta::FromMilliseconds(1000) /= 0.5); 930 TimeDelta::FromMilliseconds(1000) /= 0.5);
961 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 931 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
962 0.5 * TimeDelta::FromMilliseconds(1000)); 932 0.5 * TimeDelta::FromMilliseconds(1000));
963 933
964 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 934 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
965 TimeDelta::FromMilliseconds(1000) * 2); 935 TimeDelta::FromMilliseconds(1000) * 2);
966 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 936 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
967 TimeDelta::FromMilliseconds(1000) / 2); 937 TimeDelta::FromMilliseconds(1000) / 2);
968 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 938 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
969 TimeDelta::FromMilliseconds(1000) *= 2); 939 TimeDelta::FromMilliseconds(1000) *= 2);
970 EXPECT_EQ(TimeDelta::FromMilliseconds(500), 940 EXPECT_EQ(TimeDelta::FromMilliseconds(500),
971 TimeDelta::FromMilliseconds(1000) /= 2); 941 TimeDelta::FromMilliseconds(1000) /= 2);
972 EXPECT_EQ(TimeDelta::FromMilliseconds(2000), 942 EXPECT_EQ(TimeDelta::FromMilliseconds(2000),
973 2 * TimeDelta::FromMilliseconds(1000)); 943 2 * TimeDelta::FromMilliseconds(1000));
974 } 944 }
975 945
946 bool IsMin(TimeDelta delta) {
947 return (-delta).is_max();
948 }
949
976 TEST(TimeDelta, Overflows) { 950 TEST(TimeDelta, Overflows) {
977 // Some sanity checks. 951 // Some sanity checks.
978 EXPECT_TRUE(TimeDelta::Max().is_max()); 952 EXPECT_TRUE(TimeDelta::Max().is_max());
979 EXPECT_TRUE(IsMin(-TimeDelta::Max())); 953 EXPECT_TRUE(IsMin(-TimeDelta::Max()));
980 EXPECT_GT(TimeDelta(), -TimeDelta::Max()); 954 EXPECT_GT(TimeDelta(), -TimeDelta::Max());
981 955
982 TimeDelta large_delta = TimeDelta::Max() - TimeDelta::FromMilliseconds(1); 956 TimeDelta large_delta = TimeDelta::Max() - TimeDelta::FromMilliseconds(1);
983 TimeDelta large_negative = -large_delta; 957 TimeDelta large_negative = -large_delta;
984 EXPECT_GT(TimeDelta(), large_negative); 958 EXPECT_GT(TimeDelta(), large_negative);
985 EXPECT_FALSE(large_delta.is_max()); 959 EXPECT_FALSE(large_delta.is_max());
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
1120 1094
1121 TEST(TimeTicksLogging, DoesNotMakeStreamBad) { 1095 TEST(TimeTicksLogging, DoesNotMakeStreamBad) {
1122 std::ostringstream oss; 1096 std::ostringstream oss;
1123 oss << TimeTicks(); 1097 oss << TimeTicks();
1124 EXPECT_TRUE(oss.good()); 1098 EXPECT_TRUE(oss.good());
1125 } 1099 }
1126 1100
1127 } // namespace 1101 } // namespace
1128 1102
1129 } // namespace base 1103 } // namespace base
OLDNEW
« no previous file with comments | « base/time/time.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698