mirror of
https://github.com/corda/corda.git
synced 2025-01-18 10:46:38 +00:00
CORDA-2175 Fix attachment service tests on Windows (#4168)
* Switch to directory per test and suppress deletion exception on windows to deal with the fact that NTFS keeps files locked to the running process once opened. * Closing files when we're done makes all the file locking issues go away.
This commit is contained in:
parent
015a36dad6
commit
1f5436dcfc
@ -35,6 +35,7 @@ import net.corda.testing.node.internal.startFlow
|
||||
import org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
import org.junit.*
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.Closeable
|
||||
import java.io.OutputStream
|
||||
import java.net.URI
|
||||
import java.nio.charset.StandardCharsets
|
||||
@ -80,25 +81,30 @@ class NodeAttachmentServiceTest {
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
dir.list { subdir ->
|
||||
subdir.forEach(Path::deleteRecursively)
|
||||
}
|
||||
database.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `importing a signed jar saves the signers to the storage`() {
|
||||
val jarAndSigner = makeTestSignedContractJar("com.example.MyContract")
|
||||
val signedJar = jarAndSigner.first
|
||||
val attachmentId = storage.importAttachment(signedJar.inputStream(), "test", null)
|
||||
assertEquals(listOf(jarAndSigner.second.hash), storage.openAttachment(attachmentId)!!.signers.map { it.hash })
|
||||
SelfCleaningDir().use { file ->
|
||||
val jarAndSigner = makeTestSignedContractJar(file.path, "com.example.MyContract")
|
||||
val signedJar = jarAndSigner.first
|
||||
signedJar.inputStream().use { jarStream ->
|
||||
val attachmentId = storage.importAttachment(jarStream, "test", null)
|
||||
assertEquals(listOf(jarAndSigner.second.hash), storage.openAttachment(attachmentId)!!.signers.map { it.hash })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `importing a non-signed jar will save no signers`() {
|
||||
val jarName = makeTestContractJar("com.example.MyContract")
|
||||
val attachmentId = storage.importAttachment(dir.resolve(jarName).inputStream(), "test", null)
|
||||
assertEquals(0, storage.openAttachment(attachmentId)!!.signers.size)
|
||||
SelfCleaningDir().use {
|
||||
val jarName = makeTestContractJar(it.path, "com.example.MyContract")
|
||||
it.path.resolve(jarName).inputStream().use { jarStream ->
|
||||
val attachmentId = storage.importAttachment(jarStream, "test", null)
|
||||
assertEquals(0, storage.openAttachment(attachmentId)!!.signers.size)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -127,25 +133,27 @@ class NodeAttachmentServiceTest {
|
||||
|
||||
@Test
|
||||
fun `insert contract attachment as an untrusted uploader and then as trusted CorDapp uploader`() {
|
||||
val contractJarName = makeTestContractJar("com.example.MyContract")
|
||||
val testJar = dir.resolve(contractJarName)
|
||||
val expectedHash = testJar.readAll().sha256()
|
||||
SelfCleaningDir().use { file ->
|
||||
val contractJarName = makeTestContractJar(file.path, "com.example.MyContract")
|
||||
val testJar = file.path.resolve(contractJarName)
|
||||
val expectedHash = testJar.readAll().sha256()
|
||||
|
||||
// PRIVILEGED_UPLOADERS = listOf(DEPLOYED_CORDAPP_UPLOADER, RPC_UPLOADER, P2P_UPLOADER, UNKNOWN_UPLOADER)
|
||||
// TRUSTED_UPLOADERS = listOf(DEPLOYED_CORDAPP_UPLOADER, RPC_UPLOADER)
|
||||
// PRIVILEGED_UPLOADERS = listOf(DEPLOYED_CORDAPP_UPLOADER, RPC_UPLOADER, P2P_UPLOADER, UNKNOWN_UPLOADER)
|
||||
// TRUSTED_UPLOADERS = listOf(DEPLOYED_CORDAPP_UPLOADER, RPC_UPLOADER)
|
||||
|
||||
database.transaction {
|
||||
val id = testJar.read { storage.privilegedImportOrGetAttachment(it, P2P_UPLOADER, null) }
|
||||
assertEquals(expectedHash, id)
|
||||
val attachment1 = storage.openAttachment(expectedHash)
|
||||
database.transaction {
|
||||
val id = testJar.read { storage.privilegedImportOrGetAttachment(it, P2P_UPLOADER, null) }
|
||||
assertEquals(expectedHash, id)
|
||||
val attachment1 = storage.openAttachment(expectedHash)
|
||||
|
||||
val id2 = testJar.read { storage.privilegedImportOrGetAttachment(it, DEPLOYED_CORDAPP_UPLOADER, null) }
|
||||
assertEquals(expectedHash, id2)
|
||||
val attachment2 = storage.openAttachment(expectedHash)
|
||||
val id2 = testJar.read { storage.privilegedImportOrGetAttachment(it, DEPLOYED_CORDAPP_UPLOADER, null) }
|
||||
assertEquals(expectedHash, id2)
|
||||
val attachment2 = storage.openAttachment(expectedHash)
|
||||
|
||||
assertNotEquals(attachment1, attachment2)
|
||||
assertEquals(P2P_UPLOADER, (attachment1 as ContractAttachment).uploader)
|
||||
assertEquals(DEPLOYED_CORDAPP_UPLOADER, (attachment2 as ContractAttachment).uploader)
|
||||
assertNotEquals(attachment1, attachment2)
|
||||
assertEquals(P2P_UPLOADER, (attachment1 as ContractAttachment).uploader)
|
||||
assertEquals(DEPLOYED_CORDAPP_UPLOADER, (attachment2 as ContractAttachment).uploader)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -350,20 +358,17 @@ class NodeAttachmentServiceTest {
|
||||
return Pair(file, file.readAll().sha256())
|
||||
}
|
||||
|
||||
/**
|
||||
* Class to create an automatically delete a temporary directory.
|
||||
*/
|
||||
class SelfCleaningDir : Closeable {
|
||||
val path: Path = Files.createTempDirectory(NodeAttachmentServiceTest::class.simpleName)
|
||||
override fun close() {
|
||||
path.deleteRecursively()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val dir = Files.createTempDirectory(NodeAttachmentServiceTest::class.simpleName)
|
||||
|
||||
@BeforeClass
|
||||
@JvmStatic
|
||||
fun beforeClass() {
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
@JvmStatic
|
||||
fun afterClass() {
|
||||
dir.deleteRecursively()
|
||||
}
|
||||
|
||||
private fun makeTestJar(output: OutputStream, extraEntries: List<Pair<String, String>> = emptyList()) {
|
||||
output.use {
|
||||
val jar = JarOutputStream(it)
|
||||
@ -372,33 +377,33 @@ class NodeAttachmentServiceTest {
|
||||
jar.closeEntry()
|
||||
jar.putNextEntry(JarEntry("test2.txt"))
|
||||
jar.write("Some more useful content".toByteArray())
|
||||
extraEntries.forEach {
|
||||
jar.putNextEntry(JarEntry(it.first))
|
||||
jar.write(it.second.toByteArray())
|
||||
extraEntries.forEach { entry ->
|
||||
jar.putNextEntry(JarEntry(entry.first))
|
||||
jar.write(entry.second.toByteArray())
|
||||
}
|
||||
jar.closeEntry()
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeTestSignedContractJar(contractName: String): Pair<Path, PublicKey> {
|
||||
private fun makeTestSignedContractJar(workingDir: Path, contractName: String): Pair<Path, PublicKey> {
|
||||
val alias = "testAlias"
|
||||
val pwd = "testPassword"
|
||||
dir.generateKey(alias, pwd, ALICE_NAME.toString())
|
||||
val jarName = makeTestContractJar(contractName)
|
||||
val signer = dir.signJar(jarName, alias, pwd)
|
||||
return dir.resolve(jarName) to signer
|
||||
workingDir.generateKey(alias, pwd, ALICE_NAME.toString())
|
||||
val jarName = makeTestContractJar(workingDir, contractName)
|
||||
val signer = workingDir.signJar(jarName, alias, pwd)
|
||||
return workingDir.resolve(jarName) to signer
|
||||
}
|
||||
|
||||
private fun makeTestContractJar(contractName: String): String {
|
||||
private fun makeTestContractJar(workingDir: Path, contractName: String): String {
|
||||
val packages = contractName.split(".")
|
||||
val jarName = "testattachment.jar"
|
||||
val className = packages.last()
|
||||
createTestClass(className, packages.subList(0, packages.size - 1))
|
||||
dir.createJar(jarName, "${contractName.replace(".", "/")}.class")
|
||||
createTestClass(workingDir, className, packages.subList(0, packages.size - 1))
|
||||
workingDir.createJar(jarName, "${contractName.replace(".", "/")}.class")
|
||||
return jarName
|
||||
}
|
||||
|
||||
private fun createTestClass(className: String, packages: List<String>): Path {
|
||||
private fun createTestClass(workingDir: Path, className: String, packages: List<String>): Path {
|
||||
val newClass = """package ${packages.joinToString(".")};
|
||||
import net.corda.core.contracts.*;
|
||||
import net.corda.core.transactions.*;
|
||||
@ -410,15 +415,15 @@ class NodeAttachmentServiceTest {
|
||||
}
|
||||
""".trimIndent()
|
||||
val compiler = ToolProvider.getSystemJavaCompiler()
|
||||
val source = object : SimpleJavaFileObject(URI.create("string:///${packages.joinToString("/")}/${className}.java"), JavaFileObject.Kind.SOURCE) {
|
||||
val source = object : SimpleJavaFileObject(URI.create("string:///${packages.joinToString("/")}/$className.java"), JavaFileObject.Kind.SOURCE) {
|
||||
override fun getCharContent(ignoreEncodingErrors: Boolean): CharSequence {
|
||||
return newClass
|
||||
}
|
||||
}
|
||||
val fileManager = compiler.getStandardFileManager(null, null, null)
|
||||
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, listOf(dir.toFile()))
|
||||
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, listOf(workingDir.toFile()))
|
||||
|
||||
val compile = compiler.getTask(System.out.writer(), fileManager, null, null, null, listOf(source)).call()
|
||||
compiler.getTask(System.out.writer(), fileManager, null, null, null, listOf(source)).call()
|
||||
return Paths.get(fileManager.list(StandardLocation.CLASS_OUTPUT, "", setOf(JavaFileObject.Kind.CLASS), true).single().name)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user