[SDK] Adds smoke test for dartaot.

Change-Id: I0e840f9e6489268d64b458872f19d0a2964f1271
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/100244
Commit-Queue: Clement Skau <cskau@google.com>
Reviewed-by: Alexander Thomas <athom@google.com>
diff --git a/tools/bots/aot_smoke_tests.dart b/tools/bots/aot_smoke_tests.dart
new file mode 100755
index 0000000..bb92379
--- /dev/null
+++ b/tools/bots/aot_smoke_tests.dart
@@ -0,0 +1,69 @@
+#!/usr/bin/env dart
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Smoke test runner for Dart AOT (dart2aot, dartaotruntime).
+// aot_smoke_tests.dart and dart_aot_test.dart together form the test that the
+// AOT toolchain is compiled and included correctly in the SDK.
+// This tests that the AOT tools can both successfully compile Dart -> AOT and
+// run the resulting AOT blob with the AOT runtime.
+
+import 'dart:io';
+import 'dart:convert';
+
+import 'package:args/args.dart';
+
+get_dart2aot() {
+  if (Platform.isLinux) {
+    return 'out/ReleaseX64/dart-sdk/bin/dart2aot';
+  } else if (Platform.isMacOS) {
+    return 'xcodebuild/ReleaseX64/dart-sdk/bin/dart2aot';
+  } else if (Platform.isWindows) {
+    return 'out\\ReleaseX64\\dart-sdk\\bin\\dart2aot.bat';
+  } else {
+    throw 'Unsupported host platform!';
+  }
+}
+
+get_dartaotruntime() {
+  if (Platform.isLinux) {
+    return 'out/ReleaseX64/dart-sdk/bin/dartaotruntime';
+  } else if (Platform.isMacOS) {
+    return 'xcodebuild/ReleaseX64/dart-sdk/bin/dartaotruntime';
+  } else if (Platform.isWindows) {
+    return 'out\\ReleaseX64\\dart-sdk\\bin\\dartaotruntime.exe';
+  } else {
+    throw 'Unsupported host platform!';
+  }
+}
+
+assert_equals(var expected, var actual) {
+  if (expected != actual) {
+    print('Test failed! Expected \'$expected\', got \'$actual\'');
+    exit(1);
+  }
+}
+
+main(List<String> args) async {
+  ProcessResult result;
+
+  result = Process.runSync(get_dart2aot(),
+      ['tools/bots/dart_aot_test.dart', 'tools/bots/dart_aot_test.dart.aot'],
+      stdoutEncoding: utf8, stderrEncoding: utf8);
+  stdout.write(result.stdout);
+  if (result.exitCode != 0 || result.stderr != '') {
+    stderr.write(result.stderr);
+    exit(1);
+  }
+
+  result = Process.runSync(
+      get_dartaotruntime(), ['tools/bots/dart_aot_test.dart.aot'],
+      stdoutEncoding: utf8, stderrEncoding: utf8);
+  if (result.exitCode != 0 || result.stderr != '') {
+    stderr.write(result.stderr);
+    exit(1);
+  }
+
+  assert_equals('Hello, 世界.', result.stdout.trim());
+}
diff --git a/tools/bots/dart_aot_test.dart b/tools/bots/dart_aot_test.dart
new file mode 100755
index 0000000..0a626f4
--- /dev/null
+++ b/tools/bots/dart_aot_test.dart
@@ -0,0 +1,10 @@
+#!/usr/bin/env dart
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test program for Dart AOT (dart2aot, dartaotruntime).
+
+main(List<String> args) async {
+  print('Hello, 世界.');
+}
diff --git a/tools/bots/dart_aot_test.dart.aot b/tools/bots/dart_aot_test.dart.aot
new file mode 100644
index 0000000..677b506
--- /dev/null
+++ b/tools/bots/dart_aot_test.dart.aot
Binary files differ
diff --git a/tools/bots/dart_aot_test.dart.aot.dill b/tools/bots/dart_aot_test.dart.aot.dill
new file mode 100644
index 0000000..02dbbad
--- /dev/null
+++ b/tools/bots/dart_aot_test.dart.aot.dill
Binary files differ
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py
index 301f269..3b0e01e 100755
--- a/tools/bots/dart_sdk.py
+++ b/tools/bots/dart_sdk.py
@@ -27,11 +27,12 @@
  else:
    return ['ia32', 'x64']
 
+def BuildRootPath(path, arch=BUILD_ARCHITECTURE, build_mode='release'):
+  return os.path.join(bot_utils.DART_DIR,
+                      utils.GetBuildRoot(BUILD_OS, build_mode, arch), path)
+
 def BuildDartdocAPIDocs(dirname):
-  dart_sdk = os.path.join(bot_utils.DART_DIR,
-                          utils.GetBuildRoot(BUILD_OS, 'release',
-                                             BUILD_ARCHITECTURE),
-                          'dart-sdk')
+  dart_sdk = BuildRootPath('dart-sdk')
   dart_exe =  os.path.join(dart_sdk, 'bin', 'dart')
   dartdoc_dart = os.path.join(bot_utils.DART_DIR,
                               'third_party', 'pkg', 'dartdoc', 'bin',
@@ -45,10 +46,7 @@
                   '--rel-canonical-prefix=' + url])
 
 def CreateUploadVersionFile():
-  file_path = os.path.join(bot_utils.DART_DIR,
-                           utils.GetBuildRoot(BUILD_OS, 'release',
-                                              BUILD_ARCHITECTURE),
-                           'VERSION')
+  file_path = BuildRootPath('VERSION')
   with open(file_path, 'w') as fd:
     fd.write(utils.GetVersionFileContent())
   DartArchiveUploadVersionFile(file_path)
@@ -60,27 +58,19 @@
     destination = namer.version_filepath(revision)
     DartArchiveFile(version_file, destination, checksum_files=False)
 
-def CreateUploadSDKZips():
-  with bot.BuildStep('Create and upload sdk zips'):
-    for arch in BuildArchitectures():
-      sdk_path = os.path.join(bot_utils.DART_DIR,
-                              utils.GetBuildRoot(BUILD_OS, 'release', arch),
-                              'dart-sdk')
-      product_sdk_path = os.path.join(bot_utils.DART_DIR,
-                              utils.GetBuildRoot(BUILD_OS, 'product', arch),
-                              'dart-sdk')
-      sdk_zip = os.path.join(bot_utils.DART_DIR,
-                             utils.GetBuildRoot(BUILD_OS, 'release', arch),
-                             'dartsdk-%s-%s.zip' % (BUILD_OS, arch))
-      FileDelete(sdk_zip)
-      # We don't support precompilation on ia32.
-      if arch != 'ia32':
-        # Patch in all the PRODUCT built AOT binaries.
-        CopyBetween(product_sdk_path, sdk_path, 'bin', 'utils', GuessExtension('gen_snapshot'))
-        CopyBetween(product_sdk_path, sdk_path, 'bin', GuessExtension('dartaotruntime'))
-      # Zip it up.
-      CreateZip(sdk_path, sdk_zip)
-      DartArchiveUploadSDKs(BUILD_OS, arch, sdk_zip)
+def CreateAndUploadSDKZip(arch, sdk_path):
+  sdk_zip = BuildRootPath('dartsdk-%s-%s.zip' % (BUILD_OS, arch), arch=arch)
+  FileDelete(sdk_zip)
+  CreateZip(sdk_path, sdk_zip)
+  DartArchiveUploadSDKs(BUILD_OS, arch, sdk_zip)
+
+def CopyAotBinaries(arch, sdk_path):
+  product_sdk_path = BuildRootPath('dart-sdk', arch=arch, build_mode='product')
+  # We don't support precompilation on ia32.
+  if arch != 'ia32':
+    with bot.BuildStep('Patching in PRODUCT built AOT binaries'):
+      CopyBetween(product_sdk_path, sdk_path, 'bin', 'utils', GuessExtension('gen_snapshot'))
+      CopyBetween(product_sdk_path, sdk_path, 'bin', GuessExtension('dartaotruntime'))
 
 def DartArchiveUploadSDKs(system, arch, sdk_zip):
   namer = bot_utils.GCSNamer(CHANNEL, bot_utils.ReleaseType.RAW)
@@ -95,21 +85,13 @@
   revision = utils.GetArchiveVersion()
   binary = namer.unstripped_filename(BUILD_OS)
   for arch in BuildArchitectures():
-    binary = os.path.join(bot_utils.DART_DIR,
-                          utils.GetBuildRoot(BUILD_OS, 'release', arch),
-                          binary)
+    binary = BuildRootPath(binary, arch=arch)
     gs_path = namer.unstripped_filepath(revision, BUILD_OS, arch)
     DartArchiveFile(binary, gs_path)
 
 def CreateUploadAPIDocs():
-  dartdoc_dir = os.path.join(bot_utils.DART_DIR,
-                             utils.GetBuildRoot(BUILD_OS, 'release',
-                                                BUILD_ARCHITECTURE),
-                             'gen-dartdocs')
-  dartdoc_zip = os.path.join(bot_utils.DART_DIR,
-                             utils.GetBuildRoot(BUILD_OS, 'release',
-                                                BUILD_ARCHITECTURE),
-                             'dartdocs-api.zip')
+  dartdoc_dir = BuildRootPath('gen-dartdocs')
+  dartdoc_zip = BuildRootPath('dartdocs-api.zip')
   if CHANNEL == bot_utils.Channel.TRY:
     BuildDartdocAPIDocs(dartdoc_dir)
   else:
@@ -236,7 +218,17 @@
     if BUILD_OS == 'linux':
       CreateUploadAPIDocs()
   elif CHANNEL != bot_utils.Channel.TRY:
-    CreateUploadSDKZips()
+    for arch in BuildArchitectures():
+      sdk_path = BuildRootPath('dart-sdk', arch=arch)
+      # Patch in all the PRODUCT built AOT binaries.
+      CopyAotBinaries(arch, sdk_path)
+      with bot.BuildStep('Create and upload sdk zip for ' + arch):
+        CreateAndUploadSDKZip(arch)
     DartArchiveUnstrippedBinaries()
     if BUILD_OS == 'linux':
       CreateUploadVersionFile()
+  else:  # CHANNEL == bot_utils.Channel.TRY
+    # Patch in all the PRODUCT built AOT binaries.
+    for arch in BuildArchitectures():
+      sdk_path = BuildRootPath('dart-sdk', arch=arch)
+      CopyAotBinaries(arch, sdk_path)
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 5cbfed8..e39d0d6 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -1347,6 +1347,13 @@
           "script": "tools/bots/dart_sdk.py"
         },
         {
+          "name": "run smoke tests",
+          "script": "out/ReleaseX64/dart",
+          "arguments": [
+            "tools/bots/aot_smoke_tests.dart"
+          ]
+        },
+        {
           "name": "build api docs",
           "script": "tools/bots/dart_sdk.py",
           "arguments": [ "api_docs" ]
@@ -1362,10 +1369,9 @@
       ]
     },
     {
-      "builders": ["dart-sdk-mac",
-                   "dart-sdk-win"],
+      "builders": ["dart-sdk-mac"],
       "meta": {
-        "description": "This configuration is used by the sdk-builders for MacOS and Windows."
+        "description": "This configuration is used by the sdk-builders for MacOS."
       },
       "steps": [
         {
@@ -1389,6 +1395,50 @@
         {
           "name": "upload sdk",
           "script": "tools/bots/dart_sdk.py"
+        },
+        {
+          "name": "run smoke tests",
+          "script": "xcodebuild/ReleaseX64/dart",
+          "arguments": [
+            "tools/bots/aot_smoke_tests.dart"
+          ]
+        }
+      ]
+    },
+    {
+      "builders": ["dart-sdk-win"],
+      "meta": {
+        "description": "This configuration is used by the sdk-builders for Windows."
+      },
+      "steps": [
+        {
+          "name": "build dart",
+          "script": "tools/build.py",
+          "arguments": ["--arch=ia32,x64",
+                        "--mode=release", "create_sdk"]
+        },
+        {
+          "name": "build gen_kernel.dart.snapshot and dart2aot",
+          "script": "tools/build.py",
+          "arguments": ["--arch=x64", "--mode=release",
+                        "copy_gen_kernel_snapshot", "copy_dart2aot"]
+        },
+        {
+          "name": "build gen_snapshot and dartaotruntime",
+          "script": "tools/build.py",
+          "arguments": ["--arch=x64", "--mode=product",
+                        "copy_gen_snapshot", "copy_dartaotruntime"]
+        },
+        {
+          "name": "upload sdk",
+          "script": "tools/bots/dart_sdk.py"
+        },
+        {
+          "name": "run smoke tests",
+          "script": "out/ReleaseX64/dart.exe",
+          "arguments": [
+            "tools/bots/aot_smoke_tests.dart"
+          ]
         }
       ]
     },