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:
Christian Sailer 2018-11-06 11:31:23 +00:00 committed by GitHub
parent 015a36dad6
commit 1f5436dcfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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)
}
}