How to enable Maven plugin for system under test?

Hi!

My plugin has an optional dependency on Maven plugin, I cannot find the way to enable the plugin in system under test so I can add more unit tests to my code. Is there a way to do that?

I'm using LightIdeaTestCase.

Here's what I have in my main code:

        PluginId pluginId = PluginId.getId(MAVEN_PLUGIN_IDENTIFIER);


        boolean installed = PluginManager.isPluginInstalled(pluginId);
        boolean enabled = false;


        if (installed) {
            IdeaPluginDescriptor descriptor = PluginManager.getPlugin(pluginId);
            assert descriptor != null;
            enabled = descriptor.isEnabled();
        }

The code reports that the plugin is installed, but not enabled.

It seems that I need to get a reference to the PluginManager of system under test or let it know beforehand that I need that plugin. Any ideas?

PS: I tried to explicitly enable Maven plugin and it was not successful. For some reason, the plugin is not in the list of "disabled" plugins. It is in the list of "enabled", but the flag on the plugin itself says that it is "disabled". Weird.

Cheers,
Andrey

11 comments
Comment actions Permalink

Do you need access to Maven to simply populate some library dependencies?
If so you might find the following class helpful PsiTestUtil, for instance PsiTestUtil#addLibrary(...)

Edit - Apologies, I now understand your requirement - unfortunately I can't delete this post though :(

0
Comment actions Permalink

Here's where my unit test code fails - on assert:

  public static <T extends ConfigurationType> T findConfigurationType(final Class<T> configurationTypeClass) {
    ConfigurationType[] types = Extensions.getExtensions(ConfigurationType.CONFIGURATION_TYPE_EP);
    for (ConfigurationType type : types) {
      if (configurationTypeClass.isInstance(type)) {
        //noinspection unchecked
        return (T)type;
      }
    }
    assert false : Arrays.toString(types) + " loader: " + configurationTypeClass.getClassLoader() +
                   ", " + configurationTypeClass;
    return null;
  }

java.lang.AssertionError: [
     com.intellij.execution.applet.AppletConfigurationType@20b45bb8,
     com.intellij.execution.application.ApplicationConfigurationType@20f19dce,
     com.intellij.execution.remote.RemoteConfigurationType@56af5047]
          loader: sun.misc.Launcher$AppClassLoader@5a74b10b,
               class org.jetbrains.idea.maven.execution.MavenRunConfigurationType
 at com.intellij.execution.configurations.ConfigurationTypeUtil.findConfigurationType(ConfigurationTypeUtil.java:39)
 at org.jetbrains.idea.maven.execution.MavenRunConfigurationType.createRunnerAndConfigurationSettings(MavenRunConfigurationType.java:204)

I'm asking for MavenConfigurationType, it means the class is available, but it is not configured as Extension.

0
Comment actions Permalink

Both snippets run fine for me.
Is it possible that test case wasn't properly initialized yet?

0
Comment actions Permalink

Hi Roman,

It is possible that the test case is not configured properly. Could you please help me to work it out?

Here's a snippet from Maven2Configuration class:

         public static final String MAVEN_PLUGIN_IDENTIFIER  = "org.jetbrains.idea.maven";

    @Override
    public Command getCommand() throws EclipserException {
        checkMavenPluginStatus();
        return new AddMaven2ConfigurationCommand(this);
    }


    private void checkMavenPluginStatus() throws EclipserException {
        PluginId pluginId = PluginId.getId(MAVEN_PLUGIN_IDENTIFIER);


        boolean installed = PluginManager.isPluginInstalled(pluginId);
        boolean enabled = false;


        if (installed) {
            IdeaPluginDescriptor descriptor = PluginManager.getPlugin(pluginId);
            assert descriptor != null;
            enabled = descriptor.isEnabled();
        }


        if (!installed) throw new EclipserException("Maven plugin is not installed. Please install Maven plugin to continue.");
        if (!enabled) throw new EclipserException("Maven plugin is installed, but not enabled. Please enable Maven plugin to continue.");
    }

execute() from AddMaven2ConfigurationCommand:

    @Override
    public void execute(Project project) throws EclipserException {
        // todo: check configuration with the same name
        MavenRunnerParameters parameters = new MavenRunnerParameters();
        parameters.setGoals(maven2Configuration.getGoals());
        parameters.setProfilesMap(maven2Configuration.getProfilesMap());
        parameters.setWorkingDirPath(maven2Configuration.getWorkingDirectory());
        parameters.setResolveToWorkspace(maven2Configuration.isResolveToWorkspace());


        RunnerAndConfigurationSettings settings = MavenRunConfigurationType.createRunnerAndConfigurationSettings(null, null, parameters, project);
        settings.setName(maven2Configuration.getConfigurationName());


        RunManagerImpl runManager = (RunManagerImpl) RunManager.getInstance(project);
        runManager.addConfiguration(settings, false);
        runManager.setSelectedConfiguration(settings);
    }


Here's the full unit test:

package com.kukido.eclipser.command;


import com.intellij.testFramework.LightIdeaTestCase;
import com.kukido.eclipser.EclipserException;
import com.kukido.eclipser.configuration.Maven2Configuration;


public class Maven2ConfigurationTest extends LightIdeaTestCase {


    public void testGetCommandWithMavenPluginDisabled() throws Exception {
        Maven2Configuration configuration = new Maven2Configuration(
                "kukido-test",
                true,
                new String[]{"local", "remote"},
                "clean compile"
        );


        try {
            configuration.getCommand();
        } catch (EclipserException ee) {
            assertEquals("Maven plugin is installed, but not enabled. Please enable Maven plugin to continue.", ee.getMessage());
        }
    }


    public void testGetCommand() throws Exception {
        Maven2Configuration configuration = new Maven2Configuration(
                "kukido-test",
                true,
                new String[]{"local", "remote"},
                "clean compile"
        );


        Command command = configuration.getCommand();
        command.execute(getProject());
                 // assertions go here
    }
}

Somehow I need to get past checkMavenPluginStatus(), to have Maven plugin installed and enabled for the test case.

Any ideas?

0
Comment actions Permalink

Update:

It seems that Maven plugin is loaded because it is in the module classpath, even though the library scope is set to "provided".

After further exploration with the debugger, I saw that although Maven plugin is loaded, it is not enabled, and marked as "skipped". I was able to force PluginManager to load the plugin, by leveraging system property
-Didea.load.plugins.id=org.jetbrains.idea.maven
Which let me move forward, but I don't think it is viable solution, because Maven plugin dependencies are not loaded by default. It works only if the flag is set for unit tests JVM. There might be a way to set it dynamically for each test case, but even then it does not look right :-)

PS: Should I just mark the dependency on Maven as "required" and get over it? Then again, if someone has difficulties with Maven plugin, they will not be able to use other functionality of my plugin, which seems unfair to me.

0
Comment actions Permalink

The code you posted doesn't add much as it contains a fair amount of missing references and can't be used directly.

Is it possible for you to attach a sample project with failing test?

0
Comment actions Permalink

Hi Roman,

Here's the sample project: https://github.com/kukido/devnet

It contains only one test case (com.kukido.eclipser.command.AddMaven2ConfigurationCommandTest) and the test case fails with:

java.lang.AssertionError:[com.intellij.execution.applet.AppletConfigurationType@7b7469af, com.intellij.execution.application.ApplicationConfigurationType@17c69f7b, com.kukido.eclipser.EclipserConfigurationType@7110506e, com.intellij.execution.remote.RemoteConfigurationType@66109fbf] loader: sun.misc.Launcher$AppClassLoader@37b90b39, class org.jetbrains.idea.maven.execution.MavenRunConfigurationType

I took the liberty of posting the project on github.com, let me know if you prefer the code to be attached to the message.


Cheers,
Andrey
0
Comment actions Permalink

Roman, did you have a chance to look at the sample project?

0
Comment actions Permalink

Not yet, will take a look next week.

0
Comment actions Permalink

Sorry for the late reply.

Right, there are additional steps needed to load Maven plugin.

First, you need to get the Maven's plugin.xml in a classpath for your test. It is not included in plugin SDK by default, so you have to extend it by including all .jar files from IDEA_SDK_HOME/plugins/maven/lib and .../properties/lib directories (the latter is needed as Maven plugin depends on it).

Second, you need to make Maven dependency in your plugin.xml mandatory (it is not only for tests; your plugin may crash otherwise if Maven plugin is disabled).

That's it, and no need to mess with "idea.load.plugins.id" property.

0

Please sign in to leave a comment.