stub out a dashboard
not pretty at all, but seems functional
ADD
scripts/gen-dashboard.php
+<?php
+// Copyright (c) 2018-present The Alive2 Authors.
+// Distributed under the MIT license that can be found in the LICENSE file.
+
+$dump = @$argv[1];
+$logsdir = @$argv[2];
+
+if (!$dump || !$logsdir || !is_file($dump) || !is_dir($logsdir))
+ die("usage: php gen-dashboard.php <dump.txt> <logs>\n");
+
+$dump = file_get_contents($dump);
+preg_match('/\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\nFailing Tests \((\d+)\):\n(.*)/Ss', $dump, $m);
+
+$num_failures = (int)$m[1];
+echo "Failures:\t\t$num_failures\n";
+
+preg_match_all('/LLVM ::\s*(\S+)/S', $m[2], $m);
+$test_failures = $m[1];
+
+@mkdir('web');
+@mkdir('web/data');
+@mkdir('web/data/logs');
+
+$fail_without_undef = 0;
+
+foreach ($test_failures as $test) {
+ if (!preg_match('@'.$test.'\' FAILED \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\n'.
+ 'Script:\n.*?Exit Code:[^\n]+\n\n'.
+ '(?:Command Output \(stdout\):\n--.*?\n--\n)?'.
+ 'Command Output \(stderr\):\n--(.*?)\n--\n@Ss', $dump, $m)) {
+ die("Failed to get data for $test\n");
+ }
+
+ $stderr = store_log(preg_replace('/Report written to \S+/S', '', $m[1]));
+
+ preg_match('/Report written to (\S+)/S', $m[1], $m);
+ $log = store_log(empty($m[1]) ? '' : file_get_contents($m[1]));
+
+ // TODO: check if correct without undef
+ $ok_wo_undef = correct_without_undef($test);
+ if (!$ok_wo_undef)
+ ++$fail_without_undef;
+ $tests[] = array($test, $ok_wo_undef, $stderr, $log);
+}
+
+echo "Failures wo undef:\t$fail_without_undef\n";
+
+$tests_csv = '';
+foreach ($tests as $t) {
+ $tests_csv .= implode(',', $t) . "\n";
+}
+
+$tests_csv = store_log($tests_csv);
+$alive_git = implode(',', git_info('~/alive2'));
+$llvm_git = implode(',', git_info('~/llvm'));
+$entry = "$tests_csv,$num_failures,$fail_without_undef,$alive_git,$llvm_git\n";
+
+file_put_contents('web/data/data.txt', $entry, FILE_APPEND);
+
+
+function correct_without_undef($test) {
+ echo "Testing $test without undef\n";
+ $output = `~/llvm/build/bin/llvm-lit -vv -Dopt="\$HOME/alive2/scripts/opt-alive.sh -tv-disable-undef-input" ~/llvm/llvm/test/$test 2>&1`;
+ return strstr($output, 'Expected Passes : 1') !== false;
+}
+
+function store_log($txt) {
+ $md5 = substr(md5($txt), 0, 16);
+ file_put_contents("web/data/logs/$md5.txt", $txt);
+ return $md5;
+}
+
+// returns [hash, timestamp]
+function git_info($dir) {
+ return explode(' ', trim(`cd $dir && git show -q --format='%h %ct'`));
+}

ADD
web/include.php
+<?php
+// Copyright (c) 2018-present The Alive2 Authors.
+// Distributed under the MIT license that can be found in the LICENSE file.
+
+function html_header($title) {
+ echo <<< HTML
+<!DOCTYPE html>
+<html>
+<head>
+<title>Alive2: $title</title>
+<script src="https://cdn.jsdelivr.net/npm/chart.js@2/dist/Chart.min.js"></script>
+<style>
+table {
+ border-collapse: collapse
+}
+
+table, th, td {
+ border: 1px solid black
+}
+</style>
+</head>
+<body>
+<h1>$title</h1>
+
+HTML;
+}
+
+function html_footer() {
+ echo <<< HTML
+</body>
+</html>
+
+HTML;
+}

ADD
web/index.php
+<?php
+// Copyright (c) 2018-present The Alive2 Authors.
+// Distributed under the MIT license that can be found in the LICENSE file.
+
+include 'include.php';
+
+// 0: tests_csv, 1: num_failures, 2: fail_without_undef, 3: alive_git_hash,
+// 4: alive_git_time, 5: llvm_git_hash, 6: llvm_git_time
+$data = array();
+foreach (file('data/data.txt') as $entry) {
+ $data[] = explode(',', trim($entry));
+}
+
+$hash = @$_GET['hash'];
+$test = @$_GET['test'];
+
+if ($hash && $test) {
+ $run = get_all_runs($data, $hash);
+ $tests = get_run_tests($run[0]);
+ foreach ($tests as $t) {
+ if ($t[0] === $test)
+ break;
+ }
+
+ html_header("Test Failure: " . htmlspecialchars($t[0]));
+
+ echo "<h2>Log:</h2>\n<pre>";
+ echo htmlspecialchars(file_get_contents("data/logs/$t[3].txt")), "</pre>\n";
+
+ echo "<h2>stderr:</h2>\n<pre>";
+ echo htmlspecialchars(file_get_contents("data/logs/$t[2].txt")), "</pre>\n";
+
+ if ($t[1])
+ echo "<p>&nbsp;</p><p>NOTE: This test would pass if undef didn't exist!</p>";
+}
+else if ($hash) {
+ $run = get_all_runs($data, $hash);
+ $tests = get_run_tests($run[0]);
+ html_header("Run $run[5] - " . format_date($run[6]));
+ echo <<< HTML
+<p>$run[1] failures ($run[2] ignoring undef)<br>
+LLVM git: <a href="https://github.com/llvm/llvm-project/commit/$run[5]">$run[5]</a><br>
+Alive2 git: <a href="https://github.com/AliveToolkit/alive2/commit/$run[3]">$run[3]</a></p>
+
+<p>Failed tests:</p>
+<table>
+<tr>
+<th>Test Name</th><th>Ok if undef ignored?</th>
+</tr>
+HTML;
+
+ foreach ($tests as $test) {
+ $check = $test[1] ? '&#x2713;' : '&nbsp;';
+ echo "<tr><td><a href=\"index.php?hash=$hash&amp;test=".
+ htmlspecialchars(urlencode($test[0])). "\">".
+ htmlspecialchars($test[0])."</a></td>".
+ "<td style=\"text-align:center\">$check</td></tr>\n";
+ }
+
+ echo "</table>\n";
+}
+else {
+ html_header('Project Zero LLVM Bugs');
+ do_plot($data);
+
+ echo <<< HTML
+<p>&nbsp;</p>
+<p>Last 5 runs:</p>
+<table>
+<tr>
+<th>LLVM commit</th><th>Date/Time</th><th>Failures</th>
+</tr>
+
+HTML;
+
+ $n_runs = sizeof($data);
+ // 5 runs is: [n_runs-5, ..., n_runs-1]
+ for ($i = sizeof($data)-1; $i >= max($n_runs-5, 0); --$i) {
+ $t = $data[$i];
+ $date = format_date($t[6]);
+ echo "<tr><td><a href=\"index.php?hash=$t[0]\">$t[5]</a></td>".
+ "<td>$date</td><td>$t[1]</td></tr>\n";
+ }
+ echo "</table>\n";
+}
+
+html_footer();
+
+
+function format_date($ts) {
+ return date('d/M/Y H:i', $ts);
+}
+
+function get_all_runs($data, $hash) {
+ $found = false;
+ foreach ($data as $t) {
+ if ($t[0] === $hash) {
+ $found = true;
+ break;
+ }
+ }
+
+ if (!$found)
+ die('Hash not found');
+
+ $t[] = file_get_contents("data/logs/$t[0].txt");
+ return $t;
+}
+
+// 0: test name, 1: ok with undef?, 2: stderr hash, log: hash
+// TODO CONFIRM THESE
+function get_run_tests($hash) {
+ $data = array();
+ foreach (file("data/logs/$hash.txt") as $entry) {
+ $data[] = explode(',', trim($entry));
+ }
+ return $data;
+}
+
+function do_plot($data) {
+ $labels = array();
+ $bugs = array();
+ $bugs_wo_undef = array();
+
+ foreach ($data as $t) {
+ $labels[] = format_date($t[6]) . " - $t[5]";
+ $bugs[] = $t[1];
+ $bugs_wo_undef[] = $t[2];
+ }
+
+ $labels = implode("',\n'", $labels);
+ $bugs = implode(",\n", $bugs);
+ $bugs_wo_undef = implode(",\n", $bugs_wo_undef);
+
+ echo <<< HTML
+<div style="width:75%">
+ <canvas id="llvmbugs"></canvas>
+</div>
+<script>
+var ctx = document.getElementById('llvmbugs').getContext('2d');
+new Chart(ctx, {
+ type: 'line',
+ data: {
+ labels: ['$labels'],
+ datasets: [{
+ label: 'Failures',
+ fill: false,
+ backgroundColor: 'rgba(255, 0, 0, 0.5)',
+ borderColor: 'rgba(255, 0, 0, 0.5)',
+ data: [
+ $bugs
+ ]
+ }, {
+ label: 'Failures if undef ignored',
+ fill: false,
+ backgroundColor: 'rgba(0, 0, 255, 0.5)',
+ borderColor: 'rgba(0, 0, 255, 0.5)',
+ data: [
+ $bugs_wo_undef
+ ],
+ }]
+ },
+ options: {
+ tooltips: {
+ mode: 'index',
+ intersect: false,
+ },
+ hover: {
+ mode: 'nearest',
+ intersect: true
+ },
+ scales: {
+ xAxes: [{
+ display: true,
+ scaleLabel: {
+ display: true,
+ labelString: 'Date & LLVM commit'
+ }
+ }],
+ yAxes: [{
+ display: true,
+ scaleLabel: {
+ display: true,
+ labelString: 'Test Failures'
+ }
+ }]
+ }
+ }
+});
+</script>
+
+HTML;
+}

stub out a dashboard
not pretty at all, but seems functional