All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.testable.selenium.TestableCSVReader Maven / Gradle / Ivy

package io.testable.selenium;

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;
import org.apache.http.client.ClientProtocolException;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * Operations to read from a CSV file while running a test on the Testable platform. When run locally it simply
 * tries to load the file from your local classpath/working directory. It is assumed your CSV file has a header row
 * with column names in the first row.
 */
public class TestableCSVReader {

    private static final int GLOBAL_CLIENT_INDEX = Integer.getInteger("TESTABLE_GLOBAL_CLIENT_INDEX", 0);
    private static final int ITERATION = Integer.getInteger("TESTABLE_ITERATION", 0);
    private static final int CONCURRENT_CLIENTS = Integer.getInteger("TESTABLE_CONCURRENT_CLIENTS", 1);

    private List records;
    private int index = CONCURRENT_CLIENTS * ITERATION + GLOBAL_CLIENT_INDEX;

    public TestableCSVReader(String path) throws IOException {
        InputStream fileIs = this.getClass().getClassLoader().getResourceAsStream(path);
        CSVParser parser = CSVParser.parse(fileIs, StandardCharsets.UTF_8, CSVFormat.DEFAULT.withFirstRecordAsHeader());
        this.records = parser.getRecords();
    }

    /**
     * Get a row from the file by index (zero based).
     *
     * @param index The row index to load. The first row in the file after the header row is row 0.
     * @return A row record
     */
    public CSVRecord get(int index) {
        return this.records.get(index % this.records.size());
    }

    /**
     * Get a row from the file by index (zero based).
     *
     * @param index The row index to load. The first row in the file after the header row is row 0.
     * @param wrap If true once the last row is reached loop back to the first row. If false a
     *        {@link ClientProtocolException} is thrown when the end of the file is reached.
     * @return A row record
     */
    public CSVRecord get(int index, boolean wrap) throws IOException {
        if (!wrap && index >= this.records.size())
            throw new ClientProtocolException("End of CSV reached");
        return this.records.get(index % this.records.size());
    }

    /**
     * Get a random row from the file.
     *
     * @return A random row record
     */
    public CSVRecord random() {
        int index = (int)Math.floor(Math.random() * records.size());
        return get(index);
    }

    /**
     * Gets the next row in the CSV file. When run on Testable this functions as a global iterator across all regions
     * and test runners. This ensures that the rows in the file are evenly distributed across your virtual users.
     * When the last row is reached the next call globally will return the first row in the file.
     *
     * @return The next row record
     * @throws IOException
     */
    public CSVRecord next() throws IOException {
        return next(true);
    }

    /**
     * Gets the next row in the CSV file. When run on Testable this functions as a global iterator across all regions
     * and test runners. This ensures that the rows in the file are evenly distributed across your virtual users.
     *
     * @param wrap If true once the last row is reached loop back to the first row. If false a
     * {@link ClientProtocolException} is thrown when the end of the file is reached.
     * @return The next row record
     * @throws IOException
     */
    public CSVRecord next(boolean wrap) throws IOException {
        return next(1, wrap).get(0);
    }

    /**
     * Gets the next 1 or more rows from the CSV file. When run on Testable this functions as a global iterator across
     * all regions and test runners. This ensures that the rows in the file are evenly distributed across your
     * virtual users. When the last row is reached the next call globally will return the first row in the file.
     *
     * @param rows Number of rows to return
     * @return A list of the records
     * @throws IOException
     */
    public List next(int rows) throws IOException {
        return next(rows, true);
    }

    /**
     * Gets the next 1 or more rows from the CSV file. When run on Testable this functions as a global iterator across
     * all regions and test runners. This ensures that the rows in the file are evenly distributed across your
     * virtual users.
     *
     * @param rows Number of rows to return
     * @param wrap If true once the last row is reached loop back to the first row. If false a
     * {@link ClientProtocolException} is thrown when the end of the file is reached.
     * @return
     * @throws IOException
     */
    public List next(int rows, boolean wrap) throws IOException {
        List records = new ArrayList<>(rows);
        for(int i = 0; i < rows; i++) {
            records.add(get(index++, wrap));
        }
        return records;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy