Let's say you have 50 objects (15Mb each) stored in Google Cloud Storage. Now, you need to create a zip archive containing all of them and store the resultant file back into GCS. How can we achieve that from within an Appengine java application?Well, after some research, I wrote the method below using Google Cloud Storage Client Library which does exactly that. Just don't forget to grant the appropriate permissions to your appengine service account so that it can read and write the objects.public static void zipFiles(final GcsFilename targetZipFile, final GcsFilename... filesToZip) throws IOException { Preconditions.checkArgument(targetZipFile != null); Preconditions.checkArgument(filesToZip != null); Preconditions.checkArgument(filesToZip.length > 0); final int fetchSize = 4 * 1024 * 1024; final int readSize = 2 * 1024 * 1024; GcsOutputChannel outputChannel = null; ZipOutputStream zip = null; try { final GcsFileOptions options = new GcsFileOptions.Builder() .mimeType(MediaType.ZIP.toString()).build(); outputChannel = GCS_SERVICE.createOrReplace(targetZipFile, options); zip = new ZipOutputStream(Channels.newOutputStream(outputChannel)); GcsInputChannel readChannel = null; for (final GcsFilename file : filesToZip) { try { final GcsFileMetadata meta = GCS_SERVICE.getMetadata(file); if (meta == null) { LOGGER.warning(file.toString() + " NOT FOUND. Skipping."); continue; } final ZipEntry entry = new ZipEntry(file.getObjectName()); zip.putNextEntry(entry); readChannel = GCS_SERVICE.openPrefetchingReadChannel(file, 0, fetchSize); final ByteBuffer buffer = ByteBuffer.allocate(readSize); int bytesRead = 0; while (bytesRead >= 0) { bytesRead = readChannel.read(buffer); buffer.flip(); zip.write(buffer.array(), buffer.position(), buffer.limit()); buffer.rewind(); buffer.limit(buffer.capacity()); } } finally { zip.closeEntry(); readChannel.close(); } } } finally { zip.flush(); zip.close(); outputChannel.close(); }} I've tested some web applications whose unexpected errors or exceptions were handled by the application code and encoded in the response body as JSON.A hypothetical response is shown below:{ data: null, message: "TimeoutException: Transaction rolled back after 3000 seconds.", success: false}The problem with this approach is that most of the times the HTTP response code is 200 (OK) which jmeter interprets as a successful sample.I'm not a big fan of this solution I'd rather have it returning 4XX or 5XX response codes, in which case jmeter would fail the sample.In order to workaround this, I normally use a BSF Assertion containing javascript code similar to:try { eval('var response = ' + prev.getResponseDataAsString()); if (!response.success) { prev.setSuccessful(false); prev.setResponseMessage(response.message); }} catch(e) { prev.setSuccessful(false); prev.setResponseMessage("Invalid response. Expected a valid JSON.");}First I try to evaluate the response string into a valid javascript object. If that succeeds I check the success flag and handle it properly, otherwise, in the catch block, I force the sample to fail due to a bad response format.Note that in both failure scenarios I invoke the setSuccessful and the setResponseMessage methods to signal a sample failure and have better detailed error messages respectively.And that's it!Happy load testing! Bitbucket repositories allow us to setup hooks which notify/trigger Jenkins' jobs about newly pushed code. The process to create such a hook is documented here.However, it doesn't mention how to integrate with Jenkins parameterized jobs.After reading the Jenkins documentation and a few trial and error I managed integrate Bitbucket and Jenkins parameterized jobs.The hook management form presents 4 fields:Endpoint: Here, youll need to set your Jenkins URL in the following format http://username:apitoken@your.jenkins.url/job/your.job.name/buildWithParameters Module name: (Optional)Project name: (Leave Empty)Token: Its the authentication token you defined in your Jenkins