Repository: spack/spack

Issue:
CDash reporter start and end time are incorrect.
### Steps to reproduce

```console
rm -rf spack-cdash-repro
mkdir spack-cdash-repro
cd spack-cdash-repro
spack env create -d .
spack env activate -d .
spack config add config:install_tree:root:"./install"
date +%s
spack install --add --log-file cdash-results --log-format cdash --cdash-build "Test" --cdash-site "Test" --cdash-track "Experimental" zlib
date +%s
```


### Error message

Open `spack-cdash-repro/cdash-results/Update.xml` and observe that the `StartTime` is earlier than result of the first `date +%s` command run by the reproducer script (dependent on how long the zlib install takes on your machine. This will be a bit more reliable with a slower to build/install package).

Looking in `lib/spack/spack/reporters/cdash.py` it appears that `CDash` stores `self.endtime = int(time.time())`  when the reporter is created, and then backs out a start time by subtracting off the duration of the installation process for all specs. However it appears the CDash reporter object is created before any specs are built and installed which leads to the wrong `StartTime` in Update.xml.

### Information on your system

* **Spack:** 0.21.0.dev0 (c3f4822f92e0afc70f3a642310c7e1282434d397)
* **Python:** 3.6.8
* **Platform:** linux-rhel7-skylake_avx512
* **Concretizer:** clingo

### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have searched the issues of this repo and believe this is not a duplicate
- [X] I have run the failing commands in debug mode and reported the output


Discussion:

Resolving patch:
diff --git a/lib/spack/spack/reporters/cdash.py b/lib/spack/spack/reporters/cdash.py
--- a/lib/spack/spack/reporters/cdash.py
+++ b/lib/spack/spack/reporters/cdash.py
@@ -92,11 +92,11 @@ def __init__(self, configuration: CDashConfiguration):
         self.osname = platform.system()
         self.osrelease = platform.release()
         self.target = spack.platforms.host().target("default_target")
-        self.endtime = int(time.time())
+        self.starttime = int(time.time())
         self.buildstamp = (
             configuration.buildstamp
             if configuration.buildstamp
-            else build_stamp(configuration.track, self.endtime)
+            else build_stamp(configuration.track, self.starttime)
         )
         self.buildIds: Dict[str, str] = {}
         self.revision = ""
@@ -125,7 +125,7 @@ def build_report_for_package(self, report_dir, package, duration):
             report_data[phase] = {}
             report_data[phase]["loglines"] = []
             report_data[phase]["status"] = 0
-            report_data[phase]["endtime"] = self.endtime
+            report_data[phase]["starttime"] = self.starttime
 
         # Track the phases we perform so we know what reports to create.
         # We always report the update step because this is how we tell CDash
@@ -160,9 +160,9 @@ def build_report_for_package(self, report_dir, package, duration):
             build_pos = phases_encountered.index("build")
             phases_encountered.insert(0, phases_encountered.pop(build_pos))
 
-        self.starttime = self.endtime - duration
+        self.endtime = self.starttime + duration
         for phase in phases_encountered:
-            report_data[phase]["starttime"] = self.starttime
+            report_data[phase]["endtime"] = self.endtime
             report_data[phase]["log"] = "\n".join(report_data[phase]["loglines"])
             errors, warnings = parse_log_events(report_data[phase]["loglines"])
 
@@ -309,7 +309,7 @@ def test_report_for_package(self, report_dir, package, duration):
             self.buildname = "{0}-{1}".format(self.current_package_name, package["id"])
         else:
             self.buildname = self.report_build_name(self.current_package_name)
-        self.starttime = self.endtime - duration
+        self.endtime = self.starttime + duration
 
         report_data = self.initialize_report(report_dir)
         report_data["hostname"] = socket.gethostname()
@@ -354,7 +354,7 @@ def concretization_report(self, report_dir, msg):
         self.buildname = self.base_buildname
         report_data = self.initialize_report(report_dir)
         report_data["update"] = {}
-        report_data["update"]["starttime"] = self.endtime
+        report_data["update"]["starttime"] = self.starttime
         report_data["update"]["endtime"] = self.endtime
         report_data["update"]["revision"] = self.revision
         report_data["update"]["log"] = msg


Test patch: