1<?php
2
3/*
4	Phoronix Test Suite
5	URLs: http://www.phoronix.com, http://www.phoronix-test-suite.com/
6	Copyright (C) 2008 - 2020, Phoronix Media
7	Copyright (C) 2008 - 2020, Michael Larabel
8
9	This program is free software; you can redistribute it and/or modify
10	it under the terms of the GNU General Public License as published by
11	the Free Software Foundation; either version 3 of the License, or
12	(at your option) any later version.
13
14	This program is distributed in the hope that it will be useful,
15	but WITHOUT ANY WARRANTY; without even the implied warranty of
16	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17	GNU General Public License for more details.
18
19	You should have received a copy of the GNU General Public License
20	along with this program. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23class pts_installed_test
24{
25	private $footnote_override = null;
26	private $install_path = null;
27	private $installed = false;
28
29	private $install_date_time = null;
30	private $last_run_date_time = null;
31	private $installed_version = null;
32	private $average_runtime = null;
33	private $last_runtime = null;
34	private $last_install_time = null;
35	private $times_run = 0;
36	private $compiler_data = null;
37	private $install_footnote = null;
38	private $install_checksum = null;
39	private $system_hash = null;
40	private $associated_test_identifier = null;
41	private $per_run_times = null;
42
43	public function __construct(&$test_profile)
44	{
45		$this->install_path = $test_profile->get_install_dir();
46
47		if(is_file($this->install_path . 'pts-install.json'))
48		{
49			$this->installed = true;
50			$jsonf = json_decode(file_get_contents($this->install_path . 'pts-install.json'), true);
51			$this->install_date_time = isset($jsonf['test_installation']['history']['install_date_time']) ? $jsonf['test_installation']['history']['install_date_time'] : null;
52			$this->last_run_date_time = isset($jsonf['test_installation']['history']['last_run_date_time']) ? $jsonf['test_installation']['history']['last_run_date_time'] : null;
53			$this->installed_version = isset($jsonf['test_installation']['environment']['test_version']) ? $jsonf['test_installation']['environment']['test_version'] : null;
54			$this->average_runtime = isset($jsonf['test_installation']['history']['average_runtime']) ? $jsonf['test_installation']['history']['average_runtime'] : null;
55			$this->last_runtime = isset($jsonf['test_installation']['history']['latest_runtime']) ? $jsonf['test_installation']['history']['latest_runtime'] : null;
56			$this->last_install_time = isset($jsonf['test_installation']['history']['install_time_length']) ? $jsonf['test_installation']['history']['install_time_length'] : null;
57			$this->times_run = isset($jsonf['test_installation']['history']['times_run']) ? $jsonf['test_installation']['history']['times_run'] : 0;
58			$this->per_run_times = isset($jsonf['test_installation']['history']['per_run_times']) ? $jsonf['test_installation']['history']['per_run_times'] : array();
59			$this->compiler_data = isset($jsonf['test_installation']['environment']['compiler_data']) ? $jsonf['test_installation']['environment']['compiler_data'] : null;
60			$this->install_footnote = isset($jsonf['test_installation']['environment']['install_footnote']) ? $jsonf['test_installation']['environment']['install_footnote'] : null;
61			$this->install_checksum = isset($jsonf['test_installation']['environment']['install_checksum']) ? $jsonf['test_installation']['environment']['install_checksum'] : null;
62			$this->system_hash = isset($jsonf['test_installation']['environment']['system_hash']) ? $jsonf['test_installation']['environment']['system_hash'] : null;
63			$this->associated_test_identifier = isset($jsonf['test_installation']['environment']['test_identifier']) ? $jsonf['test_installation']['environment']['test_identifier'] : null;
64		}
65		else if(is_file($this->install_path . 'pts-install.xml'))
66		{
67			// Fallback to pre PTS 10.2 XML based data
68			// Around PTS11 this path will likely be dropped....
69			$this->installed = true;
70			$xml_options = LIBXML_COMPACT | LIBXML_PARSEHUGE;
71			$xml = simplexml_load_file($this->install_path . 'pts-install.xml', 'SimpleXMLElement', $xml_options);
72			$this->install_date_time = isset($xml->TestInstallation->History->InstallTime) ? $xml->TestInstallation->History->InstallTime->__toString() : null;
73			$this->last_run_date_time = isset($xml->TestInstallation->History->LastRunTime) ? $xml->TestInstallation->History->LastRunTime->__toString() : null;
74			$this->installed_version = isset($xml->TestInstallation->Environment->Version) ? $xml->TestInstallation->Environment->Version->__toString() : null;
75			$this->average_runtime = isset($xml->TestInstallation->History->AverageRunTime) ? $xml->TestInstallation->History->AverageRunTime->__toString() : null;
76			$this->last_runtime = isset($xml->TestInstallation->History->LatestRunTime) ? $xml->TestInstallation->History->LatestRunTime->__toString() : null;
77			$this->last_install_time = isset($xml->TestInstallation->History->InstallTimeLength) ? $xml->TestInstallation->History->InstallTimeLength->__toString() : null;
78			$this->times_run = isset($xml->TestInstallation->History->TimesRun) ? $xml->TestInstallation->History->TimesRun->__toString() : 0;
79			$this->compiler_data = isset($xml->TestInstallation->Environment->CompilerData) ? json_decode($xml->TestInstallation->Environment->CompilerData->__toString(), true) : null;
80			$this->install_footnote = isset($xml->TestInstallation->Environment->InstallFootnote) ? $xml->TestInstallation->Environment->InstallFootnote->__toString() : null;
81			$this->install_checksum = isset($xml->TestInstallation->Environment->CheckSum) ? $xml->TestInstallation->Environment->CheckSum->__toString() : null;
82			$this->system_hash = isset($xml->TestInstallation->Environment->SystemIdentifier) ? $xml->TestInstallation->Environment->SystemIdentifier->__toString() : null;
83			$this->associated_test_identifier = isset($xml->TestInstallation->Environment->Identifier) ? $xml->TestInstallation->Environment->Identifier->__toString() : null;
84		}
85	}
86	public function save_test_install_metadata()
87	{
88		// Refresh/generate an PTS install file
89
90		// JSON output
91
92		$to_json = array();
93		$to_json['test_installation']['environment']['test_identifier'] = $this->get_associated_test_identifier();
94		$to_json['test_installation']['environment']['test_version'] = $this->get_installed_version();
95		$to_json['test_installation']['environment']['install_checksum'] = $this->get_installed_checksum();
96		$to_json['test_installation']['environment']['system_hash'] = $this->get_system_hash();
97		$to_json['test_installation']['environment']['compiler_data'] = $this->get_compiler_data();
98		$to_json['test_installation']['environment']['install_footnote'] = $this->get_install_footnote();
99		$to_json['test_installation']['history']['install_date_time'] = $this->get_install_date_time();
100		$to_json['test_installation']['history']['last_run_date_time'] = $this->get_last_run_date_time();
101		$to_json['test_installation']['history']['install_time_length'] = $this->get_latest_install_time();
102		$to_json['test_installation']['history']['times_run'] = $this->get_run_count();
103		$to_json['test_installation']['history']['average_runtime'] = $this->get_average_run_time();
104		$to_json['test_installation']['history']['latest_runtime'] = $this->get_latest_run_time();
105		$to_json['test_installation']['history']['per_run_times'] = $this->get_per_run_times();
106		file_put_contents($this->install_path . 'pts-install.json', json_encode($to_json, JSON_PRETTY_PRINT));
107
108		// The pts-install.xml XML file is traditionally how PTS install metadata was installed...
109		// With PTS 10.2, JSON is preferred for storing the data more easily
110		// But continue generating the install XML for backwards compatibility and for parts of PTS checking for 'pts-install.xml' to determine if test installed, etc.
111		// But PTS 10.2+ will use the data actually stored in the JSON file....
112		// TODO XXX PTS 11.0 or so drop the pts-install.xml and use just pts-install.json
113
114		$xml_writer = new nye_XmlWriter();
115		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/Environment/Identifier', $this->get_associated_test_identifier());
116		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/Environment/Version', $this->get_installed_version());
117		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/Environment/CheckSum', $this->get_installed_checksum());
118		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/Environment/CompilerData', json_encode($this->get_compiler_data()));
119		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/Environment/InstallFootnote', $this->get_install_footnote());
120		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/Environment/SystemIdentifier', $this->get_system_hash());
121		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/History/InstallTime', $this->get_install_date_time());
122		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/History/InstallTimeLength', $this->get_latest_install_time());
123		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/History/LastRunTime', $this->get_last_run_date_time());
124		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/History/TimesRun', $this->get_run_count());
125		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/History/AverageRunTime', $this->get_average_run_time());
126		$xml_writer->addXmlNode('PhoronixTestSuite/TestInstallation/History/LatestRunTime', $this->get_latest_run_time());
127		$xml_writer->saveXMLFile($this->install_path . 'pts-install.xml');
128	}
129	public function is_installed()
130	{
131		return $this->installed;
132	}
133	public function get_install_log_location()
134	{
135		return $this->install_path . 'install.log';
136	}
137	public function get_associated_test_identifier()
138	{
139		return $this->associated_test_identifier;
140	}
141	public function has_install_log()
142	{
143		return is_file($this->get_install_log_location());
144	}
145	public function get_install_date_time()
146	{
147		return $this->install_date_time;
148	}
149	public function get_install_date()
150	{
151		return substr($this->get_install_date_time(), 0, 10);
152	}
153	public function get_last_run_date_time()
154	{
155		return $this->last_run_date_time;
156	}
157	public function get_last_run_date()
158	{
159		return !empty($this->last_run_date_time) ? substr($this->last_run_date_time, 0, 10) : '';
160	}
161	public function get_installed_version()
162	{
163		return $this->installed_version;
164	}
165	public function get_average_run_time()
166	{
167		return $this->average_runtime;
168	}
169	public function get_latest_run_time()
170	{
171		return $this->last_runtime;
172	}
173	public function get_per_run_times()
174	{
175		return $this->per_run_times;
176	}
177	public function get_latest_install_time()
178	{
179		return $this->last_install_time;
180	}
181	public function get_run_count()
182	{
183		return $this->times_run;
184	}
185	public function get_compiler_data()
186	{
187		return $this->compiler_data;
188	}
189	public function get_install_footnote()
190	{
191		return !empty($this->footnote_override) ? $this->footnote_override : $this->install_footnote;
192	}
193	public function set_install_footnote($f = null)
194	{
195		return $this->footnote_override = $f;
196	}
197	public function get_installed_checksum()
198	{
199		return $this->install_checksum;
200	}
201	public function get_system_hash()
202	{
203		return $this->system_hash;
204	}
205	public function get_install_size()
206	{
207		$install_size = 0;
208
209		if(pts_client::executable_in_path('du'))
210		{
211			$du = trim(shell_exec('du -sk ' . $this->install_path . ' 2>&1'));
212			$du = substr($du, 0, strpos($du, "\t"));
213			if(is_numeric($du) && $du > 1)
214			{
215				$install_size = $du;
216			}
217		}
218
219		return $install_size;
220	}
221	public function update_install_time($t)
222	{
223		$this->last_install_time = ceil($t);
224	}
225	public function add_latest_run_time(&$test_result_obj, $t)
226	{
227		$this->last_runtime = ceil($t);
228		$this->times_run++;
229		$this->last_run_date_time = date('Y-m-d H:i:s');
230		$individual_run_times = $test_result_obj->test_run_times;
231
232		if(!empty($individual_run_times))
233		{
234			$per_run_avg = ceil(array_sum($individual_run_times) / count($individual_run_times));
235			$this->add_to_run_times($this->per_run_times, 'all', $per_run_avg);
236			$this->add_to_run_times($this->per_run_times, $test_result_obj->get_comparison_hash(true, false), $per_run_avg, $test_result_obj->get_arguments_description());
237			$this->average_runtime = $this->get_average_time_per_run('all') * $test_result_obj->test_profile->get_default_times_to_run();
238		}
239	}
240	public function get_average_time_per_run($index, $fallback_value = 0)
241	{
242		return isset($this->per_run_times[$index]['avg']) && $this->per_run_times[$index]['avg'] > 0 ? $this->per_run_times[$index]['avg'] : $fallback_value;
243	}
244	protected function add_to_run_times(&$run_times, $index, $value, $description = null)
245	{
246		if(is_array($run_times) && count($run_times) > 80)
247		{
248			// Only show the last 80 to avoid this file becoming too large...
249			$all = $run_times['all'];
250			$run_times = array_slice($run_times, -80, null, true);
251			$run_times['all'] = $all;
252		}
253
254		if(!isset($run_times[$index]))
255		{
256			$run_times[$index] = array();
257			$run_times[$index]['values'] = array();
258			$run_times[$index]['total_times'] = 0;
259		}
260
261		if($description != null)
262		{
263			$run_times[$index]['desc'] = $description;
264		}
265
266		$run_times[$index]['total_times']++;
267		array_unshift($run_times[$index]['values'], $value);
268
269		if(isset($run_times[$index]['values'][20]))
270		{
271			$run_times[$index]['values'] = array_slice($run_times[$index]['values'], 0, 20);
272		}
273		$run_times[$index]['avg'] = ceil(array_sum($run_times[$index]['values']) / count($run_times[$index]['values']));
274	}
275	public function update_install_data(&$test_profile, $compiler_data, $install_footnote)
276	{
277		$this->compiler_data = $compiler_data;
278		$this->install_footnote = $install_footnote;
279		$this->associated_test_identifier = $test_profile->get_identifier();
280		$this->installed_version = $test_profile->get_test_profile_version();
281		$this->install_checksum = $test_profile->get_installer_checksum();
282		$this->system_hash = phodevi::system_id_string();
283		$this->install_date_time = date('Y-m-d H:i:s');
284	}
285}
286
287?>
288