API Testing

A sample application (backend+db) exposing a REST API is started automatically. The test exercises the REST API. Logs & metrics for app & db are collected automatically.



docker run --rm -v ~/.elastest:/data -v /var/run/docker.sock:/var/run/docker.sock elastest/platform start

Recommended system specifications

ElasTest needs some minimum system specifications in order to run smoothly:

Processor 1GHz or faster
RAM 16GB
SWAP 4GB (if RAM < 16GB)
Hard Disk 30GB



Test
@DisplayName("Tests for Fullteaching login")
public class UserRestTest {

    protected static String APP_URL;
    **`protected static String ET_SUT_HOST;**`
    protected static int ET_SUT_PORT = 5000;
    private HttpApiClient httpApiClient;

    // urls
    static String new_user_uri = "/api-users/new";
    static String change_password_uri = "/api-users/changePassword";
    static String login_uri = "/api-logIn";
    // userStrings
    static String ok_parameters = "[\"unique@gmail.com\", \"Mock66666\", \"fakeUser\", \"IGNORE\"]";
    static String ok_parameters_2 = "[\"unique2@gmail.com\", \"Mock66666\", \"fakeUser\", \"IGNORE\"]";
    // passParameters
    static String pass_parameters = "[\"Mock66666\", \"Mock77777\"]";
    static String revert_pass_parameters = "[\"Mock77777\", \"Mock66666\"]";

    @BeforeAll
    public static void setUp() {
        if (System.getenv("ET_SUT_HOST") != null) {
            ET_SUT_HOST = System.getenv("ET_SUT_HOST");
        } else {
            ET_SUT_HOST = System.getProperty("sut.host");
            if (ET_SUT_HOST == null) {
                ET_SUT_HOST = "localhost";
            }
        }

        if (System.getenv("ET_SUT_PORT") != null) {
            if (!System.getenv("ET_SUT_PORT").isEmpty()) {
                ET_SUT_PORT = Integer.parseInt(System.getenv("ET_SUT_PORT"));
            } else {
                ET_SUT_PORT = 0;
            }
        }
    }

    @Test
    public void testCreateUserOk() {
        try {
            // Create the user if it doesn't exist
            int status = createUser(ok_parameters);

            int expected = HttpStatus.CREATED.value();

            assertEquals(expected, status,
                    "failure - expected HTTP status " + expected);
        } catch (IOException | KeyManagementException | NoSuchAlgorithmException
                | KeyStoreException e) {
            e.printStackTrace();
            fail("EXCEPTION: " + e.getMessage());
        }
    }

    @Test
    public void testChangeUserPassword() {
        try {
            // Create the user if it doesn't exist
            createUser(ok_parameters_2);

            // Change the user's password
            httpApiClient = new HttpApiClient(null, ET_SUT_HOST, ET_SUT_PORT,
                    change_password_uri, "unique2@gmail.com", "Mock66666");

            int status_pass = httpApiClient.sendRequest(pass_parameters, "put");
            assertTrue(status_pass == HttpStatus.OK.value(),
                    "failure login - expected HTTP status "
                            + HttpStatus.OK.value() + " but was: "
                            + status_pass);

            // Revert the change of user password
            httpApiClient = new HttpApiClient(null, ET_SUT_HOST, ET_SUT_PORT,
                    change_password_uri, "unique2@gmail.com", "Mock77777");

            httpApiClient.sendRequest(revert_pass_parameters, "put");

        } catch (IOException | KeyManagementException | NoSuchAlgorithmException
                | KeyStoreException e) {
            e.printStackTrace();
            fail("EXCEPTION: " + e.getMessage());
        }
    }

    private int createUser(String parameters) throws KeyManagementException,
            NoSuchAlgorithmException, KeyStoreException, IOException {
        httpApiClient = new HttpApiClient(null, ET_SUT_HOST, ET_SUT_PORT,
                new_user_uri, null, null);

        return httpApiClient.sendRequest(parameters, "post");
    }

}
  • ET_SUT_HOST, ET_SUT_PORT variables will be the IP and port of our SuT respectively. (Know more about Environment Variables)
Jenkins
node{
    def sutIp
    elastest(surefireReportsPattern: '**/target/surefire-reports/TEST-*.xml', monitoring: true, project: 'Jenkins Examples') {
        stage("Setting environment") {
            echo 'Environment variables'
            sh "env"
            git "https://github.com/elastest/full-teaching-experiment.git"
        }
        try {
            stage("Start Sut") {
                sh "cd docker-compose/full-teaching-et-network; export BUG_TAG=demo; docker-compose --no-ansi -p ${env.ET_SUT_CONTAINER_NAME} up -d"
                sutContainerName = env.ET_SUT_CONTAINER_NAME + "_full-teaching_1";
                sutNetwork = getFirstNetwork(sutContainerName)
                sutIp = containerIp(sutContainerName,network)

                echo 'Sut ip: '+ sutIp
                sh 'docker run -e IP=' + sutIp + ' -e PORT=5001 --network=' + sutNetwork + ' elastest/etm-check-service-up'
            }
            stage("Run Tests") {
                echo 'Running test'
                mvnHome = tool 'M3.3.9'
                sh "export ET_SUT_PORT=5001; '${mvnHome}/bin/mvn' -Dtest=UserRestTest -Dsut.host=" + sutIp +" -B -DforkCount=0 test"
                step([$class: 'JUnitResultArchiver', testResults: '**/target/surefire-reports/TEST-*.xml'])
            }
        } finally {
                echo 'Stopping SUT'
                sh "cd docker-compose/full-teaching-env; docker-compose --no-ansi -p ${env.ET_SUT_CONTAINER_NAME} down"
        }
    }
}

def getFirstNetwork(containerName) {
    echo "Inside getFirstNetwork function"
    network = sh (
        script: "docker inspect " + containerName + " -f \"{{json .NetworkSettings.Networks}}\" | awk \"{sub(/:.*/,\\\"\\\")}1\" | awk \"{sub(/\\\"/,\\\"\\\")}1\" | awk \"{sub(/\\\"/,\\\"\\\")}1\" | awk \"{sub(/{/,\\\"\\\")}1\"",
        returnStdout: true
    ).trim()

    echo containerName+" Network = " + network;
    return network;
}

def containerIp(containerName, network) {
    echo "Inside containerIp function"
    containerIp = sh (
        script: "docker inspect --format=\"{{.NetworkSettings.Networks." + network + ".IPAddress}}\" "+ containerName,
        returnStdout: true
    ).trim()

    echo containerName+" IP = " + containerIp;
    return containerIp;
}