Moved some shared arbitrary test methods to a new ArbitraryUtils class.

This commit is contained in:
CalDescent 2021-12-04 14:26:10 +00:00
parent 6026b7800a
commit a3038da3d7
4 changed files with 109 additions and 102 deletions

View File

@ -7,6 +7,7 @@ import org.qortal.arbitrary.ArbitraryDataCreatePatch;
import org.qortal.arbitrary.ArbitraryDataDigest; import org.qortal.arbitrary.ArbitraryDataDigest;
import org.qortal.crypto.Crypto; import org.qortal.crypto.Crypto;
import org.qortal.repository.DataException; import org.qortal.repository.DataException;
import org.qortal.test.common.ArbitraryUtils;
import org.qortal.test.common.Common; import org.qortal.test.common.Common;
import java.io.BufferedWriter; import java.io.BufferedWriter;
@ -239,7 +240,7 @@ public class ArbitraryDataMergeTests extends Common {
// Write a random string to the first file // Write a random string to the first file
BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file1)); BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file1));
String initialString = this.generateRandomString(1024); String initialString = ArbitraryUtils.generateRandomString(1024);
// Add a newline every 50 chars // Add a newline every 50 chars
initialString = initialString.replaceAll("(.{50})", "$1\n"); initialString = initialString.replaceAll("(.{50})", "$1\n");
file1Writer.write(initialString); file1Writer.write(initialString);
@ -308,7 +309,7 @@ public class ArbitraryDataMergeTests extends Common {
// Write a random string to the first file // Write a random string to the first file
BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file1)); BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file1));
String initialString = this.generateRandomString(1024); String initialString = ArbitraryUtils.generateRandomString(1024);
// Add a newline every 50 chars // Add a newline every 50 chars
initialString = initialString.replaceAll("(.{50})", "$1\n"); initialString = initialString.replaceAll("(.{50})", "$1\n");
// Remove newline at end of string // Remove newline at end of string
@ -382,7 +383,7 @@ public class ArbitraryDataMergeTests extends Common {
// Write a random string to the first file // Write a random string to the first file
BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file1)); BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file1));
String initialString = this.generateRandomString(110 * 1024); String initialString = ArbitraryUtils.generateRandomString(110 * 1024);
// Add a newline every 50 chars // Add a newline every 50 chars
initialString = initialString.replaceAll("(.{50})", "$1\n"); initialString = initialString.replaceAll("(.{50})", "$1\n");
file1Writer.write(initialString); file1Writer.write(initialString);
@ -442,16 +443,4 @@ public class ArbitraryDataMergeTests extends Common {
} }
private String generateRandomString(int length) {
int leftLimit = 48; // numeral '0'
int rightLimit = 122; // letter 'z'
Random random = new Random();
return random.ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
.limit(length)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
} }

View File

@ -17,6 +17,7 @@ import org.qortal.data.transaction.RegisterNameTransactionData;
import org.qortal.repository.DataException; import org.qortal.repository.DataException;
import org.qortal.repository.Repository; import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager; import org.qortal.repository.RepositoryManager;
import org.qortal.test.common.ArbitraryUtils;
import org.qortal.test.common.BlockUtils; import org.qortal.test.common.BlockUtils;
import org.qortal.test.common.Common; import org.qortal.test.common.Common;
import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.TransactionUtils;
@ -55,15 +56,15 @@ public class ArbitraryDataTests extends Common {
// Create PUT transaction // Create PUT transaction
Path path1 = Paths.get("src/test/resources/arbitrary/demo1"); Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice);
// Create PATCH transaction // Create PATCH transaction
Path path2 = Paths.get("src/test/resources/arbitrary/demo2"); Path path2 = Paths.get("src/test/resources/arbitrary/demo2");
this.createAndMintTxn(repository, publicKey58, path2, name, identifier, Method.PATCH, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path2, name, identifier, Method.PATCH, service, alice);
// Create another PATCH transaction // Create another PATCH transaction
Path path3 = Paths.get("src/test/resources/arbitrary/demo3"); Path path3 = Paths.get("src/test/resources/arbitrary/demo3");
this.createAndMintTxn(repository, publicKey58, path3, name, identifier, Method.PATCH, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path3, name, identifier, Method.PATCH, service, alice);
// Now build the latest data state for this name // Now build the latest data state for this name
ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier); ArbitraryDataReader arbitraryDataReader = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier);
@ -100,7 +101,7 @@ public class ArbitraryDataTests extends Common {
// Create PATCH transaction, ensuring that an exception is thrown // Create PATCH transaction, ensuring that an exception is thrown
try { try {
Path path1 = Paths.get("src/test/resources/arbitrary/demo1"); Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PATCH, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PATCH, service, alice);
fail("Creating transaction should fail due to nonexistent PUT transaction"); fail("Creating transaction should fail due to nonexistent PUT transaction");
} catch (DataException expectedException) { } catch (DataException expectedException) {
@ -126,7 +127,7 @@ public class ArbitraryDataTests extends Common {
// Create PUT transaction, ensuring that an exception is thrown // Create PUT transaction, ensuring that an exception is thrown
try { try {
Path path1 = Paths.get("src/test/resources/arbitrary/demo1"); Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice);
fail("Creating transaction should fail due to the name being unregistered"); fail("Creating transaction should fail due to the name being unregistered");
} catch (DataException expectedException) { } catch (DataException expectedException) {
@ -149,7 +150,7 @@ public class ArbitraryDataTests extends Common {
// Create PUT transaction // Create PUT transaction
Path path1 = Paths.get("src/test/resources/arbitrary/demo1"); Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
this.createAndMintTxn(repository, Base58.encode(alice.getPublicKey()), path1, name, identifier, Method.PUT, service, alice); ArbitraryUtils.createAndMintTxn(repository, Base58.encode(alice.getPublicKey()), path1, name, identifier, Method.PUT, service, alice);
// Bob attempts to update Alice's data // Bob attempts to update Alice's data
PrivateKeyAccount bob = Common.getTestAccount(repository, "bob"); PrivateKeyAccount bob = Common.getTestAccount(repository, "bob");
@ -157,7 +158,7 @@ public class ArbitraryDataTests extends Common {
// Create PATCH transaction, ensuring that an exception is thrown // Create PATCH transaction, ensuring that an exception is thrown
try { try {
Path path2 = Paths.get("src/test/resources/arbitrary/demo2"); Path path2 = Paths.get("src/test/resources/arbitrary/demo2");
this.createAndMintTxn(repository, Base58.encode(bob.getPublicKey()), path2, name, identifier, Method.PATCH, service, bob); ArbitraryUtils.createAndMintTxn(repository, Base58.encode(bob.getPublicKey()), path2, name, identifier, Method.PATCH, service, bob);
fail("Creating transaction should fail due to the name being registered to Alice instead of Bob"); fail("Creating transaction should fail due to the name being registered to Alice instead of Bob");
} catch (DataException expectedException) { } catch (DataException expectedException) {
@ -181,7 +182,7 @@ public class ArbitraryDataTests extends Common {
// Create PUT transaction // Create PUT transaction
Path path1 = Paths.get("src/test/resources/arbitrary/demo1"); Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice);
// Now build the latest data state for this name // Now build the latest data state for this name
ArbitraryDataReader arbitraryDataReader1 = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier); ArbitraryDataReader arbitraryDataReader1 = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier);
@ -192,7 +193,7 @@ public class ArbitraryDataTests extends Common {
// Create PATCH transaction // Create PATCH transaction
Path path2 = Paths.get("src/test/resources/arbitrary/demo2"); Path path2 = Paths.get("src/test/resources/arbitrary/demo2");
this.createAndMintTxn(repository, publicKey58, path2, name, identifier, Method.PATCH, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path2, name, identifier, Method.PATCH, service, alice);
// Rebuild the latest state // Rebuild the latest state
ArbitraryDataReader arbitraryDataReader2 = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier); ArbitraryDataReader arbitraryDataReader2 = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier);
@ -226,7 +227,7 @@ public class ArbitraryDataTests extends Common {
// Create PUT transaction // Create PUT transaction
Path path1 = Paths.get("src/test/resources/arbitrary/demo1"); Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice);
// Build the latest data state for this name, with a null identifier, ensuring that it fails // Build the latest data state for this name, with a null identifier, ensuring that it fails
ArbitraryDataReader arbitraryDataReader1a = new ArbitraryDataReader(name, ResourceIdType.NAME, service, null); ArbitraryDataReader arbitraryDataReader1a = new ArbitraryDataReader(name, ResourceIdType.NAME, service, null);
@ -260,7 +261,7 @@ public class ArbitraryDataTests extends Common {
// Create PATCH transaction // Create PATCH transaction
Path path2 = Paths.get("src/test/resources/arbitrary/demo2"); Path path2 = Paths.get("src/test/resources/arbitrary/demo2");
this.createAndMintTxn(repository, publicKey58, path2, name, identifier, Method.PATCH, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path2, name, identifier, Method.PATCH, service, alice);
// Rebuild the latest state // Rebuild the latest state
ArbitraryDataReader arbitraryDataReader2 = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier); ArbitraryDataReader arbitraryDataReader2 = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier);
@ -296,7 +297,7 @@ public class ArbitraryDataTests extends Common {
Path path1 = Paths.get("src/test/resources/arbitrary/demo1"); Path path1 = Paths.get("src/test/resources/arbitrary/demo1");
ArbitraryDataDigest path1Digest = new ArbitraryDataDigest(path1); ArbitraryDataDigest path1Digest = new ArbitraryDataDigest(path1);
path1Digest.compute(); path1Digest.compute();
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice);
// Now build the latest data state for this name with a null identifier, ensuring that it succeeds and the data matches // Now build the latest data state for this name with a null identifier, ensuring that it succeeds and the data matches
ArbitraryDataReader arbitraryDataReader1a = new ArbitraryDataReader(name, ResourceIdType.NAME, service, null); ArbitraryDataReader arbitraryDataReader1a = new ArbitraryDataReader(name, ResourceIdType.NAME, service, null);
@ -346,7 +347,7 @@ public class ArbitraryDataTests extends Common {
byte[] path1FileDigest = Crypto.digest(path1.toFile()); byte[] path1FileDigest = Crypto.digest(path1.toFile());
ArbitraryDataDigest path1DirectoryDigest = new ArbitraryDataDigest(path1.getParent()); ArbitraryDataDigest path1DirectoryDigest = new ArbitraryDataDigest(path1.getParent());
path1DirectoryDigest.compute(); path1DirectoryDigest.compute();
this.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice); ArbitraryUtils.createAndMintTxn(repository, publicKey58, path1, name, identifier, Method.PUT, service, alice);
// Now build the latest data state for this name // Now build the latest data state for this name
ArbitraryDataReader arbitraryDataReader1 = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier); ArbitraryDataReader arbitraryDataReader1 = new ArbitraryDataReader(name, ResourceIdType.NAME, service, identifier);
@ -365,18 +366,4 @@ public class ArbitraryDataTests extends Common {
} }
} }
private void createAndMintTxn(Repository repository, String publicKey58, Path path, String name, String identifier,
Method method, Service service, PrivateKeyAccount account) throws DataException {
ArbitraryDataTransactionBuilder txnBuilder = new ArbitraryDataTransactionBuilder(
repository, publicKey58, path, name, method, service, identifier);
txnBuilder.build();
txnBuilder.computeNonce();
ArbitraryTransactionData transactionData = txnBuilder.getArbitraryTransactionData();
Transaction.ValidationResult result = TransactionUtils.signAndImport(repository, transactionData, account);
assertEquals(Transaction.ValidationResult.OK, result);
BlockUtils.mintBlock(repository);
}
} }

View File

@ -15,6 +15,7 @@ import org.qortal.data.transaction.RegisterNameTransactionData;
import org.qortal.repository.DataException; import org.qortal.repository.DataException;
import org.qortal.repository.Repository; import org.qortal.repository.Repository;
import org.qortal.repository.RepositoryManager; import org.qortal.repository.RepositoryManager;
import org.qortal.test.common.ArbitraryUtils;
import org.qortal.test.common.BlockUtils; import org.qortal.test.common.BlockUtils;
import org.qortal.test.common.Common; import org.qortal.test.common.Common;
import org.qortal.test.common.TransactionUtils; import org.qortal.test.common.TransactionUtils;
@ -56,8 +57,8 @@ public class ArbitraryTransactionMetadataTests extends Common {
TransactionUtils.signAndMint(repository, transactionData, alice); TransactionUtils.signAndMint(repository, transactionData, alice);
// Create PUT transaction // Create PUT transaction
Path path1 = generateRandomDataPath(dataLength); Path path1 = ArbitraryUtils.generateRandomDataPath(dataLength);
ArbitraryDataFile arbitraryDataFile = this.createAndMintTxn(repository, publicKey58, path1, name, identifier, ArbitraryTransactionData.Method.PUT, service, alice, chunkSize); ArbitraryDataFile arbitraryDataFile = ArbitraryUtils.createAndMintTxn(repository, publicKey58, path1, name, identifier, ArbitraryTransactionData.Method.PUT, service, alice, chunkSize);
// Check the chunk count is correct // Check the chunk count is correct
assertEquals(10, arbitraryDataFile.chunkCount()); assertEquals(10, arbitraryDataFile.chunkCount());
@ -76,61 +77,4 @@ public class ArbitraryTransactionMetadataTests extends Common {
} }
} }
private Path generateRandomDataPath(int length) throws IOException {
// Create a file in a random temp directory
Path tempDir = Files.createTempDirectory("generateRandomDataPath");
File file = new File(Paths.get(tempDir.toString(), "file.txt").toString());
file.deleteOnExit();
// Write a random string to the file
BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file));
String initialString = this.generateRandomString(length - 1); // -1 due to newline at EOF
// Add a newline every 50 chars
// initialString = initialString.replaceAll("(.{50})", "$1\n");
file1Writer.write(initialString);
file1Writer.newLine();
file1Writer.close();
return tempDir;
}
private String generateRandomString(int length) {
int leftLimit = 48; // numeral '0'
int rightLimit = 122; // letter 'z'
Random random = new Random();
return random.ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
.limit(length)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
private ArbitraryDataFile createAndMintTxn(Repository repository, String publicKey58, Path path, String name, String identifier,
ArbitraryTransactionData.Method method, Service service, PrivateKeyAccount account,
int chunkSize) throws DataException {
ArbitraryDataTransactionBuilder txnBuilder = new ArbitraryDataTransactionBuilder(
repository, publicKey58, path, name, method, service, identifier);
txnBuilder.setChunkSize(chunkSize);
txnBuilder.build();
txnBuilder.computeNonce();
ArbitraryTransactionData transactionData = txnBuilder.getArbitraryTransactionData();
Transaction.ValidationResult result = TransactionUtils.signAndImport(repository, transactionData, account);
assertEquals(Transaction.ValidationResult.OK, result);
BlockUtils.mintBlock(repository);
// We need a new ArbitraryDataFile instance because the files will have been moved to the signature's folder
byte[] hash = txnBuilder.getArbitraryDataFile().getHash();
byte[] signature = transactionData.getSignature();
ArbitraryDataFile arbitraryDataFile = ArbitraryDataFile.fromHash(hash, signature);
arbitraryDataFile.setMetadataHash(transactionData.getMetadataHash());
return arbitraryDataFile;
}
} }

View File

@ -1,2 +1,89 @@
package org.qortal.test.common;public class ArbitraryUtils { package org.qortal.test.common;
import org.qortal.account.PrivateKeyAccount;
import org.qortal.arbitrary.ArbitraryDataFile;
import org.qortal.arbitrary.ArbitraryDataTransactionBuilder;
import org.qortal.arbitrary.misc.Service;
import org.qortal.data.transaction.ArbitraryTransactionData;
import org.qortal.repository.DataException;
import org.qortal.repository.Repository;
import org.qortal.transaction.Transaction;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Random;
import static org.junit.Assert.assertEquals;
public class ArbitraryUtils {
public static ArbitraryDataFile createAndMintTxn(Repository repository, String publicKey58, Path path, String name, String identifier,
ArbitraryTransactionData.Method method, Service service, PrivateKeyAccount account,
int chunkSize) throws DataException {
ArbitraryDataTransactionBuilder txnBuilder = new ArbitraryDataTransactionBuilder(
repository, publicKey58, path, name, method, service, identifier);
txnBuilder.setChunkSize(chunkSize);
txnBuilder.build();
txnBuilder.computeNonce();
ArbitraryTransactionData transactionData = txnBuilder.getArbitraryTransactionData();
Transaction.ValidationResult result = TransactionUtils.signAndImport(repository, transactionData, account);
assertEquals(Transaction.ValidationResult.OK, result);
BlockUtils.mintBlock(repository);
// We need a new ArbitraryDataFile instance because the files will have been moved to the signature's folder
byte[] hash = txnBuilder.getArbitraryDataFile().getHash();
byte[] signature = transactionData.getSignature();
ArbitraryDataFile arbitraryDataFile = ArbitraryDataFile.fromHash(hash, signature);
arbitraryDataFile.setMetadataHash(transactionData.getMetadataHash());
return arbitraryDataFile;
}
public static ArbitraryDataFile createAndMintTxn(Repository repository, String publicKey58, Path path, String name, String identifier,
ArbitraryTransactionData.Method method, Service service, PrivateKeyAccount account) throws DataException {
// Use default chunk size
int chunkSize = ArbitraryDataFile.CHUNK_SIZE;
return ArbitraryUtils.createAndMintTxn(repository, publicKey58, path, name, identifier, method, service, account, chunkSize);
}
public static Path generateRandomDataPath(int length) throws IOException {
// Create a file in a random temp directory
Path tempDir = Files.createTempDirectory("generateRandomDataPath");
File file = new File(Paths.get(tempDir.toString(), "file.txt").toString());
file.deleteOnExit();
// Write a random string to the file
BufferedWriter file1Writer = new BufferedWriter(new FileWriter(file));
String initialString = ArbitraryUtils.generateRandomString(length - 1); // -1 due to newline at EOF
// Add a newline every 50 chars
// initialString = initialString.replaceAll("(.{50})", "$1\n");
file1Writer.write(initialString);
file1Writer.newLine();
file1Writer.close();
return tempDir;
}
public static String generateRandomString(int length) {
int leftLimit = 48; // numeral '0'
int rightLimit = 122; // letter 'z'
Random random = new Random();
return random.ints(leftLimit, rightLimit + 1)
.filter(i -> (i <= 57 || i >= 65) && (i <= 90 || i >= 97))
.limit(length)
.collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
.toString();
}
} }