Search code examples
performancetestingjmeterperformance-testingethereum

How to sumbit a form to blockchain using jmeter?


I have developed a web application using React on top of Ethereum blockchain.

One of the pages in my application gets information from user like this:

class AssetNew extends Component {
 state = {
  name: "",
  description: "",
  manufacturer: "",
  price: "",
  errorMessage: ""
 };

 onSubmit = async event => {
  event.preventDefault();

  const { name, description, manufacturer, price} = this.state;
  this.setState({errorMessage: "" });

  try {
    const accounts = await web3.eth.getAccounts();
    await tracker.methods
      .createAsset(name, description, manufacturer, price)
      .send({
       from: accounts[0],
       value: web3.utils.toWei(this.state.price, "ether"),
       gas: "1000000"
     });
 } catch (err) {
   this.setState({ errorMessage: err.message });
 }
};

render() {
return (
     <Form onSubmit={this.onSubmit} error={!!this.state.errorMessage}>
       <Form.Field>
         <label>Name</label>
         <Input
           value={this.state.name}
           onChange={event => this.setState({ name: event.target.value })}
        />
       </Form.Field>
       .... // three more from.field for description, manufacturer and price
 );
 }
}
export default AssetNew;

This page gets name, description, manufacturer, and price and sends it to the smart contract to register a new product. Everything works fine with the browser (I can create a new product with the form). However, I am not able to create a new product with Jmeter. I tried to send parameters with POST Method:

enter image description here

After running the test Http requests are successful but nothing happens (I expect Jmeter to create a new product).

Should I expect Jmeter to create a new product by passing parameters? Do I check the performance correctly?

Smart contract to create a new product:

contract AssetTracker {
  uint public id;
  uint nonce;
  struct Asset {
    string name;
    string description;
    string manufacture;
    uint price;
    uint id;
    address owner;
    bool initialized;
 }
 Asset[] public assets;

 function createAsset(string name, string description, string manufacture, uint price) public payable{

    id = uint(keccak256(now, msg.sender, nonce)) % 1000;
    nonce++;
    Asset memory newAsset = Asset(name, description, manufacture, price, id, msg.sender, true);
    assets.push(newAsset);
}

Solution

  • If you're able to send the request using the browser, you should be able to use JMeter's HTTP(S) Test Script Recorder in order to capture the relevant HTTP POST Request and generate HTTP Request sampler

    1. Prepare JMeter for recording. The fastest way is using JMeter Templates feature

      • From JMeter's main menu choose File - Templates - Recording and click "Create"
      • Expand HTTP(S) Test Script Recorder and click "Start"

        enter image description here

    2. Prepare your browser for recording. Configure it to use JMeter as the proxy

      • localhost or 127.0.0.1 as the proxy host
      • 8888 as the proxy port
      • make sure that the proxy is set to all protocols and there are no exceptions
      • If you plan to record HTTPS traffic - import ApacheJMeterTemporaryRootCA.crt certificate into your browser, the certificate is generated in "bin" folder of your JMeter installation when you start the HTTP(S) Test Script Recorder

      enter image description here

    3. Execute the request in browser

    4. JMeter should capture the request and store the HTTP Request sampler under Thread Group - Recording Controller.

    More information: Apache JMeter HTTP(S) Test Script Recorder

    Alternatively you can use JMeter Chrome Extension for creating the test plan, in this case you will not have to worry about proxies and certificates.