JUnit test on recursive function (creating file and compare size) - java

I'm working on a project : copy a file and check if the size are equals. If not, delete file and redo it (number of retries is defined)
public boolean copieFichierAvecRetry(FileObject copieFichierFile, FileObject fichierACopier, int nbRetry, int currentNbRetry)
throws InterruptedException, IOException {
logger.logInfo("Deplacement du fichier " + fichierACopier.getName().getBaseName(),
"de " + fichierACopier.getParent().getName().getPath() + " vers "
+ copieFichierFile.getParent().getName().getPath());
copieFichierFile.copyFrom(fichierACopier, Selectors.SELECT_SELF);
boolean tailleOk = false;
// Si le flag de vérification est à true on vérifie que les fichiers
// copies ont la même taille
try {
tailleOk = verificationTailleCorrespondantes(copieFichierFile, fichierACopier);
if (!tailleOk && currentNbRetry <= nbRetry){
logger.logInfo("Erreur lors de la verification de la taille, essai n°" + currentNbRetry, null);
copieFichierFile.delete();
currentNbRetry++;
copieFichierAvecRetry(copieFichierFile, fichierACopier, nbRetry, currentNbRetry);
}
} catch (IOException e) {
logger.logWarn("Erreur lors de la verification de la taille : ", e.getMessage());
tailleOk = false;
}
return tailleOk;
}
Here is the unit test for the non-recursive function :
public void testCopieFichier()
throws IOException, InterruptedException, URISyntaxException, TransfertFichierException {
socleUtil.setNbTentativeMaxTransfert(1);
String nomFichierSource = "test123.txt";
String nomFichierDestination = "testDownloadSuccess.xml";
File fileOrigine = new File(getClass().getResource(SocleConstantes.SLASH).getFile());
String cheminFichierDistantOrigine = fileOrigine.getPath();
File fileDestination = new File(getClass().getResource(SocleConstantes.SLASH).toURI());
String cheminFichierDistantDestination = fileDestination.getPath() + FILE_SEPARATOR + "download";
assertTrue(socleUtil.copieFichier(
socleUtil.findFileLocal(cheminFichierDistantDestination + "/" + nomFichierDestination),
socleUtil.findFileLocal(cheminFichierDistantOrigine + "/" + nomFichierSource)));
assertTrue(fileDestination.exists());
}
As you can see in the code above, it will copy a file, check size and if it's OK then return true.
If it's false for 5 times (in the exemple) the function calls itself after deleting the file with wrong size.
verificationTailleCorrespondantes is the function to compare sizes.
tailleOk is true if both files are same size.
How should I test the recursivity of this function if it copies a file and never fail (which happens in production) ?
Thanks

In this case, I'd write the following scenarios:
the process success at its first iteration
the process fails at its (n-1)th iteration, success at its nth iteration with n < number of retries
the process fails at its nth iteration with n == number of retries
In order to do it, you'll need to mock your dependencies. Specially the one checking the file size. The mocking for the previous scenarios would be
file size check returns true. Assert that the check was run once and the result is valid
file size check returns false (n-1) times and true the nth time. Assert that the check was run n times and the result is valid
file size check returns false. Assert that the check was run number of retries times and the result is invalid

Related

bitcoinJ get transaction value

I downloaded a lot of blockchain data using https://bitcoin.org, I took some file and I try to analyse it with bitcoinj library.
I would like to get information from every transaction:
-who send bitcoins,
-how much,
-who receive bitcoins.
I use:
<dependency>
<groupId>org.bitcoinj</groupId>
<artifactId>bitcoinj-core</artifactId>
<version>0.15.10</version>
</dependency>
I have a code:
NetworkParameters np = new MainNetParams();
Context.getOrCreate(MainNetParams.get());
BlockFileLoader loader = new BlockFileLoader(np,List.of(new File("test/resources/blk00450.dat")));
for (Block block : loader) {
for (Transaction tx : block.getTransactions()) {
System.out.println("Transaction ID" + tx.getTxId().toString());
for (TransactionInput ti : tx.getInputs()) {
// how to get wallet addresses of inputs?
}
// this code works for 99% of transactions but for some throws exceptions
for (TransactionOutput to : tx.getOutputs()) {
// sometimes this line throws: org.bitcoinj.script.ScriptException: Cannot cast this script to an address
System.out.println("out address:" + to.getScriptPubKey().getToAddress(np));
System.out.println("out value:" + to.getValue().toString());
}
}
}
Can you share some snippet that will work for all transactions in the blockchain?
There are at least two type of transaction, P2PKH and P2SH.
Your code would work well with P2PKH, but wouldn not work with P2SH.
You can change the line from:
System.out.println("out address:" + to.getScriptPubKey().getToAddress(np));
to:
System.out.println("out address:" + to.getAddressFromP2PKHScript(np)!=null?to.getAddressFromP2PKHScript(np):to.getAddressFromP2SH(np));
The API of Bitcoin says the methods getAddressFromP2PKHScript() and getAddressFromP2SH() are deprecated, and I have not find suitable method.
However, P2SH means "Pay to Script Hash", which means it could contain two or more public keys to support multi-signature. Moreover, getAddressFromP2SH() returns only one address, perhaps this is the reason why it is deprecated.
I also wrote a convinient method to check the inputs and outputs of a block:
private void printCoinValueInOut(Block block) {
Coin blockInputSum = Coin.ZERO;
Coin blockOutputSum = Coin.ZERO;
System.out.println("--------------------Block["+block.getHashAsString()+"]------"+block.getPrevBlockHash()+"------------------------");
for(Transaction tx : block.getTransactions()) {
Coin txInputSum = tx.getOutputSum();
Coin txOutputSum = tx.getOutputSum();
blockInputSum = blockInputSum.add(txInputSum);
blockOutputSum = blockOutputSum.add(txOutputSum);
System.out.println("Tx["+tx.getTxId()+"]:\t" + txInputSum + "(satoshi) IN, " + txOutputSum + "(satoshi) OUT.");
}
System.out.println("Block total:\t" + blockInputSum + "(satoshi) IN, " + blockOutputSum + "(satoshi) OUT. \n");
}

How to fix "GetStatus Write RFID_API_UNKNOWN_ERROR data(x)- Field can Only Take Word values" Android RFID 8500 Zebra

I am trying to develop and application to read and write to RF tags. Reading is flawless, but I'm having issues with writing. Specifically the error "GetStatus Write RFID_API_UNKNOWN_ERROR data(x)- Field can Only Take Word values"
I have tried reverse-engineering the Zebra RFID API Mobile by obtaining the .apk and decoding it, but the code is obfuscated and I am not able to decypher why that application's Write works and mine doesn't.
I see the error in the https://www.ptsmobile.com/rfd8500/rfd8500-rfid-developer-guide.pdf at page 185, but I have no idea what's causing it.
I've tried forcefully changing the writeData to Hex, before I realized that the API does that on its own, I've tried changing the Length of the writeData as well, but it just gets a null value. I'm so lost.
public boolean WriteTag(String sourceEPC, long Password, MEMORY_BANK memory_bank, String targetData, int offset) {
Log.d(TAG, "WriteTag " + targetData);
try {
TagData tagData = null;
String tagId = sourceEPC;
TagAccess tagAccess = new TagAccess();
tagAccess.getClass();
TagAccess.WriteAccessParams writeAccessParams = tagAccess.new WriteAccessParams();
String writeData = targetData; //write data in string
writeAccessParams.setAccessPassword(Password);
writeAccessParams.setMemoryBank(MEMORY_BANK.MEMORY_BANK_USER);
writeAccessParams.setOffset(offset); // start writing from word offset 0
writeAccessParams.setWriteData(writeData);
// set retries in case of partial write happens
writeAccessParams.setWriteRetries(3);
// data length in words
System.out.println("length: " + writeData.length()/4);
System.out.println("length: " + writeData.length());
writeAccessParams.setWriteDataLength(writeData.length()/4);
// 5th parameter bPrefilter flag is true which means API will apply pre filter internally
// 6th parameter should be true in case of changing EPC ID it self i.e. source and target both is EPC
boolean useTIDfilter = memory_bank == MEMORY_BANK.MEMORY_BANK_EPC;
reader.Actions.TagAccess.writeWait(tagId, writeAccessParams, null, tagData, true, useTIDfilter);
} catch (InvalidUsageException e) {
System.out.println("INVALID USAGE EXCEPTION: " + e.getInfo());
e.printStackTrace();
return false;
} catch (OperationFailureException e) {
//System.out.println("OPERATION FAILURE EXCEPTION");
System.out.println("OPERATION FAILURE EXCEPTION: " + e.getResults().toString());
e.printStackTrace();
return false;
}
return true;
}
With
Password being 00
sourceEPC being the Tag ID obtained after reading
Memory Bank being MEMORY_BANK.MEMORY_BANK_USER
target data being "8426017056458"
offset being 0
It just keeps giving me "GetStatus Write RFID_API_UNKNOWN_ERROR data(x)- Field can Only Take Word values" and I have no idea why this is the case, nor I know what a "Word value" is, and i've searched for it. This is all under the "OperationFailureException", as well. Any help would be appreciated, as there's almost no resources online for this kind of thing.
Even this question is a bit older, I had the same problem so as far as I know this should be the answer.
Your target data "8426017056458" length is 13 and at writeAccessParams.setWriteDataLength(writeData.length()/4)
you are devide it with four. Now if you are trying to write the target data it is longer than the determined WriteDataLength. And this throws the Error.
One 'word' is 4 Hex => 16 Bits long. So your Data have to be filled up first and convert it to Hex.

How can I automate image upload to commercetools using JVM API

I'm a pretty new developer in CommerceTools and I've been working with this tool for just a few weeks.
At this moment I need to develop a process that should be able to upload all the images related to a product from a folder to commercetools using the JVM API.
I think the best way would be to recover the SKU (eg PROD001ABC) of each product from the CTP database and then use this string to locate in the given folder if there are images containing such SKU in the filename (PROD001ABC_front.jpg, PROD001ABC_side1.jpg, PROD001ABC_side2.jpg, etc.).
Once all the product images are located, I want to upload them to CommerceTools using the API.
As I've researched, I think I'd have to use the io.sphere.sdk.products.commands.ProductImageUploadCommand method, but I'm not sure how to get to that point.
I'm really lost.
Thanks so much for any help
Best regards.
Miguel
Basically what you need to do is to create an HttpClient and then use this client to execute the image upload command, to make things more concrete take a look at this test senario
here is the typical use of the commercetools JVM SDK for your purpose:
//create client
SphereClientConfig sphereClientConfig = SphereClientConfig.of( projectKey, clientId, clientSecret);
SphereClient client = SphereClient.of(sphereClientConfig, SphereClientFactory.of().createHttpClient(), SphereAccessTokenSupplier.ofConstantToken("accessToken"))
final ByIdVariantIdentifier identifier = product.getMasterData().getStaged().getMasterVariant().getIdentifier();
File imageFile = new File("Path to your image");
//create update commands
final ProductImageUploadCommand cmd1 = ProductImageUploadCommand
.ofVariantId(imageFile, identifier)
.withFilename("myProductImage1.gif")
.withStaged(true);
final ProductImageUploadCommand cmd2 = ProductImageUploadCommand
.ofVariantId(imageFile, identifier)
.withFilename("myProductImage2.gif")
.withStaged(true);
//update the product
final Product updatedProduct1 = client().executeBlocking(cmd1);
final Product updatedProduct = client().executeBlocking(cmd2);
//get the images
List<Image> images = updatedProduct.getMasterData().getStaged().getMasterVariant().getImages();
Hope this helps :)
Well, finally I have achieved it.
I used an attribute of my products (EAN) to locate the images in the path corresponding to "product type / EAN".
// Buscamos una carpeta con el nombre del EAN
final String pathCarpetaEan = rutaBaseLocal + "\\" + typeName + "\\" + vEan;
final File carpetaEAN = new File(pathCarpetaEan);
final File carpetaEanSubidas = new File(pathCarpetaEan + "\\subidas\\");
if (carpetaEAN.exists() && carpetaEAN.isDirectory()) {
// La carpeta existe. Buscamos imagenes dentro.
System.out.println("Encontrada la carpeta " + pathCarpetaEan);
File[] fileImages = carpetaEAN.listFiles();
for (File fileImagen : fileImages) {
if (fileImagen.isFile()) {
final String nomImagen = fileImagen.getName();
System.out.println("---\nNombre fichero: " + nomImagen);
if (nomImagen.startsWith(vEan)
&& (nomImagen.toLowerCase().endsWith(JPEG)
|| nomImagen.toLowerCase().endsWith(PNG)
|| nomImagen.toLowerCase().endsWith(GIF))) {
System.out.println("El nombre de archivo contiene el EAN: " + vEan);
System.out.println("Y se trata de una imagen");
// A partir de aqui realizamos la subida de las imagenes para la variante concreta.
final ProductImageUploadCommand cmd = ProductImageUploadCommand
.ofVariantId(fileImagen, identificador)
.withFilename(nomImagen)
.withStaged(true);
final Product updatedProduct = client.executeBlocking(cmd);
System.out.println("Uploaded your image (" + nomImagen + ") and added to the masterVariant");
System.out.println("Producto actualizado: " + updatedProduct.toString());
nUploadedImages++;
}
}
}
}
After uploading the images, I move them to another subfolder "uploaded".
Thank you very much for your help.

Problems fetching URL in java with Jsoup

Edit: I have apparently solve the problem forcing the code getting the HTML. The problem I have is that randomly the HTML is not taken. To force that I have added:
int intento = 0;
while (document == null) {
intento++;
System.out.println("Intento número: " + intento);
document = getHtmlDocument(urlPage);
}
I am experiencing this random issue. Sometimes it gives me problems when fetching an URL an as it reaches to the timeout the program execution stops. The code:
public static int getStatusConnectionCode(String url) {
Response response = null;
try {
response = Jsoup.connect(url).userAgent("Mozilla/5.0").timeout(100000).ignoreHttpErrors(true).execute();
} catch (IOException ex) {
System.out.println("Excepción al obtener el Status Code: " + ex.getMessage());
}
return response.statusCode();
}
/**
* Con este método devuelvo un objeto de la clase Document con el contenido del
* HTML de la web que me permitirá parsearlo con los métodos de la librelia JSoup
* #param url
* #return Documento con el HTML
*/
public static Document getHtmlDocument(String url) {
Document doc = null;
try {
doc = Jsoup.connect(url).userAgent("Mozilla/5.0").timeout(100000).get();
} catch (IOException ex) {
System.out.println("Excepción al obtener el HTML de la página" + ex.getMessage());
}
return doc;
}
Should I use another method or increase the time out limit? The problem is that the program execution spends more or less 10 hours, and sometimes the problem happens in the URL number 500 another time in the 250...this is nonsense for me...if there is a problem in the link number 250, why if I run another time the program the problem happens in the link number 450 (for example)? I have been thinking that it could be internet problems but it's not.
The solution for another case is not solving my problem: Java JSoup error fetching URL
Thanks in advice.

PRNG with seed in an interval

So my problem is the following : I'm trying to implement in Java a way to encrypt a message M (like from 1 character to let's say 1000) with a password P, chosen by the user (let's say "4z327yU10p"). I then want to hide the message in an image using a Pseudo Random Number Generator (PRNG) to choose the pixels. My seed is the password.
Here's my approach :
sha3 on the password to get a 256b output to use as key
use AES with the previously generated key to get an encrypted message
use the output as a seed for my PRNG
For (1): is this possible for a short password?
For (2): can AES be used for small messages?
For (3): how can I have random number in the interval of my image ? (0,...,480000) because my algorithm gives me an int?
here's the code :
public void initSeed(String password){ //pour initier la seed avec le password
Message message = new Message();
message.initMessageASCII(password);
List <Integer> temp = message.getMsg();
byte[] vect = new byte[temp.size()];
for (int i=0; i< temp.size(); i++){
vect[i] = temp.get(i).byteValue();
}
this.seed = vect;
}
public void init() { //pour initier le remplissage du vecteur randList
SecureRandom random;
try {
random = SecureRandom.getInstance("SHA1PRNG"); //SHA1PRNG est un algorithme très efficace
random.setSeed(seed);
random.nextBytes(randList); //fonction pour créer les bytes aléatoires et les écrire dans "bytes"
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
I'll answer the separate questions (ask separate questions):
Yes, SHA-3 can be used for arbitrarily sized messages.
Yes, AES can be used for arbitrarily sized messages.
Random.nextInt(int).
You can see this as a consultants curse though, I gave you what you asked for instead of what you need. For instance, you don't need the (not yet standardized) SHA-3 but you should use a PBKDF instead.

Categories