Skip to content

Add Java/Maven support to pulumitest #149

@rshade

Description

@rshade

Background

The providertest repository provides testing infrastructure for Pulumi programs and providers. It currently supports:

Java/Maven projects (https://github.com/pulumi/pulumi-java) currently lack equivalent support for testing with local SDK builds.

Enhancement Request

Add Java/Maven support to pulumitest to enable testing Java Pulumi programs with local SDK builds and custom Maven configurations.

Proposed Features

1. JavaMavenDependency Option

Add local Maven dependency replacement support similar to .NET's DotNetReference():

opttest.JavaMavenDependency("com.pulumi:pulumi", "/path/to/local/pulumi-java")

Implementation approach:

  • Manipulate pom.xml to add/modify <dependency> elements
  • Support both local file paths and local Maven repository references
  • Use generic XML tree manipulation (similar to .NET's xmlNode approach) to preserve all pom.xml structure

2. JavaMavenProfile Option

Support Maven profiles for different build configurations:

opttest.JavaMavenProfile("development")

Implementation approach:

  • Set Maven -P flag via command-line arguments
  • Or set MAVEN_ACTIVE_PROFILES environment variable

3. JavaTargetVersion Option

Specify Java target version (similar to DotNetTargetFramework):

opttest.JavaTargetVersion("17")

Implementation approach:

  • Modify <maven.compiler.source> and <maven.compiler.target> properties in pom.xml
  • Or modify <java.version> property for Spring Boot projects

4. JavaMavenSettings Option

Support custom Maven settings.xml:

opttest.JavaMavenSettings("/path/to/settings.xml")

Implementation approach:

  • Pass -s or --settings flag to Maven commands

Implementation Details

Files to Create/Modify

  1. pulumitest/pomxml.go - Maven pom.xml manipulation utilities

    • findPomFile(dir string) - locate pom.xml in directory
    • addMavenDependency(pomPath, groupId, artifactId, version, systemPath string) - add dependency with optional system scope
    • setJavaVersion(pomPath, version string) - modify Java version properties
    • Use generic xmlNode structure (like csproj.go) to preserve all XML content
  2. pulumitest/opttest/opttest.go - Add Java options

    • Add JavaMavenDependencies map[string]MavenDependency to Options struct
    • Add JavaMavenProfile string field
    • Add JavaTargetVersion string field
    • Add JavaMavenSettings string field
    • Implement option functions
  3. pulumitest/newStack.go - Integrate Java configuration

    • Handle Java-specific configurations during stack creation
    • Modify pom.xml before pulumi install runs
    • Set Maven-specific environment variables
  4. pulumitest/testdata/java_simple/ - Test data

    • pom.xml with Pulumi dependencies
    • src/main/java/myproject/App.java with simple Pulumi program
    • Use Pulumi Random provider for lightweight testing
  5. pulumitest/pulumiTest_test.go - Integration tests

    • TestJavaDeploy - Basic deployment test
    • TestJavaSkipInstall - Manual install flow
    • TestJavaWithLocalDependency - Local SDK reference test
  6. CONTRIBUTING.md - Documentation

    • Add Java/Maven section to SDK configuration
    • Include examples and troubleshooting

XML Manipulation Approach

Use the generic XML tree approach (proven in .NET implementation):

type xmlNode struct {
    XMLName xml.Name
    Attrs   []xml.Attr `xml:"-"`
    Content []byte     `xml:",innerxml"`
    Nodes   []xmlNode  `xml:",any"`
}

This preserves all pom.xml structure including:

  • Maven properties
  • Build plugins
  • Profiles
  • Dependencies
  • Parent POM references

Maven Dependency Scopes

Support Maven's system scope for local dependencies:

<dependency>
    <groupId>com.pulumi</groupId>
    <artifactId>pulumi</artifactId>
    <version>0.0.0-dev</version>
    <scope>system</scope>
    <systemPath>/absolute/path/to/pulumi-java.jar</systemPath>
</dependency>

Environment Variables

Maven respects these environment variables:

  • MAVEN_OPTS - JVM options for Maven
  • JAVA_HOME - Java installation path
  • Standard Maven properties can be set via workspace environment in Automation API

Example Usage

func TestJavaWithLocalSDK(t *testing.T) {
    test := NewPulumiTest(t,
        "path/to/java/project",
        opttest.JavaMavenDependency(
            "com.pulumi:pulumi",
            "../pulumi-java/sdk/java/target/pulumi-0.0.0-dev.jar",
        ),
        opttest.JavaTargetVersion("17"),
    )
    
    up := test.Up(t)
    assert.NotEmpty(t, up.Outputs)
}

Testing Strategy

  1. Unit Tests

    • Test pom.xml parsing and modification
    • Test option parsing and application
    • Test path resolution for local dependencies
  2. Integration Tests

    • Test with Java 11, 17, and 21
    • Test with different Maven versions
    • Test with Pulumi Random provider (lightweight, no cloud credentials)
    • Test local SDK development workflow

Benefits

  • Enables local Java SDK development and testing for https://github.com/pulumi/pulumi-java
  • Consistent API with existing language support (Node.js, Go, .NET)
  • No external dependencies or cloud credentials required for basic tests
  • Follows established patterns from .NET implementation

Related

Priority

Medium - Would enable Java SDK developers to use the same testing infrastructure as other language SDKs.

Notes

  • Maven's dependency management is more complex than NuGet (.NET) due to transitive dependencies
  • May need to handle Maven local repository (~/.m2/repository) for caching
  • Consider supporting Gradle in future (separate issue)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions