mirror of
https://codeberg.org/PGPainless/sop-java.git
synced 2024-06-16 00:24:54 +02:00
Compare commits
11 commits
03f8950b16
...
cbbdd09472
Author | SHA1 | Date | |
---|---|---|---|
Paul Schaub | cbbdd09472 | ||
Paul Schaub | da6cba1d55 | ||
Paul Schaub | 4b2875d572 | ||
Paul Schaub | 30f7ca90cd | ||
Paul Schaub | bfa97aede8 | ||
Paul Schaub | bdbc9593c8 | ||
Paul Schaub | 3643aff082 | ||
Paul Schaub | ed9b2f5fef | ||
Paul Schaub | cd208c8942 | ||
Paul Schaub | 7325cad696 | ||
Paul Schaub | 7a825c7607 |
|
@ -6,6 +6,12 @@ SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 10.0.0
|
||||||
|
- Update implementation to [SOP Specification revision 10](https://www.ietf.org/archive/id/draft-dkg-openpgp-stateless-cli-10.html).
|
||||||
|
- Throw `BadData` when passing KEYS where CERTS are expected
|
||||||
|
- Introduce `sopv` interface subset with revision `1.0`
|
||||||
|
- Add `sop version --sopv`
|
||||||
|
|
||||||
## 8.0.1
|
## 8.0.1
|
||||||
- `decrypt`: Do not throw `NoSignature` exception (exit code 3) if `--verify-with` is provided, but `VERIFICATIONS` is empty.
|
- `decrypt`: Do not throw `NoSignature` exception (exit code 3) if `--verify-with` is provided, but `VERIFICATIONS` is empty.
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ SPDX-License-Identifier: Apache-2.0
|
||||||
# SOP for Java
|
# SOP for Java
|
||||||
|
|
||||||
[![status-badge](https://ci.codeberg.org/api/badges/PGPainless/sop-java/status.svg)](https://ci.codeberg.org/PGPainless/sop-java)
|
[![status-badge](https://ci.codeberg.org/api/badges/PGPainless/sop-java/status.svg)](https://ci.codeberg.org/PGPainless/sop-java)
|
||||||
[![Spec Revision: 8](https://img.shields.io/badge/Spec%20Revision-8-blue)](https://datatracker.ietf.org/doc/draft-dkg-openpgp-stateless-cli/08/)
|
[![Spec Revision: 10](https://img.shields.io/badge/Spec%20Revision-10-blue)](https://datatracker.ietf.org/doc/draft-dkg-openpgp-stateless-cli/10/)
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/pgpainless/sop-java/badge.svg?branch=main)](https://coveralls.io/github/pgpainless/sop-java?branch=main)
|
[![Coverage Status](https://coveralls.io/repos/github/pgpainless/sop-java/badge.svg?branch=main)](https://coveralls.io/github/pgpainless/sop-java?branch=main)
|
||||||
[![REUSE status](https://api.reuse.software/badge/github.com/pgpainless/sop-java)](https://api.reuse.software/info/github.com/pgpainless/sop-java)
|
[![REUSE status](https://api.reuse.software/badge/github.com/pgpainless/sop-java)](https://api.reuse.software/info/github.com/pgpainless/sop-java)
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ The repository contains the following modules:
|
||||||
* [sop-java](/sop-java) defines a set of Java interfaces describing the Stateless OpenPGP Protocol.
|
* [sop-java](/sop-java) defines a set of Java interfaces describing the Stateless OpenPGP Protocol.
|
||||||
* [sop-java-picocli](/sop-java-picocli) contains a wrapper application that transforms the `sop-java` API into a command line application
|
* [sop-java-picocli](/sop-java-picocli) contains a wrapper application that transforms the `sop-java` API into a command line application
|
||||||
compatible with the SOP-CLI specification.
|
compatible with the SOP-CLI specification.
|
||||||
|
* [external-sop](/external-sop) contains an API implementation that can be used to forward API calls to a SOP executable,
|
||||||
|
allowing to delegate the implementation logic to an arbitrary SOP CLI implementation.
|
||||||
|
|
||||||
## Known Implementations
|
## Known Implementations
|
||||||
(Please expand!)
|
(Please expand!)
|
||||||
|
|
|
@ -16,7 +16,7 @@ import sop.external.operation.*
|
||||||
import sop.operation.*
|
import sop.operation.*
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of the {@link SOP} API using an external SOP binary.
|
* Implementation of the [SOP] API using an external SOP binary.
|
||||||
*
|
*
|
||||||
* Instantiate an [ExternalSOP] object for the given binary and the given [TempDirProvider] using
|
* Instantiate an [ExternalSOP] object for the given binary and the given [TempDirProvider] using
|
||||||
* empty environment variables.
|
* empty environment variables.
|
||||||
|
|
53
external-sop/src/main/kotlin/sop/external/ExternalSOPV.kt
vendored
Normal file
53
external-sop/src/main/kotlin/sop/external/ExternalSOPV.kt
vendored
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package sop.external
|
||||||
|
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.util.*
|
||||||
|
import sop.SOPV
|
||||||
|
import sop.external.ExternalSOP.TempDirProvider
|
||||||
|
import sop.external.operation.DetachedVerifyExternal
|
||||||
|
import sop.external.operation.InlineVerifyExternal
|
||||||
|
import sop.external.operation.VersionExternal
|
||||||
|
import sop.operation.DetachedVerify
|
||||||
|
import sop.operation.InlineVerify
|
||||||
|
import sop.operation.Version
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the [SOPV] API subset using an external sopv/sop binary.
|
||||||
|
*
|
||||||
|
* Instantiate an [ExternalSOPV] object for the given binary and the given [TempDirProvider] using
|
||||||
|
* empty environment variables.
|
||||||
|
*
|
||||||
|
* @param binaryName name / path of the sopv binary
|
||||||
|
* @param tempDirProvider custom tempDirProvider
|
||||||
|
*/
|
||||||
|
class ExternalSOPV(
|
||||||
|
private val binaryName: String,
|
||||||
|
private val properties: Properties = Properties(),
|
||||||
|
private val tempDirProvider: TempDirProvider = defaultTempDirProvider()
|
||||||
|
) : SOPV {
|
||||||
|
|
||||||
|
override fun version(): Version = VersionExternal(binaryName, properties)
|
||||||
|
|
||||||
|
override fun detachedVerify(): DetachedVerify = DetachedVerifyExternal(binaryName, properties)
|
||||||
|
|
||||||
|
override fun inlineVerify(): InlineVerify =
|
||||||
|
InlineVerifyExternal(binaryName, properties, tempDirProvider)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default implementation of the [TempDirProvider] which stores temporary files in the
|
||||||
|
* systems temp dir ([Files.createTempDirectory]).
|
||||||
|
*
|
||||||
|
* @return default implementation
|
||||||
|
*/
|
||||||
|
@JvmStatic
|
||||||
|
fun defaultTempDirProvider(): TempDirProvider {
|
||||||
|
return TempDirProvider { Files.createTempDirectory("ext-sopv").toFile() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -68,6 +68,10 @@ class VersionExternal(binary: String, environment: Properties) : Version {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getSopVVersion(): String {
|
||||||
|
return executeForLines(commandList.plus("--sopv"))
|
||||||
|
}
|
||||||
|
|
||||||
override fun getSopSpecVersion(): String {
|
override fun getSopSpecVersion(): String {
|
||||||
return executeForLines(commandList.plus("--sop-spec"))
|
return executeForLines(commandList.plus("--sop-spec"))
|
||||||
}
|
}
|
||||||
|
|
98
sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopVCLI.kt
Normal file
98
sop-java-picocli/src/main/kotlin/sop/cli/picocli/SopVCLI.kt
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package sop.cli.picocli
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
import kotlin.system.exitProcess
|
||||||
|
import picocli.AutoComplete
|
||||||
|
import picocli.CommandLine
|
||||||
|
import sop.SOPV
|
||||||
|
import sop.cli.picocli.commands.*
|
||||||
|
import sop.exception.SOPGPException
|
||||||
|
|
||||||
|
@CommandLine.Command(
|
||||||
|
name = "sopv",
|
||||||
|
resourceBundle = "msg_sop",
|
||||||
|
exitCodeOnInvalidInput = SOPGPException.UnsupportedSubcommand.EXIT_CODE,
|
||||||
|
subcommands =
|
||||||
|
[
|
||||||
|
// Meta subcommands
|
||||||
|
VersionCmd::class,
|
||||||
|
// signature verification subcommands
|
||||||
|
VerifyCmd::class,
|
||||||
|
InlineVerifyCmd::class,
|
||||||
|
// misc
|
||||||
|
CommandLine.HelpCommand::class,
|
||||||
|
AutoComplete.GenerateCompletion::class])
|
||||||
|
class SopVCLI {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@JvmStatic private var sopvInstance: SOPV? = null
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getSopV(): SOPV =
|
||||||
|
checkNotNull(sopvInstance) { cliMsg.getString("sop.error.runtime.no_backend_set") }
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun setSopVInstance(sopv: SOPV?) {
|
||||||
|
sopvInstance = sopv
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmField var cliMsg: ResourceBundle = ResourceBundle.getBundle("msg_sop")
|
||||||
|
|
||||||
|
@JvmField var EXECUTABLE_NAME = "sopv"
|
||||||
|
|
||||||
|
@JvmField
|
||||||
|
@CommandLine.Option(names = ["--stacktrace"], scope = CommandLine.ScopeType.INHERIT)
|
||||||
|
var stacktrace = false
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun main(vararg args: String) {
|
||||||
|
val exitCode = execute(*args)
|
||||||
|
if (exitCode != 0) {
|
||||||
|
exitProcess(exitCode)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun execute(vararg args: String): Int {
|
||||||
|
// Set locale
|
||||||
|
CommandLine(InitLocale()).parseArgs(*args)
|
||||||
|
|
||||||
|
// Re-set bundle with updated locale
|
||||||
|
cliMsg = ResourceBundle.getBundle("msg_sop")
|
||||||
|
|
||||||
|
return CommandLine(SopVCLI::class.java)
|
||||||
|
.apply {
|
||||||
|
// explicitly set help command resource bundle
|
||||||
|
subcommands["help"]?.setResourceBundle(ResourceBundle.getBundle("msg_help"))
|
||||||
|
// Hide generate-completion command
|
||||||
|
subcommands["generate-completion"]?.commandSpec?.usageMessage()?.hidden(true)
|
||||||
|
// overwrite executable name
|
||||||
|
commandName = EXECUTABLE_NAME
|
||||||
|
// setup exception handling
|
||||||
|
executionExceptionHandler = SOPExecutionExceptionHandler()
|
||||||
|
exitCodeExceptionMapper = SOPExceptionExitCodeMapper()
|
||||||
|
isCaseInsensitiveEnumValuesAllowed = true
|
||||||
|
}
|
||||||
|
.execute(*args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control the locale.
|
||||||
|
*
|
||||||
|
* @see <a href="https://picocli.info/#_controlling_the_locale">Picocli Readme</a>
|
||||||
|
*/
|
||||||
|
@CommandLine.Command
|
||||||
|
class InitLocale {
|
||||||
|
@CommandLine.Option(names = ["-l", "--locale"], descriptionKey = "sop.locale")
|
||||||
|
fun setLocale(locale: String) = Locale.setDefault(Locale(locale))
|
||||||
|
|
||||||
|
@CommandLine.Unmatched
|
||||||
|
var remainder: MutableList<String> =
|
||||||
|
mutableListOf() // ignore any other parameters and options in the first parsing phase
|
||||||
|
}
|
||||||
|
}
|
|
@ -22,6 +22,7 @@ class VersionCmd : AbstractSopCmd() {
|
||||||
@Option(names = ["--extended"]) var extended: Boolean = false
|
@Option(names = ["--extended"]) var extended: Boolean = false
|
||||||
@Option(names = ["--backend"]) var backend: Boolean = false
|
@Option(names = ["--backend"]) var backend: Boolean = false
|
||||||
@Option(names = ["--sop-spec"]) var sopSpec: Boolean = false
|
@Option(names = ["--sop-spec"]) var sopSpec: Boolean = false
|
||||||
|
@Option(names = ["--sopv"]) var sopv: Boolean = false
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun run() {
|
override fun run() {
|
||||||
|
@ -47,5 +48,10 @@ class VersionCmd : AbstractSopCmd() {
|
||||||
println(version.getSopSpecVersion())
|
println(version.getSopSpecVersion())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (exclusive!!.sopv) {
|
||||||
|
println(version.getSopVVersion())
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
sop.name=sop
|
sop.name=sop
|
||||||
|
sopv.name=sopv
|
||||||
usage.header=Stateless OpenPGP Protocol
|
usage.header=Stateless OpenPGP Protocol
|
||||||
|
sopv.usage.header=Stateless OpenPGP Protocol - Signature Verification Interface Subset
|
||||||
locale=Locale for description texts
|
locale=Locale for description texts
|
||||||
|
|
||||||
# Generic
|
# Generic
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
sop.name=sop
|
sop.name=sop
|
||||||
|
sopv.name=sopv
|
||||||
usage.header=Stateless OpenPGP Protocol
|
usage.header=Stateless OpenPGP Protocol
|
||||||
|
sopv.usage.header=Stateless OpenPGP Protocol - Signature Verification Interface Subset
|
||||||
locale=Gebietsschema für Beschreibungstexte
|
locale=Gebietsschema für Beschreibungstexte
|
||||||
|
|
||||||
# Generic
|
# Generic
|
||||||
|
|
|
@ -9,16 +9,13 @@ import sop.operation.ChangeKeyPassword
|
||||||
import sop.operation.Dearmor
|
import sop.operation.Dearmor
|
||||||
import sop.operation.Decrypt
|
import sop.operation.Decrypt
|
||||||
import sop.operation.DetachedSign
|
import sop.operation.DetachedSign
|
||||||
import sop.operation.DetachedVerify
|
|
||||||
import sop.operation.Encrypt
|
import sop.operation.Encrypt
|
||||||
import sop.operation.ExtractCert
|
import sop.operation.ExtractCert
|
||||||
import sop.operation.GenerateKey
|
import sop.operation.GenerateKey
|
||||||
import sop.operation.InlineDetach
|
import sop.operation.InlineDetach
|
||||||
import sop.operation.InlineSign
|
import sop.operation.InlineSign
|
||||||
import sop.operation.InlineVerify
|
|
||||||
import sop.operation.ListProfiles
|
import sop.operation.ListProfiles
|
||||||
import sop.operation.RevokeKey
|
import sop.operation.RevokeKey
|
||||||
import sop.operation.Version
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stateless OpenPGP Interface. This class provides a stateless interface to various OpenPGP related
|
* Stateless OpenPGP Interface. This class provides a stateless interface to various OpenPGP related
|
||||||
|
@ -26,10 +23,7 @@ import sop.operation.Version
|
||||||
* intended for reuse. If you for example need to generate multiple keys, make a dedicated call to
|
* intended for reuse. If you for example need to generate multiple keys, make a dedicated call to
|
||||||
* [generateKey] once per key generation.
|
* [generateKey] once per key generation.
|
||||||
*/
|
*/
|
||||||
interface SOP {
|
interface SOP : SOPV {
|
||||||
|
|
||||||
/** Get information about the implementations name and version. */
|
|
||||||
fun version(): Version
|
|
||||||
|
|
||||||
/** Generate a secret key. */
|
/** Generate a secret key. */
|
||||||
fun generateKey(): GenerateKey
|
fun generateKey(): GenerateKey
|
||||||
|
@ -53,24 +47,6 @@ interface SOP {
|
||||||
*/
|
*/
|
||||||
fun inlineSign(): InlineSign
|
fun inlineSign(): InlineSign
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify detached signatures. If you need to verify an inline-signed message, use
|
|
||||||
* [inlineVerify] instead.
|
|
||||||
*/
|
|
||||||
fun verify(): DetachedVerify = detachedVerify()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify detached signatures. If you need to verify an inline-signed message, use
|
|
||||||
* [inlineVerify] instead.
|
|
||||||
*/
|
|
||||||
fun detachedVerify(): DetachedVerify
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify signatures of an inline-signed message. If you need to verify detached signatures over
|
|
||||||
* a message, use [detachedVerify] instead.
|
|
||||||
*/
|
|
||||||
fun inlineVerify(): InlineVerify
|
|
||||||
|
|
||||||
/** Detach signatures from an inline signed message. */
|
/** Detach signatures from an inline signed message. */
|
||||||
fun inlineDetach(): InlineDetach
|
fun inlineDetach(): InlineDetach
|
||||||
|
|
||||||
|
|
34
sop-java/src/main/kotlin/sop/SOPV.kt
Normal file
34
sop-java/src/main/kotlin/sop/SOPV.kt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
// SPDX-FileCopyrightText: 2024 Paul Schaub <vanitasvitae@fsfe.org>
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
package sop
|
||||||
|
|
||||||
|
import sop.operation.DetachedVerify
|
||||||
|
import sop.operation.InlineVerify
|
||||||
|
import sop.operation.Version
|
||||||
|
|
||||||
|
/** Subset of [SOP] implementing only OpenPGP signature verification. */
|
||||||
|
interface SOPV {
|
||||||
|
|
||||||
|
/** Get information about the implementations name and version. */
|
||||||
|
fun version(): Version
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify detached signatures. If you need to verify an inline-signed message, use
|
||||||
|
* [inlineVerify] instead.
|
||||||
|
*/
|
||||||
|
fun verify(): DetachedVerify = detachedVerify()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify detached signatures. If you need to verify an inline-signed message, use
|
||||||
|
* [inlineVerify] instead.
|
||||||
|
*/
|
||||||
|
fun detachedVerify(): DetachedVerify
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify signatures of an inline-signed message. If you need to verify detached signatures over
|
||||||
|
* a message, use [detachedVerify] instead.
|
||||||
|
*/
|
||||||
|
fun inlineVerify(): InlineVerify
|
||||||
|
}
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
package sop.operation
|
package sop.operation
|
||||||
|
|
||||||
|
import kotlin.jvm.Throws
|
||||||
|
import sop.exception.SOPGPException
|
||||||
|
|
||||||
interface Version {
|
interface Version {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,4 +100,11 @@ interface Version {
|
||||||
* @return remarks or null
|
* @return remarks or null
|
||||||
*/
|
*/
|
||||||
fun getSopSpecImplementationRemarks(): String?
|
fun getSopSpecImplementationRemarks(): String?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the single-line SEMVER version of the sopv interface subset it provides complete
|
||||||
|
* coverage of. If the implementation does not provide complete coverage for any sopv interface,
|
||||||
|
* this method throws an [SOPGPException.UnsupportedOption] instead.
|
||||||
|
*/
|
||||||
|
@Throws(SOPGPException.UnsupportedOption::class) fun getSopVVersion(): String
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,4 +327,15 @@ public class EncryptDecryptTest extends AbstractSOPTest {
|
||||||
.toByteArrayAndResult()
|
.toByteArrayAndResult()
|
||||||
.getBytes());
|
.getBytes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideInstances")
|
||||||
|
public void passingSecretKeysForPublicKeysFails(SOP sop) {
|
||||||
|
assertThrows(SOPGPException.BadData.class, () ->
|
||||||
|
sop.encrypt()
|
||||||
|
.withCert(TestData.ALICE_KEY.getBytes(StandardCharsets.UTF_8))
|
||||||
|
.plaintext(TestData.PLAINTEXT.getBytes(StandardCharsets.UTF_8))
|
||||||
|
.toByteArrayAndResult()
|
||||||
|
.getBytes());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,15 @@ import org.junit.jupiter.api.condition.EnabledIf;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
import org.junit.jupiter.params.provider.Arguments;
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
import org.junit.jupiter.params.provider.MethodSource;
|
import org.junit.jupiter.params.provider.MethodSource;
|
||||||
|
import org.opentest4j.TestAbortedException;
|
||||||
import sop.SOP;
|
import sop.SOP;
|
||||||
|
import sop.exception.SOPGPException;
|
||||||
|
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
import static org.junit.jupiter.api.Assumptions.assumeTrue;
|
|
||||||
|
|
||||||
@EnabledIf("sop.testsuite.operation.AbstractSOPTest#hasBackends")
|
@EnabledIf("sop.testsuite.operation.AbstractSOPTest#hasBackends")
|
||||||
public class VersionTest extends AbstractSOPTest {
|
public class VersionTest extends AbstractSOPTest {
|
||||||
|
@ -59,7 +60,7 @@ public class VersionTest extends AbstractSOPTest {
|
||||||
try {
|
try {
|
||||||
sop.version().getSopSpecVersion();
|
sop.version().getSopSpecVersion();
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
assumeTrue(false); // SOP backend does not support this operation yet
|
throw new TestAbortedException("SOP backend does not support 'version --sop-spec' yet.");
|
||||||
}
|
}
|
||||||
|
|
||||||
String sopSpec = sop.version().getSopSpecVersion();
|
String sopSpec = sop.version().getSopSpecVersion();
|
||||||
|
@ -72,4 +73,17 @@ public class VersionTest extends AbstractSOPTest {
|
||||||
int sopRevision = sop.version().getSopSpecRevisionNumber();
|
int sopRevision = sop.version().getSopSpecRevisionNumber();
|
||||||
assertTrue(sop.version().getSopSpecRevisionName().endsWith("" + sopRevision));
|
assertTrue(sop.version().getSopSpecRevisionName().endsWith("" + sopRevision));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@MethodSource("provideInstances")
|
||||||
|
public void sopVVersionTest(SOP sop) {
|
||||||
|
try {
|
||||||
|
sop.version().getSopVVersion();
|
||||||
|
} catch (SOPGPException.UnsupportedOption e) {
|
||||||
|
throw new TestAbortedException(
|
||||||
|
"Implementation does (gracefully) not provide coverage for any sopv interface version.");
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
throw new TestAbortedException("Implementation does not provide coverage for any sopv interface version.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
ext {
|
ext {
|
||||||
shortVersion = '8.0.2'
|
shortVersion = '10.0.1'
|
||||||
isSnapshot = true
|
isSnapshot = true
|
||||||
minAndroidSdk = 10
|
minAndroidSdk = 10
|
||||||
javaSourceCompatibility = 1.8
|
javaSourceCompatibility = 1.8
|
||||||
|
@ -12,7 +12,7 @@ allprojects {
|
||||||
jsrVersion = '3.0.2'
|
jsrVersion = '3.0.2'
|
||||||
junitVersion = '5.8.2'
|
junitVersion = '5.8.2'
|
||||||
junitSysExitVersion = '1.1.2'
|
junitSysExitVersion = '1.1.2'
|
||||||
logbackVersion = '1.2.11'
|
logbackVersion = '1.2.13'
|
||||||
mockitoVersion = '4.5.1'
|
mockitoVersion = '4.5.1'
|
||||||
picocliVersion = '4.6.3'
|
picocliVersion = '4.6.3'
|
||||||
slf4jVersion = '1.7.36'
|
slf4jVersion = '1.7.36'
|
||||||
|
|
Loading…
Reference in a new issue