Skip to content
This repository
Browse code

Mark DBDatetimeTest skipped on wrong offsets, rather than error out.

While well-intentioned, this test keeps causing problems
due to wrong timezone settings in test mode.
It shouldn't completely abort test execution,
since its more of an environment sanity check than a failed test.

Refactored to mark test skipped (regardless of offset, as long as
its greater than 5 seconds). And skipping tests altogether
on SQLite3 with new supportsTimezoneOverride() check.
SapphireTest->setUp() sets the PHP timezone to UTC (see 5954774),
but SQLite doesn't support this for a DB connection.
Since changing it on a global UNIX system level is infeasible,
the tests need to be skipped.
  • Loading branch information...
commit 664903433deea72c2ae0f0e644587a1e911d5080 1 parent 683d420
Ingo Schommer authored July 05, 2012

Showing 1 changed file with 82 additions and 86 deletions. Show diff stats Hide diff stats

  1. 168  tests/model/DbDatetimeTest.php
168  tests/model/DbDatetimeTest.php
@@ -6,20 +6,16 @@ class DbDatetimeTest extends FunctionalTest {
6 6
 	
7 7
 	protected $extraDataObjects = array('DbDatetimeTest_Team');
8 8
 
9  
-	private static $offset = 0;					// number of seconds of php and db time are out of sync
10  
-	private static $offset_thresholds = array(	// throw an error if the offset exceeds 30 minutes
11  
-		E_USER_ERROR => 1800,
12  
-		E_USER_NOTICE => 5,
13  
-	);
  9
+	protected $offset;
  10
+
  11
+	protected $adapter;
14 12
 
15  
-	private $adapter;
16  
-	
17 13
 	/**
18 14
 	 * Check if dates match more or less. This takes into the account the db query
19 15
 	 * can overflow to the next second giving offset readings.
20 16
 	 */
21  
-	private function matchesRoughly($date1, $date2, $comment = '') {
22  
-		$allowedDifference = 5 + abs(self::$offset); // seconds
  17
+	private function matchesRoughly($date1, $date2, $comment = '', $offset) {
  18
+		$allowedDifference = 5 + abs($offset); // seconds
23 19
 		
24 20
 		$time1 = is_numeric($date1) ? $date1 : strtotime($date1);
25 21
 		$time2 = is_numeric($date2) ? $date2 : strtotime($date2);
@@ -31,104 +27,104 @@ private function getDbNow() {
31 27
 		$query = 'SELECT ' . $this->adapter->formattedDatetimeClause('now', '%U');
32 28
 		return DB::query($query)->value();
33 29
 	}
34  
-	
35  
-	function setUpOnce() {
36  
-		parent::setUpOnce();
37  
-
38  
-		self::$offset = time() - strtotime(DB::query('SELECT ' . DB::getConn()->now())->value());
39  
-		foreach(self::$offset_thresholds as $code => $offset) {
40  
-			if(abs(self::$offset) > $offset) {
41  
-				if($code == E_USER_NOTICE) {
42  
-					Debug::show('The time of the database is out of sync with the webserver by ' . abs(self::$offset) . ' seconds.');
43  
-				} else {
44  
-					trigger_error('The time of the database is out of sync with the webserver by ' . abs(self::$offset) . ' seconds.', $code);
45  
-				}
46  
-				break;
47  
-			}
  30
+
  31
+	/**
  32
+	 * Needs to be run within a test*() context.
  33
+	 *
  34
+	 * @return Int Offset in seconds
  35
+	 */
  36
+	private function checkPreconditions() {
  37
+		// number of seconds of php and db time are out of sync
  38
+		$offset = time() - strtotime(DB::query('SELECT ' . DB::getConn()->now())->value());
  39
+		$threshold = 5; // seconds
  40
+
  41
+		if($offset > 5) {
  42
+			$this->markTestSkipped('The time of the database is out of sync with the webserver by ' . abs($offset) . ' seconds.');
  43
+		}
  44
+
  45
+		if(method_exists($this->adapter, 'supportsTimezoneOverride') && !$this->adapter->supportsTimezoneOverride()) {
  46
+			$this->markTestSkipped("Database doesn't support timezone overrides");
48 47
 		}
  48
+
  49
+		return $offset;
49 50
 	}
50 51
 
51 52
 	function setUp() {
52 53
 		parent::setUp();
53 54
 		$this->adapter = DB::getConn();
54  
-		$this->supportDbDatetime = method_exists($this->adapter, 'datetimeIntervalClause');
55 55
 	}
56 56
 
57 57
 	function testCorrectNow() {
58  
-		if($this->supportDbDatetime) {
59  
-			$clause = $this->adapter->formattedDatetimeClause('now', '%U');
60  
-			$result = DB::query('SELECT ' . $clause)->value();
61  
-			$this->assertRegExp('/^\d*$/', (string) $result);
62  
-			$this->assertTrue($result>0);
63  
-		}
  58
+		$offset = $this->checkPreconditions();
  59
+
  60
+		$clause = $this->adapter->formattedDatetimeClause('now', '%U');
  61
+		$result = DB::query('SELECT ' . $clause)->value();
  62
+		$this->assertRegExp('/^\d*$/', (string) $result);
  63
+		$this->assertTrue($result>0);
64 64
 	}
65 65
 
66 66
 	function testDbDatetimeFormat() {
67  
-		if($this->supportDbDatetime) {
68  
-			$clause = $this->adapter->formattedDatetimeClause('1973-10-14 10:30:00', '%H:%i, %d/%m/%Y');
69  
-			$result = DB::query('SELECT ' . $clause)->value();
70  
-			$this->matchesRoughly($result, date('H:i, d/m/Y', strtotime('1973-10-14 10:30:00')), 'nice literal time');
71  
-
72  
-			$clause = $this->adapter->formattedDatetimeClause('now', '%d');
73  
-			$result = DB::query('SELECT ' . $clause)->value();
74  
-			$this->matchesRoughly($result, date('d', $this->getDbNow()), 'todays day');
75  
-
76  
-			$clause = $this->adapter->formattedDatetimeClause('"Created"', '%U') . ' AS test FROM "DbDateTimeTest_Team"';
77  
-			$result = DB::query('SELECT ' . $clause)->value();
78  
-			$this->matchesRoughly($result, strtotime(DataObject::get_one('DbDateTimeTest_Team')->Created), 'fixture ->Created as timestamp');
79  
-		}
  67
+		$offset = $this->checkPreconditions();
  68
+
  69
+		$clause = $this->adapter->formattedDatetimeClause('1973-10-14 10:30:00', '%H:%i, %d/%m/%Y');
  70
+		$result = DB::query('SELECT ' . $clause)->value();
  71
+		$this->matchesRoughly($result, date('H:i, d/m/Y', strtotime('1973-10-14 10:30:00')), 'nice literal time', $offset);
  72
+
  73
+		$clause = $this->adapter->formattedDatetimeClause('now', '%d');
  74
+		$result = DB::query('SELECT ' . $clause)->value();
  75
+		$this->matchesRoughly($result, date('d', $this->getDbNow()), 'todays day', $offset);
  76
+
  77
+		$clause = $this->adapter->formattedDatetimeClause('"Created"', '%U') . ' AS test FROM "DbDateTimeTest_Team"';
  78
+		$result = DB::query('SELECT ' . $clause)->value();
  79
+		$this->matchesRoughly($result, strtotime(DataObject::get_one('DbDateTimeTest_Team')->Created), 'fixture ->Created as timestamp', $offset);
80 80
 	}
81 81
 	
82 82
 	function testDbDatetimeInterval() {
83  
-		if($this->supportDbDatetime) {
84  
-
85  
-			$clause = $this->adapter->datetimeIntervalClause('1973-10-14 10:30:00', '+18 Years');
86  
-			$result = DB::query('SELECT ' . $clause)->value();
87  
-			$this->matchesRoughly($result, '1991-10-14 10:30:00', 'add 18 years');
  83
+		$offset = $this->checkPreconditions();
88 84
 
89  
-			$clause = $this->adapter->datetimeIntervalClause('now', '+1 Day');
90  
-			$result = DB::query('SELECT ' . $clause)->value();
91  
-			$this->matchesRoughly($result, date('Y-m-d H:i:s', strtotime('+1 Day', $this->getDbNow())), 'tomorrow');
  85
+		$clause = $this->adapter->datetimeIntervalClause('1973-10-14 10:30:00', '+18 Years');
  86
+		$result = DB::query('SELECT ' . $clause)->value();
  87
+		$this->matchesRoughly($result, '1991-10-14 10:30:00', 'add 18 years', $offset);
92 88
 
93  
-			$query = new SQLQuery();
94  
-			$query->setSelect(array());
95  
-			$query->selectField($this->adapter->datetimeIntervalClause('"Created"', '-15 Minutes'), 'test')
96  
-				->setFrom('"DbDateTimeTest_Team"')
97  
-				->setLimit(1);
  89
+		$clause = $this->adapter->datetimeIntervalClause('now', '+1 Day');
  90
+		$result = DB::query('SELECT ' . $clause)->value();
  91
+		$this->matchesRoughly($result, date('Y-m-d H:i:s', strtotime('+1 Day', $this->getDbNow())), 'tomorrow', $offset);
98 92
 
99  
-			$result = $query->execute()->value();
100  
-			$this->matchesRoughly($result, date('Y-m-d H:i:s', strtotime(DataObject::get_one('DbDateTimeTest_Team')->Created) - 900), '15 Minutes before creating fixture');
  93
+		$query = new SQLQuery();
  94
+		$query->setSelect(array());
  95
+		$query->selectField($this->adapter->datetimeIntervalClause('"Created"', '-15 Minutes'), 'test')
  96
+			->setFrom('"DbDateTimeTest_Team"')
  97
+			->setLimit(1);
101 98
 
102  
-		}
  99
+		$result = $query->execute()->value();
  100
+		$this->matchesRoughly($result, date('Y-m-d H:i:s', strtotime(DataObject::get_one('DbDateTimeTest_Team')->Created) - 900), '15 Minutes before creating fixture', $offset);
103 101
 	}
104 102
 	
105 103
 	function testDbDatetimeDifference() {
106  
-		if($this->supportDbDatetime) {
107  
-
108  
-			$clause = $this->adapter->datetimeDifferenceClause('1974-10-14 10:30:00', '1973-10-14 10:30:00');
109  
-			$result = DB::query('SELECT ' . $clause)->value();
110  
-			$this->matchesRoughly($result/86400, 365, '1974 - 1973 = 365 * 86400 sec');
111  
-
112  
-			$clause = $this->adapter->datetimeDifferenceClause(date('Y-m-d H:i:s', strtotime('-15 seconds')), 'now');
113  
-			$result = DB::query('SELECT ' . $clause)->value();
114  
-			$this->matchesRoughly($result, -15, '15 seconds ago - now');
115  
-
116  
-			$clause = $this->adapter->datetimeDifferenceClause('now', $this->adapter->datetimeIntervalClause('now', '+45 Minutes'));
117  
-			$result = DB::query('SELECT ' . $clause)->value();
118  
-			$this->matchesRoughly($result, -45 * 60, 'now - 45 minutes ahead');
119  
-
120  
-			$query = new SQLQuery();
121  
-			$query->setSelect(array());
122  
-			$query->selectField($this->adapter->datetimeDifferenceClause('"LastEdited"', '"Created"'), 'test')
123  
-				->setFrom('"DbDateTimeTest_Team"')
124  
-				->setLimit(1);
125  
-
126  
-			$result = $query->execute()->value();
127  
-			$lastedited = Dataobject::get_one('DbDateTimeTest_Team')->LastEdited;
128  
-			$created = Dataobject::get_one('DbDateTimeTest_Team')->Created;
129  
-			$this->matchesRoughly($result, strtotime($lastedited) - strtotime($created), 'age of HomePage record in seconds since unix epoc');
130  
-
131  
-		}
  104
+		$offset = $this->checkPreconditions();
  105
+
  106
+		$clause = $this->adapter->datetimeDifferenceClause('1974-10-14 10:30:00', '1973-10-14 10:30:00');
  107
+		$result = DB::query('SELECT ' . $clause)->value();
  108
+		$this->matchesRoughly($result/86400, 365, '1974 - 1973 = 365 * 86400 sec', $offset);
  109
+
  110
+		$clause = $this->adapter->datetimeDifferenceClause(date('Y-m-d H:i:s', strtotime('-15 seconds')), 'now');
  111
+		$result = DB::query('SELECT ' . $clause)->value();
  112
+		$this->matchesRoughly($result, -15, '15 seconds ago - now', $offset);
  113
+
  114
+		$clause = $this->adapter->datetimeDifferenceClause('now', $this->adapter->datetimeIntervalClause('now', '+45 Minutes'));
  115
+		$result = DB::query('SELECT ' . $clause)->value();
  116
+		$this->matchesRoughly($result, -45 * 60, 'now - 45 minutes ahead', $offset);
  117
+
  118
+		$query = new SQLQuery();
  119
+		$query->setSelect(array());
  120
+		$query->selectField($this->adapter->datetimeDifferenceClause('"LastEdited"', '"Created"'), 'test')
  121
+			->setFrom('"DbDateTimeTest_Team"')
  122
+			->setLimit(1);
  123
+
  124
+		$result = $query->execute()->value();
  125
+		$lastedited = Dataobject::get_one('DbDateTimeTest_Team')->LastEdited;
  126
+		$created = Dataobject::get_one('DbDateTimeTest_Team')->Created;
  127
+		$this->matchesRoughly($result, strtotime($lastedited) - strtotime($created), 'age of HomePage record in seconds since unix epoc', $offset);
132 128
 	}
133 129
 	
134 130
 }
@@ -137,4 +133,4 @@ class DbDateTimeTest_Team extends DataObject implements TestOnly {
137 133
 	static $db = array(
138 134
 		'Title' => 'Varchar'
139 135
 	);
140  
-}
  136
+}

0 notes on commit 6649034

Please sign in to comment.
Something went wrong with that request. Please try again.