Home > Back-end >  nu.studer.credentials does not work from inside Spock
nu.studer.credentials does not work from inside Spock

Time:01-03

I am building a Gradle plugin that requires a username and password for the access to an external resource; to avoid clear text passwords, I use the plugin nu.studer.credentials.

To test my plugin, I use Spock; the following test file CredentialsFunctionTest.groovy was stripped down to only the relevant parts, to show the problem:

package my.gradle.plugin

import org.gradle.testkit.runner.GradleRunner
import spock.lang.Specification
import spock.lang.TempDir

/**
 * A simple functional test for the credentials acquisition.
 */
class CredentialsFunctionalTest extends Specification {
    @TempDir
    private File projectDir

    private getBuildFile() {
        new File( projectDir, "build.gradle" )
    }

    private getSettingsFile() {
        new File( projectDir, "settings.gradle" )
    }

    def "can run task"() {
        given:
//---> Begin of settings file <------------------------------------------------
        settingsFile << """
plugins {
    id  'nu.studer.credentials' version '3.0'
}

"""
//---> End of settings file <--------------------------------------------------

//---> Begin of build file <---------------------------------------------------
        buildFile << """
plugins {
    id  'nu.studer.credentials'
}

String username = credentials.forKey( 'myUser' )
System.out.printf( 'Username: %s%n', username )
String password = credentials.forKey( 'myPassword' )
System.out.printf( 'Password: %s%n', password )

task doSomething {
} 
"""
//---> End of build file <-----------------------------------------------------

        when:
        def runner = GradleRunner.create()
        runner.forwardOutput()
        runner.withPluginClasspath()
        runner.withArguments("doSomething" )
        runner.withProjectDir( projectDir )
        def result = runner.build()

        then:
        result.output.contains( "Alive!" )
    }
}

The output for "Username" and "Password" is null – that the test as such fails is expected, as there is no output for the String "Alive!" anywhere.

When I place the files settings.gradle and build.gradle (content below) to an empty folder, and call gradle with gradle doSomething, I get the expected output.

settings.gradle:

plugins {
    id  'nu.studer.credentials' version '3.0'
}

build.gradle:

plugins {
    id  'nu.studer.credentials'
}

String username = credentials.forKey( 'myUser' )
System.out.printf( 'Username: %s%n', username )
String password = credentials.forKey( 'myPassword' )
System.out.printf( 'Password: %s%n', password )

task doSomething {
} 

The nu.studer.credentials plugin stores the values in $GRADLE_USER_HOME/gradle.encrypted.properties, so one assumption is that Spock is using a different, temporary user and/or home folder.

CodePudding user response:

Based on the hint that Leonard Brünings gave me in his comment to my question, I was able to identify the problem and to create a solution.

As Leonard said, the issue is not with Spock as such, but with the GradleRuner that executes the test: this will use a different "Gradle user home directory" than a 'regular' Gradle execution.

With the parameter -g or --gradle-user-home, this can be changed, but that is not recommended when testing a Gradle plugin (we are using Gradle to test Gradle here …).

Luckily, the nu.studer.credentials plugin provides an configuration parameter that allows to specify the location of the file that holds the encrypted credentials: -PcredentialsLocation=<path>.

So the solution looks like this (I took only the when: section from the original test script):

…
when:
def runner = GradleRunner.create()
runner.forwardOutput()
runner.withPluginClasspath()
runner.withArguments( "-PcredentialsLocation=%s/.gradle".formatted( System.getProperty( "user.home" ) ), "doSomething" )
runner.withProjectDir( projectDir )
def result = runner.build()
…

Of course, the test still fails, but it displays now correct values for username and password!

  • Related