alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

JMeter example source code file (PostWriterTest.java)

This example JMeter source code file (PostWriterTest.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - JMeter tags/keywords

bytearrayoutputstream, c3, io, ioexception, ioexception, iso-8859-1, iso-8859-1, net, network, override, string, string, test_file_content, todo, us-ascii, us-ascii, utf_8, util

The JMeter PostWriterTest.java source code

/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

package org.apache.jmeter.protocol.http.sampler;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import junit.framework.TestCase;

import org.apache.jmeter.config.Arguments;
import org.apache.jmeter.protocol.http.util.HTTPArgument;
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
import org.apache.jorphan.logging.LoggingManager;
import org.apache.log.Logger;

public class PostWriterTest extends TestCase {

    private static final Logger log = LoggingManager.getLoggerForClass();

    private static final String UTF_8 = "UTF-8";
    private final static String HTTP_ENCODING = "ISO-8859-1";
    private final static byte[] CRLF = { 0x0d, 0x0A };
    private static byte[] TEST_FILE_CONTENT;
    
    private StubURLConnection connection;
    private HTTPSampler sampler;
    private File temporaryFile;
    
    private PostWriter postWriter;
    @Override
    protected void setUp() throws Exception {
        establishConnection();
        sampler = new HTTPSampler();// This must be the original (Java) HTTP sampler
        postWriter=new PostWriter();
        
        // Create the test file content
        TEST_FILE_CONTENT = "foo content &?=01234+56789-\u007c\u2aa1\u266a\u0153\u20a1\u0115\u0364\u00c5\u2052".getBytes(UTF_8);

        // create a temporary file to make sure we always have a file to give to the PostWriter 
        // Whereever we are or Whatever the current path is.
        temporaryFile = File.createTempFile("foo", "txt");
        OutputStream output = new FileOutputStream(temporaryFile);
        output.write(TEST_FILE_CONTENT);
        output.flush();
        output.close();
    }

    @Override
    protected void tearDown() throws Exception {
        // delete temporay file
        temporaryFile.delete();
    }

    /*
     * Test method for 'org.apache.jmeter.protocol.http.sampler.postWriter.sendPostData(URLConnection, HTTPSampler)'
     * This method test sending a request which contains both formdata and file content
     */
    public void testSendPostData() throws IOException {
        sampler.setMethod(HTTPSamplerBase.POST);
        setupFilepart(sampler);
        String titleValue = "mytitle";
        String descriptionValue = "mydescription";
        setupFormData(sampler, titleValue, descriptionValue);
        
        // Test sending data with default encoding
        String contentEncoding = "";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        byte[] expectedFormBody = createExpectedOutput(PostWriter.BOUNDARY, null, titleValue, descriptionValue, TEST_FILE_CONTENT);
        checkContentLength(connection, expectedFormBody.length);        
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();

        // Test sending data as ISO-8859-1
        establishConnection();
        contentEncoding = "ISO-8859-1";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        expectedFormBody = createExpectedOutput(PostWriter.BOUNDARY, contentEncoding, titleValue, descriptionValue, TEST_FILE_CONTENT);
        checkContentLength(connection, expectedFormBody.length);        
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();
        
        // Test sending data as UTF-8
        establishConnection();
        titleValue = "mytitle\u0153\u20a1\u0115\u00c5";
        descriptionValue = "mydescription\u0153\u20a1\u0115\u00c5";
        contentEncoding = UTF_8;
        sampler.setContentEncoding(contentEncoding);        
        setupFormData(sampler, titleValue, descriptionValue);
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        expectedFormBody = createExpectedOutput(PostWriter.BOUNDARY, contentEncoding, titleValue, descriptionValue, TEST_FILE_CONTENT);
        checkContentLength(connection, expectedFormBody.length);        
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();

        // Test sending UTF-8 data with ISO-8859-1 content encoding
        establishConnection();
        contentEncoding = UTF_8;
        sampler.setContentEncoding("ISO-8859-1");
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        expectedFormBody = createExpectedOutput(PostWriter.BOUNDARY, contentEncoding, titleValue, descriptionValue, TEST_FILE_CONTENT);
        checkContentLength(connection, expectedFormBody.length);        
        checkArraysHaveDifferentContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();
    }

    /*
     * Test method for 'org.apache.jmeter.protocol.http.sampler.postWriter.sendPostData(URLConnection, HTTPSampler)'
     * This method test sending a HTTPSampler with form parameters, and only
     * the filename of a file.
     */
    public void testSendPostData_NoFilename() throws IOException {
        setupNoFilename(sampler);
        String titleValue = "mytitle";
        String descriptionValue = "mydescription";
        setupFormData(sampler, titleValue, descriptionValue);

        // Test sending data with default encoding
        String contentEncoding = "";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        byte[] expectedUrl = "title=mytitle&description=mydescription".getBytes(); // TODO - charset?
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        expectedUrl = "title=mytitle&description=mydescription".getBytes(UTF_8);
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        connection.disconnect();

        // Test sending data as ISO-8859-1
        establishConnection();
        contentEncoding = "ISO-8859-1";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        expectedUrl = "title=mytitle&description=mydescription".getBytes(contentEncoding);
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        expectedUrl = "title=mytitle&description=mydescription".getBytes(UTF_8);
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        connection.disconnect();
    }

    /*
     * Test method for 'org.apache.jmeter.protocol.http.sampler.postWriter.sendPostData(URLConnection, HTTPSampler)'
     * This method test sending file content as the only content of the post body
     */
    public void testSendPostData_FileAsBody() throws IOException {
        setupFilepart(sampler, "", temporaryFile, "");
        
        // Check using default encoding
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentLength(connection, TEST_FILE_CONTENT.length);        
        checkArraysHaveSameContent(TEST_FILE_CONTENT, connection.getOutputStreamContent());
        connection.disconnect();
        
        // Check using a different encoding
        
        String otherEncoding;
        final String fileEncoding = System.getProperty( "file.encoding");// $NON-NLS-1$
        log.info("file.encoding: "+fileEncoding);
        if (UTF_8.equalsIgnoreCase(fileEncoding) || "UTF8".equalsIgnoreCase(fileEncoding)){// $NON-NLS-1$
            otherEncoding="ISO-8859-1"; // $NON-NLS-1$
        } else {
            otherEncoding=UTF_8;
        }
        log.info("Using other encoding: "+otherEncoding);
        establishConnection();
        sampler.setContentEncoding(otherEncoding);
        // File content is sent as binary, so the content encoding should not change the file data
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentLength(connection, TEST_FILE_CONTENT.length);        
        checkArraysHaveSameContent(TEST_FILE_CONTENT, connection.getOutputStreamContent());
        // Check that other encoding is not the current encoding
        checkArraysHaveDifferentContent(new String(TEST_FILE_CONTENT) // TODO - charset?
            .getBytes(otherEncoding), connection.getOutputStreamContent());
        
        // If we have both file as body, and form data, then only form data will be sent
        setupFormData(sampler);
        establishConnection();
        sampler.setContentEncoding("");
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        byte[] expectedUrl = "title=mytitle&description=mydescription".getBytes(); // TODO - charset?
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
    }

    /*
     * Test method for 'org.apache.jmeter.protocol.http.sampler.postWriter.sendPostData(URLConnection, HTTPSampler)'
     * This method test sending only a file multipart.
     */
    public void testSendFileData_Multipart() throws IOException {
        sampler.setMethod(HTTPSamplerBase.POST);
        String fileField = "upload";
        String mimeType = "text/plain";
        File file = temporaryFile;
        byte[] fileContent = TEST_FILE_CONTENT;
        setupFilepart(sampler, fileField, file, mimeType);
        
        // Test sending data with default encoding
        String contentEncoding = "";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        byte[] expectedFormBody = createExpectedFilepartOutput(PostWriter.BOUNDARY, fileField, file, mimeType, fileContent, true, true);
        checkContentLength(connection, expectedFormBody.length);
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();

        // Test sending data as ISO-8859-1
        establishConnection();
        contentEncoding = "ISO-8859-1";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        expectedFormBody = createExpectedFilepartOutput(PostWriter.BOUNDARY, fileField, file, mimeType, fileContent, true, true);
        checkContentLength(connection, expectedFormBody.length);        
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();
        
        // Test sending data as UTF-8
        establishConnection();
        fileField = "some_file_field";
        mimeType = "image/png";
        contentEncoding = UTF_8;
        sampler.setContentEncoding(contentEncoding);        
        setupFilepart(sampler, fileField, file, mimeType);
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        expectedFormBody = createExpectedFilepartOutput(PostWriter.BOUNDARY, fileField, file, mimeType, fileContent, true, true);
        checkContentLength(connection, expectedFormBody.length);        
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();
    }

    /*
     * Test method for 'org.apache.jmeter.protocol.http.sampler.postWriter.sendPostData(URLConnection, HTTPSampler)'
     * This method test sending only a formdata, as a multipart/form-data request.
     */
    public void testSendFormData_Multipart() throws IOException {
        sampler.setMethod(HTTPSamplerBase.POST);
        String titleField = "title";
        String titleValue = "mytitle";
        String descriptionField = "description";
        String descriptionValue = "mydescription";
        setupFormData(sampler, titleValue, descriptionValue);
        // Tell sampler to do multipart, even if we have no files to upload
        sampler.setDoMultipartPost(true);

        // Test sending data with default encoding
        String contentEncoding = "";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        byte[] expectedFormBody = createExpectedFormdataOutput(PostWriter.BOUNDARY, null, titleField, titleValue, descriptionField, descriptionValue, true, true);
        checkContentLength(connection, expectedFormBody.length);
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();

        // Test sending data as ISO-8859-1
        establishConnection();
        contentEncoding = "ISO-8859-1";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        expectedFormBody = createExpectedFormdataOutput(PostWriter.BOUNDARY, contentEncoding, titleField, titleValue, descriptionField, descriptionValue, true, true);
        checkContentLength(connection, expectedFormBody.length);
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();
        
        // Test sending data as ISO-8859-1, with values that need to be urlencoded
        establishConnection();
        titleValue = "mytitle+123 456&yes";
        descriptionValue = "mydescription and some spaces";
        contentEncoding = "ISO-8859-1";
        sampler.setContentEncoding(contentEncoding);        
        setupFormData(sampler, titleValue, descriptionValue);
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        expectedFormBody = createExpectedFormdataOutput(PostWriter.BOUNDARY, contentEncoding, titleField, titleValue, descriptionField, descriptionValue, true, true);
        checkContentLength(connection, expectedFormBody.length);
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();
        
        // Test sending data as UTF-8
        establishConnection();
        titleValue = "mytitle\u0153\u20a1\u0115\u00c5";
        descriptionValue = "mydescription\u0153\u20a1\u0115\u00c5";
        contentEncoding = UTF_8;
        sampler.setContentEncoding(contentEncoding);        
        setupFormData(sampler, titleValue, descriptionValue);
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        expectedFormBody = createExpectedFormdataOutput(PostWriter.BOUNDARY, contentEncoding, titleField, titleValue, descriptionField, descriptionValue, true, true);
        checkContentLength(connection, expectedFormBody.length);
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();

        // Test sending data as UTF-8, with values that would have been urlencoded
        // if it was not sent as multipart
        establishConnection();
        titleValue = "mytitle\u0153+\u20a1 \u0115&yes\u00c5";
        descriptionValue = "mydescription \u0153 \u20a1 \u0115 \u00c5";
        contentEncoding = UTF_8;
        sampler.setContentEncoding(contentEncoding);        
        setupFormData(sampler, titleValue, descriptionValue);
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
        expectedFormBody = createExpectedFormdataOutput(PostWriter.BOUNDARY, contentEncoding, titleField, titleValue, descriptionField, descriptionValue, true, true);
        checkContentLength(connection, expectedFormBody.length);
        checkArraysHaveSameContent(expectedFormBody, connection.getOutputStreamContent());
        connection.disconnect();
    }
    
    /*
     * Test method for 'org.apache.jmeter.protocol.http.sampler.postWriter.sendPostData(URLConnection, HTTPSampler)'
     * This method test sending only a formdata, as urlencoded data
     */
    public void testSendFormData_Urlencoded() throws IOException {
        String titleValue = "mytitle";
        String descriptionValue = "mydescription";
        setupFormData(sampler, titleValue, descriptionValue);

        // Test sending data with default encoding
        String contentEncoding = "";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        byte[] expectedUrl = ("title=" + titleValue + "&description=" + descriptionValue).getBytes("US-ASCII");        
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        assertEquals(
                URLDecoder.decode(new String(expectedUrl, "US-ASCII"), "ISO-8859-1"), 
                URLDecoder.decode(new String(connection.getOutputStreamContent(), "US-ASCII"), "ISO-8859-1")); 
        connection.disconnect();

        // Test sending data as ISO-8859-1
        establishConnection();
        contentEncoding = "ISO-8859-1";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        expectedUrl = new String("title=" + titleValue + "&description=" + descriptionValue).getBytes("US-ASCII");
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        assertEquals(
                URLDecoder.decode(new String(expectedUrl, "US-ASCII"), contentEncoding), 
                URLDecoder.decode(new String(connection.getOutputStreamContent(), "US-ASCII"), contentEncoding)); 
        connection.disconnect();
        
        // Test sending data as ISO-8859-1, with values that need to be urlencoded
        establishConnection();
        titleValue = "mytitle+123 456&yes";
        descriptionValue = "mydescription and some spaces";
        contentEncoding = "ISO-8859-1";
        sampler.setContentEncoding(contentEncoding);        
        setupFormData(sampler, titleValue, descriptionValue);
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        String expectedString = "title=" + URLEncoder.encode(titleValue, contentEncoding) + "&description=" + URLEncoder.encode(descriptionValue, contentEncoding);
        expectedUrl = expectedString.getBytes(contentEncoding);
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        assertEquals(
                URLDecoder.decode(new String(expectedUrl, "US-ASCII"), contentEncoding), 
                URLDecoder.decode(new String(connection.getOutputStreamContent(), "US-ASCII"), contentEncoding)); 
        String unencodedString = "title=" + titleValue + "&description=" + descriptionValue;
        byte[] unexpectedUrl = unencodedString.getBytes(UTF_8);
        checkArraysHaveDifferentContent(unexpectedUrl, connection.getOutputStreamContent());
        connection.disconnect();
        
        // Test sending data as UTF-8
        establishConnection();
        titleValue = "mytitle\u0153\u20a1\u0115\u00c5";
        descriptionValue = "mydescription\u0153\u20a1\u0115\u00c5";
        contentEncoding = UTF_8;
        sampler.setContentEncoding(contentEncoding);        
        setupFormData(sampler, titleValue, descriptionValue);
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        expectedString = "title=" + URLEncoder.encode(titleValue, contentEncoding) + "&description=" + URLEncoder.encode(descriptionValue, contentEncoding);
        expectedUrl = expectedString.getBytes("US-ASCII");
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        assertEquals(
                URLDecoder.decode(new String(expectedUrl, "US-ASCII"), contentEncoding), 
                URLDecoder.decode(new String(connection.getOutputStreamContent(), "US-ASCII"), contentEncoding)); 
        connection.disconnect();

        // Test sending data as UTF-8, with values that needs to be urlencoded
        establishConnection();
        titleValue = "mytitle\u0153+\u20a1 \u0115&yes\u00c5";
        descriptionValue = "mydescription \u0153 \u20a1 \u0115 \u00c5";
        contentEncoding = UTF_8;
        sampler.setContentEncoding(contentEncoding);        
        setupFormData(sampler, titleValue, descriptionValue);
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);

        checkContentTypeUrlEncoded(connection);
        expectedString = "title=" + URLEncoder.encode(titleValue, UTF_8) + "&description=" + URLEncoder.encode(descriptionValue, UTF_8);
        expectedUrl = expectedString.getBytes("US-ASCII");
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        assertEquals(
                URLDecoder.decode(new String(expectedUrl, "US-ASCII"), contentEncoding), 
                URLDecoder.decode(new String(connection.getOutputStreamContent(), "US-ASCII"), contentEncoding)); 
        unencodedString = "title=" + titleValue + "&description=" + descriptionValue;
        unexpectedUrl = unencodedString.getBytes("US-ASCII");
        checkArraysHaveDifferentContent(unexpectedUrl, connection.getOutputStreamContent());
        connection.disconnect();
        
        // Test sending parameters which are urlencoded beforehand
        // The values must be URL encoded with UTF-8 encoding, because that
        // is what the HTTPArgument assumes
        // %C3%85 in UTF-8 is the same as %C5 in ISO-8859-1, which is the same as Å
        titleValue = "mytitle%20and%20space%2Ftest%C3%85";
        descriptionValue = "mydescription+and+plus+as+space%2Ftest%C3%85";
        setupFormData(sampler, true, titleValue, descriptionValue);

        // Test sending data with default encoding
        establishConnection();
        contentEncoding = "";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        expectedUrl = new String("title=" + titleValue.replaceAll("%20", "+").replaceAll("%C3%85", "%C5") + "&description=" + descriptionValue.replaceAll("%C3%85", "%C5")).getBytes("US-ASCII");
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        assertEquals(
                URLDecoder.decode(new String(expectedUrl, "US-ASCII"), "ISO-8859-1"), // HTTPSampler uses ISO-8859-1 as default encoding
                URLDecoder.decode(new String(connection.getOutputStreamContent(), "US-ASCII"), "ISO-8859-1")); // HTTPSampler uses ISO-8859-1 as default encoding
        connection.disconnect();

        // Test sending data as ISO-8859-1
        establishConnection();
        contentEncoding = "ISO-8859-1";
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        expectedUrl = new String("title=" + titleValue.replaceAll("%20", "+").replaceAll("%C3%85", "%C5") + "&description=" + descriptionValue.replaceAll("%C3%85", "%C5")).getBytes("US-ASCII");
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        assertEquals(
                URLDecoder.decode(new String(expectedUrl, "US-ASCII"), contentEncoding), 
                URLDecoder.decode(new String(connection.getOutputStreamContent(), "US-ASCII"), contentEncoding)); 
        connection.disconnect();

        // Test sending data as UTF-8
        establishConnection();
        contentEncoding = UTF_8;
        sampler.setContentEncoding(contentEncoding);        
        postWriter.setHeaders(connection, sampler);
        postWriter.sendPostData(connection, sampler);
        
        checkContentTypeUrlEncoded(connection);
        expectedUrl = new String("title=" + titleValue.replaceAll("%20", "+") + "&description=" + descriptionValue).getBytes("US-ASCII");
        checkContentLength(connection, expectedUrl.length);
        checkArraysHaveSameContent(expectedUrl, connection.getOutputStreamContent());
        assertEquals(
                URLDecoder.decode(new String(expectedUrl, "US-ASCII"), contentEncoding), 
                URLDecoder.decode(new String(connection.getOutputStreamContent(), "US-ASCII"), contentEncoding)); 
        connection.disconnect();
    }

    /*
     * Test method for 'org.apache.jmeter.protocol.http.sampler.postWriter.setHeaders(URLConnection, HTTPSampler)'
     */
    public void testSetHeaders() throws IOException {
        sampler.setMethod(HTTPSamplerBase.POST);
        setupFilepart(sampler);
        setupFormData(sampler);
        
        postWriter.setHeaders(connection, sampler);
        checkContentTypeMultipart(connection, PostWriter.BOUNDARY);
    }

    /*
     * Test method for 'org.apache.jmeter.protocol.http.sampler.postWriter.setHeaders(URLConnection, HTTPSampler)'
     */
    public void testSetHeaders_NoFilename() throws IOException {
        setupNoFilename(sampler);
        setupFormData(sampler);
        
        postWriter.setHeaders(connection, sampler);
        checkContentTypeUrlEncoded(connection);
        checkContentLength(connection, "title=mytitle&description=mydescription".length());
    }

    /**
     * setup commons parts of HTTPSampler with a no filename.
     *  
     * @param httpSampler
     * @throws IOException
     */
    private void setupNoFilename(HTTPSampler httpSampler) {
        setupFilepart(sampler, "upload", null, "application/octet-stream");
    }

    /**
     * Setup the filepart with default values
     * 
     * @param httpSampler
     */
    private void setupFilepart(HTTPSampler httpSampler) {
        setupFilepart(sampler, "upload", temporaryFile, "text/plain");
    }

    /**
     * Setup the filepart with specified values
     * 
     * @param httpSampler
     */
    private void setupFilepart(HTTPSampler httpSampler, String fileField, File file, String mimeType) {
        HTTPFileArg[] hfa = {new HTTPFileArg(file == null ? "" : file.getAbsolutePath(), fileField, mimeType)};
        httpSampler.setHTTPFiles(hfa);
    }

    /**
     * Setup the form data with default values
     * 
     * @param httpSampler
     */
    private void setupFormData(HTTPSampler httpSampler) {
        setupFormData(httpSampler, "mytitle", "mydescription");
    }

    /**
     * Setup the form data with specified values
     * 
     * @param httpSampler
     */
    private void setupFormData(HTTPSampler httpSampler, String titleValue, String descriptionValue) {
        setupFormData(sampler, false, titleValue, descriptionValue);
    }

    /**
     * Setup the form data with specified values
     * 
     * @param httpSampler
     */
    private void setupFormData(HTTPSampler httpSampler, boolean isEncoded, String titleValue, String descriptionValue) {
        Arguments args = new Arguments();
        HTTPArgument argument1 = new HTTPArgument("title", titleValue, isEncoded);
        HTTPArgument argument2 = new HTTPArgument("description", descriptionValue, isEncoded);
        args.addArgument(argument1);
        args.addArgument(argument2);
        httpSampler.setArguments(args);
    }

    private void establishConnection() throws MalformedURLException { 
        connection = new StubURLConnection("http://fake_url/test");
    }
    
    /**
     * Create the expected output post body for form data and file multiparts
     * with default values for field names
     */
    private byte[] createExpectedOutput(
            String boundaryString,
            String contentEncoding,
            String titleValue,
            String descriptionValue,
            byte[] fileContent) throws IOException {
        return createExpectedOutput(boundaryString, contentEncoding, "title", titleValue, "description", descriptionValue, "upload", fileContent);
    }

    /**
     * Create the expected output post body for form data and file multiparts
     * with specified values
     */
    private byte[] createExpectedOutput(
            String boundaryString,
            String contentEncoding,
            String titleField,
            String titleValue,
            String descriptionField,
            String descriptionValue,
            String fileField,
            byte[] fileContent) throws IOException {
        // Create the multiparts
        byte[] formdataMultipart = createExpectedFormdataOutput(boundaryString, contentEncoding, titleField, titleValue, descriptionField, descriptionValue, true, false);
        byte[] fileMultipart = createExpectedFilepartOutput(boundaryString, fileField, temporaryFile, "text/plain", fileContent, false, true);
        
        // Join the two multiparts
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        output.write(formdataMultipart);
        output.write(fileMultipart);
        
        output.flush();
        output.close();
        
        return output.toByteArray();
    }

    /**
     * Create the expected output multipart/form-data, with only form data,
     * and no file multipart
     * 
     * @param lastMultipart true if this is the last multipart in the request
     */
    private byte[] createExpectedFormdataOutput(
            String boundaryString,
            String contentEncoding,
            String titleField,
            String titleValue,
            String descriptionField,
            String descriptionValue,
            boolean firstMultipart,
            boolean lastMultipart) throws IOException {
        final byte[] DASH_DASH = "--".getBytes(HTTP_ENCODING);
        // All form parameter always have text/plain as mime type
        final String mimeType="text/plain";//TODO make this a parameter?
        
        final ByteArrayOutputStream output = new ByteArrayOutputStream();
        if(firstMultipart) {
            output.write(DASH_DASH);
            output.write(boundaryString.getBytes(HTTP_ENCODING));
            output.write(CRLF);
        }
        output.write("Content-Disposition: form-data; name=\"".getBytes(HTTP_ENCODING));
        output.write(titleField.getBytes(HTTP_ENCODING));
        output.write("\"".getBytes(HTTP_ENCODING));
        output.write(CRLF);
        output.write("Content-Type: ".getBytes(HTTP_ENCODING));
        output.write(mimeType.getBytes(HTTP_ENCODING));
        output.write("; charset=".getBytes(HTTP_ENCODING));
        output.write((contentEncoding==null ? PostWriter.ENCODING : contentEncoding).getBytes(HTTP_ENCODING));
        output.write(CRLF);
        output.write("Content-Transfer-Encoding: 8bit".getBytes(HTTP_ENCODING));
        output.write(CRLF);
        output.write(CRLF);
        if(contentEncoding != null) {
            output.write(titleValue.getBytes(contentEncoding));
        }
        else {
            output.write(titleValue.getBytes()); // TODO - charset?
        }
        output.write(CRLF);
        output.write(DASH_DASH);
        output.write(boundaryString.getBytes(HTTP_ENCODING));
        output.write(CRLF);
        output.write("Content-Disposition: form-data; name=\"".getBytes(HTTP_ENCODING));
        output.write(descriptionField.getBytes(HTTP_ENCODING));
        output.write("\"".getBytes(HTTP_ENCODING));
        output.write(CRLF);
        output.write("Content-Type: ".getBytes(HTTP_ENCODING));
        output.write(mimeType.getBytes(HTTP_ENCODING));
        output.write("; charset=".getBytes(HTTP_ENCODING));
        output.write((contentEncoding==null ? PostWriter.ENCODING : contentEncoding).getBytes(HTTP_ENCODING));
        output.write(CRLF);
        output.write("Content-Transfer-Encoding: 8bit".getBytes(HTTP_ENCODING));
        output.write(CRLF);
        output.write(CRLF);
        if(contentEncoding != null) {
            output.write(descriptionValue.getBytes(contentEncoding));
        }
        else {
            output.write(descriptionValue.getBytes()); // TODO - charset?
        }
        output.write(CRLF);
        output.write(DASH_DASH);
        output.write(boundaryString.getBytes(HTTP_ENCODING));
        if(lastMultipart) {
            output.write(DASH_DASH);
        }
        output.write(CRLF);
                
        output.flush();
        output.close();

        return output.toByteArray();
    }
    
    /**
     * Create the expected file multipart
     * 
     * @param lastMultipart true if this is the last multipart in the request
     */
    private byte[] createExpectedFilepartOutput(
            String boundaryString,
            String fileField,
            File file,
            String mimeType,
            byte[] fileContent,
            boolean firstMultipart,
            boolean lastMultipart) throws IOException {
        // The encoding used for http headers and control information
        final String httpEncoding = "ISO-8859-1";
        final byte[] DASH_DASH = "--".getBytes(httpEncoding);
        
        final ByteArrayOutputStream output = new ByteArrayOutputStream();
        if(firstMultipart) {
            output.write(DASH_DASH);
            output.write(boundaryString.getBytes(httpEncoding));
            output.write(CRLF);
        }
        // replace all backslash with double backslash
        String filename = file.getName();
        output.write("Content-Disposition: form-data; name=\"".getBytes(httpEncoding));
        output.write(fileField.getBytes(httpEncoding));
        output.write(("\"; filename=\"" + filename + "\"").getBytes(httpEncoding));
        output.write(CRLF);
        output.write("Content-Type: ".getBytes(httpEncoding));
        output.write(mimeType.getBytes(httpEncoding));
        output.write(CRLF);
        output.write("Content-Transfer-Encoding: binary".getBytes(httpEncoding));
        output.write(CRLF);
        output.write(CRLF);
        output.write(fileContent);
        output.write(CRLF);
        output.write(DASH_DASH);
        output.write(boundaryString.getBytes(httpEncoding));
        if(lastMultipart) {
            output.write(DASH_DASH);
        }
        output.write(CRLF);
        
        output.flush();
        output.close();

        return output.toByteArray();
    }

    /**
     * Check that the the two byte arrays have identical content
     * 
     * @param expected
     * @param actual
     * @throws UnsupportedEncodingException 
     */
    private void checkArraysHaveSameContent(byte[] expected, byte[] actual) throws UnsupportedEncodingException {
        if(expected != null && actual != null) {
            if(expected.length != actual.length) {
                System.out.println(new String(expected,UTF_8));
                System.out.println("--------------------");
                System.out.println(new String(actual,UTF_8));
                System.out.println("====================");
                fail("arrays have different length, expected is " + expected.length + ", actual is " + actual.length);
            }
            else {
                for(int i = 0; i < expected.length; i++) {
                    if(expected[i] != actual[i]) {
                        System.out.println(new String(expected,0,i+1));
                        System.out.println("--------------------");
                        System.out.println(new String(actual,0,i+1));
                        System.out.println("====================");
                        fail("byte at position " + i + " is different, expected is " + expected[i] + ", actual is " + actual[i]);
                    }
                }
            }
        }
        else {
            fail("expected or actual byte arrays were null");
        }
    }

    /**
     * Check that the the two byte arrays different content
     * 
     * @param expected
     * @param actual
     */
    private void checkArraysHaveDifferentContent(byte[] expected, byte[] actual) {
        if(expected != null && actual != null) {
            if(expected.length == actual.length) {
                boolean allSame = true;
                for(int i = 0; i < expected.length; i++) {
                    if(expected[i] != actual[i]) {
                        allSame = false;
                        break;
                    }
                }
                if(allSame) {
                    fail("all bytes were equal");
                }
            }
        }
        else {
            fail("expected or actual byte arrays were null");
        }
    }
    
    private void checkContentTypeMultipart(HttpURLConnection conn, String boundaryString) {
        assertEquals("multipart/form-data; boundary=" + boundaryString, conn.getRequestProperty("Content-Type"));
    }

    private void checkContentTypeUrlEncoded(HttpURLConnection conn) {
        assertEquals(HTTPSamplerBase.APPLICATION_X_WWW_FORM_URLENCODED, conn.getRequestProperty("Content-Type"));
    }

    private void checkContentLength(HttpURLConnection conn, int length) {
        assertEquals(Integer.toString(length), conn.getRequestProperty("Content-Length"));
    }

    /**
     * Mock an HttpURLConnection.
     * extends HttpURLConnection instead of just URLConnection because there is a cast in PostWriter.
     */
    private static class StubURLConnection extends HttpURLConnection {
        private ByteArrayOutputStream output = new ByteArrayOutputStream();
        private Map<String, String> properties = new HashMap();
        
        public StubURLConnection(String url) throws MalformedURLException {
            super(new URL(url));
        }

        @Override
        public void connect() throws IOException {
        }
        
        @Override
        public OutputStream getOutputStream() throws IOException {
            return output;
        }

        @Override
        public void disconnect() {
        }

        @Override
        public boolean usingProxy() {
            return false;
        }

        @Override
        public String getRequestProperty(String key) {
            return properties.get(key);
        }

        @Override
        public void setRequestProperty(String key, String value) {
            properties.put(key, value);
        }
        
        public byte[] getOutputStreamContent() {
            return output.toByteArray();
        }
    }
}

Other JMeter examples (source code examples)

Here is a short list of links related to this JMeter PostWriterTest.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.