forked from jquery/testswarm
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTestSwarm.php
208 lines (184 loc) · 5.72 KB
/
TestSwarm.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
<?php
/**
* Wrapper class containing various request-specific objects.
* Each of these objects is created only once for the context.
* The creation happends on-demand and is put in a private cache.
*
* @author Timo Tijhof, 2012
* @since 1.0.0
* @package TestSwarm
*/
class TestSwarmContext {
protected $browserInfo, $conf, $db, $request, $versionInfo;
/**
* The context is self-initializing. The only thing it needs to be passed is
* an object with all setting keys from testswarm-defaults.json. Logic for
* loading defaults and overriding with local settings is in inc/init.php
* @param $config
*/
public function __construct( stdClass $config ) {
$this->conf = $config;
}
public function getBrowserInfo() {
if ( $this->browserInfo === null ) {
$ua = isset( $_SERVER['HTTP_USER_AGENT'] ) ? $_SERVER['HTTP_USER_AGENT'] : '';
$this->browserInfo = BrowserInfo::newFromContext( $this, $ua );
}
return $this->browserInfo;
}
/**
* Get the configuration object
* @return stdClass
*/
public function getConf() {
return $this->conf;
}
/**
* Get the Database object
* @return Database
*/
public function getDB() {
if ( $this->db === null ) {
// Check if there is a database lock
$lock = $this->dbLock();
if ( $lock ) {
throw new SwarmException(
'Database is temporarily locked for maintenance (since: '
. strftime( '%c', $lock ) . ')'
);
}
$this->db = Database::newFromContext( $this );
}
return $this->db;
}
/**
* Get and set the lock status.
* @param $change bool: [optional] Change the lock state.
* @return bool|int Boolean false or a timestamp of when the lock was set.
*/
public function dbLock( $change = null ) {
$dbLockFile = $this->getConf()->storage->cacheDir . '/database.lock';
$dbLocktime = false;
if ( is_bool( $change ) ) {
if ( $change ) {
$done = @touch( $dbLockFile );
} else {
$done = @unlink( $dbLockFile );
}
if ( !$done ) {
throw new SwarmException( 'Unable to change database.lock' );
}
}
if ( file_exists( $dbLockFile ) ) {
$dbLocktime = @filemtime( $dbLockFile );
}
return $dbLocktime;
}
/**
* Get the WebRequest object
* @return WebRequest
*/
public function getRequest() {
if ( $this->request === null ) {
$this->request = WebRequest::newFromContext( $this );
}
return $this->request;
}
public function createDerivedRequestContext( Array $query = array(), $method = 'GET' ) {
$derivContext = clone $this;
$req = DerivativeWebRequest::newFromContext( $derivContext );
$req->setRawQuery( $query );
$req->setWasPosted( $method === 'POST' );
$derivContext->request = $req;
return $derivContext;
}
/**
* Get the current TestSwarm version (cached for 5 minutes).
*
* @param $options string|array: 'bypass-cache'
* @return array (see also calculateVersionInfo)
*/
public function getVersionInfo( $options = array() ) {
$options = (array)$options;
if ( in_array( 'bypass-cache', $options ) ) {
return $this->calculateVersionInfo();
}
// Cache within the class, never calculate more than once per request
if ( $this->versionInfo !== null ) {
return $this->versionInfo;
}
// Deal with cache expiration
$versionCacheFile = $this->getConf()->storage->cacheDir . '/version_info.json';
if ( is_readable( $versionCacheFile ) ) {
$versionCacheFileUpdated = filemtime( $versionCacheFile );
if ( $versionCacheFileUpdated < strtotime( '5 minutes ago' ) ) {
unlink( $versionCacheFile );
}
}
// If cache file (still) exists it means we can use it
if ( is_readable( $versionCacheFile ) ) {
$this->versionInfo = json_decode( file_get_contents( $versionCacheFile ), /*assoc=*/true );
return $this->versionInfo;
}
// Calculate it and populate the class cache and file cache
$this->versionInfo = $this->calculateVersionInfo();
$isWritten = file_put_contents( $versionCacheFile, json_encode( $this->versionInfo ) );
if ( $isWritten === false ) {
throw new SwarmException( 'Writing to cache directory failed.' );
}
return $this->versionInfo;
}
/**
* Compute the version of this TestSwarm install, including the Git hash
* if the installation directory contains a git repository.
* @since 1.0.0
*
* @return array
*/
protected function calculateVersionInfo() {
global $swarmInstallDir;
$baseVersionFile = "$swarmInstallDir/config/version.ini";
if ( !is_readable( $baseVersionFile ) ) {
throw new SwarmException( 'version.ini is missing or unreadable.' );
}
$swarmVersion = trim( file_get_contents( $baseVersionFile ) );
$devInfo = null;
// If this is a git repository, get a hold of the HEAD SHA1 hash as well,
// and append it to the version.
$gitHeadFile = "$swarmInstallDir/.git/HEAD";
if ( is_readable( $gitHeadFile ) ) {
// Get HEAD
$gitHeadFileCnt = file_get_contents( $gitHeadFile );
if ( preg_match( '/ref: (.*)/', $gitHeadFileCnt, $matches ) ) {
$gitHead = trim( $matches[1] );
} else {
$gitHead = trim( $gitHead );
}
// Get current branch
if ( $gitHead && preg_match( "#^refs/heads/(.*)$#", $gitHead, $m ) ) {
// If it is a simple head, only return the heads name
$gitBranch = $m[1];
} else {
// Otherwise it is something else, for which we'll show the full name
$gitBranch = $gitHead;
}
// Get SHA1
$gitRefFile = "$swarmInstallDir/.git/$gitHead";
if ( is_readable( $gitRefFile ) ) {
$gitSHA1 = trim( file_get_contents( $gitRefFile ) );
} else {
// If such refs file doesn't exist, HEAD is detached,
// in which case ./.git/HEAD contains the SHA1 directly.
$gitSHA1 = $gitHead;
}
$devInfo = array(
'branch' => $gitBranch,
'SHA1' => $gitSHA1,
);
}
return array(
'TestSwarm' => $swarmVersion,
'devInfo' => $devInfo,
);
}
}