Merge "[UI Testing] Now UI tests can specify a minimum JDK needed." into studio-1.3-dev
diff --git a/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/GuiTests.java b/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/GuiTests.java
index 3ac6337..bdaa48a 100644
--- a/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/GuiTests.java
+++ b/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/GuiTests.java
@@ -26,6 +26,9 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.wm.IdeFrame;
 import com.intellij.openapi.wm.impl.IdeFrameImpl;
@@ -63,7 +66,6 @@
 import static com.intellij.openapi.util.io.FileUtil.toSystemDependentName;
 import static com.intellij.util.containers.ContainerUtil.getFirstItem;
 import static java.util.concurrent.TimeUnit.MINUTES;
-import static junit.framework.Assert.assertNotNull;
 import static org.fest.assertions.Assertions.assertThat;
 import static org.fest.swing.edt.GuiActionRunner.execute;
 import static org.fest.swing.finder.WindowFinder.findFrame;
@@ -71,8 +73,7 @@
 import static org.fest.swing.timing.Timeout.timeout;
 import static org.fest.util.Strings.quote;
 import static org.jetbrains.android.AndroidPlugin.setGuiTestingMode;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.*;
 
 public final class GuiTests {
   public static final Timeout SHORT_TIMEOUT = timeout(2, MINUTES);
@@ -96,6 +97,14 @@
     GradleExperimentalSettings.getInstance().SKIP_SOURCE_GEN_ON_PROJECT_SYNC = true;
   }
 
+  @SuppressWarnings("unused") // Invoked through reflection by MethodInvoker
+  public static boolean hasRequiredJdk(@NotNull JavaSdkVersion jdkVersion) {
+    Sdk jdk = IdeSdks.getJdk();
+    assertNotNull("Expecting to have a JDK", jdk);
+    JavaSdkVersion currentVersion = JavaSdk.getInstance().getVersion(jdk);
+    return currentVersion != null && currentVersion.isAtLeast(jdkVersion);
+  }
+
   // Called by IdeTestApplication via reflection.
   @SuppressWarnings("UnusedDeclaration")
   public static void setUpDefaultGeneralSettings() {
diff --git a/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/IdeGuiTest.java b/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/IdeGuiTest.java
index 0e7ea8a..fe00eba 100644
--- a/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/IdeGuiTest.java
+++ b/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/IdeGuiTest.java
@@ -15,13 +15,18 @@
  */
 package com.android.tools.idea.tests.gui.framework;
 
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import static com.intellij.openapi.projectRoots.JavaSdkVersion.JDK_1_6;
+
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.METHOD)
 public @interface IdeGuiTest {
   boolean closeProjectBeforeExecution() default true;
+  JavaSdkVersion runWithMinimumJdkVersion() default JDK_1_6;
 }
diff --git a/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/MethodInvoker.java b/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/MethodInvoker.java
index 9c3230f..85a18ce 100644
--- a/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/MethodInvoker.java
+++ b/android/guiTestSrc/com/android/tools/idea/tests/gui/framework/MethodInvoker.java
@@ -15,11 +15,15 @@
  */
 package com.android.tools.idea.tests.gui.framework;
 
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import org.junit.runners.model.FrameworkMethod;
 import org.junit.runners.model.Statement;
 
+import java.lang.annotation.Annotation;
+
 import static com.android.tools.idea.tests.gui.framework.GuiTestRunner.canRunGuiTests;
 import static org.fest.reflect.core.Reflection.field;
+import static org.fest.reflect.core.Reflection.method;
 
 public class MethodInvoker extends Statement {
   private final FrameworkMethod myTestMethod;
@@ -35,6 +39,35 @@
     ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
     Class<?> guiTestCaseType = Class.forName(GuiTestCase.class.getCanonicalName(), true, classLoader);
     String name = myTestMethod.getName();
+
+    Annotation ideGuiTestAnnotation = null;
+    for (Annotation annotation : myTestMethod.getAnnotations()) {
+      if (annotation.annotationType().getCanonicalName().equals(IdeGuiTest.class.getCanonicalName())) {
+        ideGuiTestAnnotation = annotation;
+        break;
+      }
+    }
+
+    if (ideGuiTestAnnotation != null) {
+      Object minimumJdkVersion = method("runWithMinimumJdkVersion").withReturnType(Object.class)
+                                                                   .in(ideGuiTestAnnotation)
+                                                                   .invoke();
+      assert minimumJdkVersion != null;
+
+      Class<?> guiTestsClass = classLoader.loadClass(GuiTests.class.getCanonicalName());
+      Class<?> javaSdkVersionClass = classLoader.loadClass(JavaSdkVersion.class.getCanonicalName());
+      Boolean hasRequiredJdk = method("hasRequiredJdk").withReturnType(boolean.class)
+                                                       .withParameterTypes(javaSdkVersionClass)
+                                                       .in(guiTestsClass)
+                                                       .invoke(minimumJdkVersion);
+      assert hasRequiredJdk != null;
+      if (!hasRequiredJdk) {
+        String jdkVersion = method("getDescription").withReturnType(String.class).in(minimumJdkVersion).invoke();
+        System.out.println(String.format("Skipping test '%1$s'. It needs JDK %2$s or newer.", name, jdkVersion));
+        return;
+      }
+    }
+
     System.out.println(String.format("Executing test '%1$s'", myTestMethod.getMethod().getDeclaringClass() + "#" + name));
     if (guiTestCaseType.isInstance(myTest)) {
       if (!canRunGuiTests()) {
diff --git a/android/guiTestSrc/com/android/tools/idea/tests/gui/gradle/GradleSyncTest.java b/android/guiTestSrc/com/android/tools/idea/tests/gui/gradle/GradleSyncTest.java
index 6c0b72d..bd5dec4 100644
--- a/android/guiTestSrc/com/android/tools/idea/tests/gui/gradle/GradleSyncTest.java
+++ b/android/guiTestSrc/com/android/tools/idea/tests/gui/gradle/GradleSyncTest.java
@@ -25,7 +25,6 @@
 import com.android.tools.idea.gradle.util.GradleProperties;
 import com.android.tools.idea.gradle.util.LocalProperties;
 import com.android.tools.idea.sdk.IdeSdks;
-import com.android.tools.idea.sdk.Jdks;
 import com.android.tools.idea.tests.gui.framework.BelongsToTestGroups;
 import com.android.tools.idea.tests.gui.framework.GuiTestCase;
 import com.android.tools.idea.tests.gui.framework.IdeGuiTest;
@@ -51,7 +50,7 @@
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ex.ProjectManagerEx;
-import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import com.intellij.openapi.roots.*;
 import com.intellij.openapi.roots.impl.libraries.ProjectLibraryTable;
 import com.intellij.openapi.roots.libraries.Library;
@@ -1255,17 +1254,8 @@
     assertEquals(JDK_1_7, getJavaLanguageLevel(app));
   }
 
-  @Test @IdeGuiTest
+  @Test @IdeGuiTest(runWithMinimumJdkVersion = JavaSdkVersion.JDK_1_8)
   public void testModuleLanguageLevelWithJdk8() throws IOException {
-    Sdk jdk = IdeSdks.getJdk();
-    assert jdk != null;
-    if (!Jdks.isApplicableJdk(jdk, JDK_1_8)) {
-      String testName = "testModuleLanguageLevelWithJdk8";
-      skip(testName);
-      System.out.println(String.format("'%1$s' needs JDK 1.8 or newer.", testName));
-      return;
-    }
-
     IdeFrameFixture projectFrame = importProjectAndWaitForProjectSyncToFinish("MultipleModuleTypes");
     Module javaLib = projectFrame.getModule("javaLib");
     assertEquals(JDK_1_7, getJavaLanguageLevel(javaLib));