[Yandex Cloud documentation](../../index.md) > [Tutorials](../index.md) > Development and testing > App testing with GitLab

# App testing with GitLab

[GitLab](https://about.gitlab.com/) is a web-based Git repository management platform. GitLab also allows developers to run a continuous process for writing, testing, and deploying code.

In this scenario, you will set up GitLab on a [virtual machine](../../compute/concepts/vm.md), create a simple C++ project, set up a test scenario, and test its execution.

To create and test a project in the GitLab environment:
1. [Get your cloud ready](#before-you-begin).
1. [Required paid resources](#paid-resources).
1. [Create a GitLab VM](#create-vm).
1. [Configure GitLab](#confgure-gitlab).
1. [Set the privacy settings](#disable-signup).
1. [Create a project](#create-project).
1. [Set up and run testing for the project](#ci-cd).
1. [Configure and register a runner](#configure-runner).
1. [Create a test pipeline](#create-test-case).
1. [Create an error in the project](#create).
1. [How to delete the resources you created](#clear-out).

## Get your cloud ready {#before-you-begin}

Sign up for Yandex Cloud and create a [billing account](../../billing/concepts/billing-account.md):
1. Navigate to the [management console](https://console.yandex.cloud) and log in to Yandex Cloud or create a new account.
1. On the **[Yandex Cloud Billing](https://center.yandex.cloud/billing/accounts)** page, make sure you have a billing account linked and it has the `ACTIVE` or `TRIAL_ACTIVE` [status](../../billing/concepts/billing-account-statuses.md). If you do not have a billing account, [create one](../../billing/quickstart/index.md) and [link](../../billing/operations/pin-cloud.md) a cloud to it.

If you have an active billing account, you can create or select a [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) for your infrastructure on the [cloud page](https://console.yandex.cloud/cloud).

[Learn more about clouds and folders here](../../resource-manager/concepts/resources-hierarchy.md).

### Required paid resources {#paid-resources}

The cost for maintaining a GitLab server includes:
* Fee for a [disk](../../compute/concepts/disk.md) and a continuously running VM (see [Yandex Compute Cloud pricing](../../compute/pricing.md)).
* Fee for a dynamic or static [public IP address](../../vpc/concepts/address.md#public-addresses) (see [Yandex Virtual Private Cloud pricing](../../vpc/pricing.md)).

## Create a GitLab VM {#create-vm}

1. On the [folder](../../resource-manager/concepts/resources-hierarchy.md#folder) dashboard in the [management console](https://console.yandex.cloud), click **Create resource** and select `Virtual machine instance`.
1. Under **Boot disk image**, in the **Product search** field, enter `Gitlab` and select a public [GitLab](https://yandex.cloud/en/marketplace/products/yc/gitlab) image.
1. Under **Location**, select an [availability zone](../../overview/concepts/geo-scope.md) for your VM. If you are not sure which one to choose, leave the default.
1. Under **Disks and file storages**, select the `SSD` [disk type](../../compute/concepts/disk.md#disks_types) and specify its size: `20 GB`.
1. Under **Computing resources**, switch to the `Custom` tab and specify the [platform](../../compute/concepts/vm-platforms.md), number of vCPUs, and amount of RAM:

    * **Platform**: `Intel Ice Lake`
    * **vCPU**: `4`
    * **Guaranteed vCPU performance**: `100%`
    * **RAM**: `8 GB`

1. Under **Network settings**:

    * In the **Subnet** field, select the network and subnet to which you want to connect your VM. If the [network](../../vpc/concepts/network.md#network) or [subnet](../../vpc/concepts/network.md#subnet) you need does not exist yet, [create it](../../vpc/operations/subnet-create.md).
    * In the **Public IP address** field, select a static IP address from the list, or leave `Auto` to assign your VM a random external IP address from the Yandex Cloud pool.

1. Under **Access**, select **SSH key** and specify the VM access credentials:

    * In the **Login** field, enter a username. Do not use `root` or other reserved usernames. For operations requiring root privileges, use the `sudo` command.
    * In the **SSH key** field, select the SSH key saved in your [organization user](../../organization/concepts/membership.md) profile.
      
      If there are no SSH keys in your profile or you want to add a new key:
      
      1. Click **Add key**.
      1. Enter a name for the SSH key.
      1. Select one of the following:
      
          * `Enter manually`: Paste the contents of the public SSH key. You need to [create](../../compute/operations/vm-connect/ssh.md#creating-ssh-keys) an SSH key pair on your own.
          * `Load from file`: Upload the public part of the SSH key. You need to create an SSH key pair on your own.
          * `Generate key`: Automatically create an SSH key pair.
          
            When adding a new SSH key, an archive containing the key pair will be created and downloaded. In Linux or macOS-based operating systems, unpack the archive to the `/home/<user_name>/.ssh` directory. In Windows, unpack the archive to the `C:\Users\<user_name>/.ssh` directory. You do not need additionally enter the public key in the management console.
      
      1. Click **Add**.
      
      The system will add the SSH key to your organization user profile. If the organization has [disabled](../../organization/operations/os-login-access.md) the ability for users to add SSH keys to their profiles, the added public SSH key will only be saved in the user profile inside the newly created resource.

1. Under **General information**, specify the VM name: `gitlab`.
1. Click **Create VM**.

Wait about five minutes until the VM is created and all its services are up and running. After all of the services are up and running, GitLab becomes accessible via the web interface in a browser.

## Configure GitLab {#confgure-gitlab}

1. Navigate to **Compute Cloud**.
1. Select the VM instance you created, `gitlab`, and copy its public IP address.
1. [Connect](../../compute/operations/vm-connect/ssh.md#vm-connect) to the VM over SSH.
1. Get the GitLab administrator password with the following VM command:

   ```bash
   sudo cat /etc/gitlab/initial_root_password
   ```

1. Copy the password without spaces from the `Password` line to the clipboard or a separate file.
1. In your browser, open `http://<VM_public_IP_address>`. This will take you to the GitLab web UI.
1. Log in as the administrator:
   * **Username or email**: `root`.
   * **Password**: Password you copied in the previous step.

   If you are unable to log in, [reset the administrator password](https://docs.gitlab.com/ee/security/reset_user_password.html#reset-your-root-password).
1. [Change the administrator password](https://docs.gitlab.com/ee/user/profile/#change-your-password).
1. Log in as the administrator with the new password.

### Set the privacy settings {#disable-signup}

Disable sign-up for other users on the login page:
1. Go to **Admin area**.
1. In the left-hand panel, go to **Settings** and select the **General** tab.
1. Under **Sign-up restrictions**, click **Expand**.
1. Uncheck **Sign-up enabled**.
1. Click **Save changes**.

Now, only the administrator can create new users in the **Users** tab under **Overview**.

## Create a project {#create-project}

To create a project:
1. On the GitLab home page, select **Create a project**.
1. On the page that opens, specify:
   * Project name: `My Project`.
   * Project group and project ID: `root` and `my-project`, respectively.
   * Description and scope of the project, if required.
1. Click **Create project**.

   ![Creating a project](../../_assets/tutorials/gitlab/gitlab1.png)

1. Once you create the project, go to **Settings** in the left-hand panel and select the **CI/CD** tab.
1. Under **Auto DevOps**, click **Expand**, disable **Default to Auto DevOps pipeline**, and click **Save changes**.

   ![Disabling Auto DevOps](../../_assets/tutorials/gitlab/gitlab2.png)

1. Add a project file.
   1. In the left-hand panel, go to the GitLab project.
   1. Click ![image](../../_assets/console-icons/plus.svg) in the repository navigation bar and select **New file** from the drop-down menu.
   1. Name your file `test.cpp`. Add program code that checks that 2 multiplied by 2 equals 4 and prints `Hello World` if the result is 4:

      ```cpp
      #include <iostream>
      #include <cassert>

      int main() {
        assert(2 * 2 == 4);
        std::cout << "Hello world!" << std::endl;
        return 0;
      }
      ```

      ![Adding a file](../../_assets/tutorials/gitlab/gitlab3.png)

   1. Enter a commit name in the **Commit message** field.
   1. Click **Commit changes**.

## Set up and run testing for the project {#ci-cd}

A runner is a program that tests and builds projects in the GitLab environment by following provided instructions.

### Configure and register a runner {#configure-runner}

1. [Use SSH to connect](../../compute/operations/vm-connect/ssh.md#vm-connect) to the VM and switch to administrator mode in the console:

   ```bash
   sudo -i
   ```

1. Download a runner:

   ```bash
   curl --location --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
   ```

1. Make the runner executable:

   ```bash
   chmod +x /usr/local/bin/gitlab-runner
   ```

1. Create a separate user to start the runner:

   ```bash
   useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
   ```

1. Install and start the runner:

   ```bash
   gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
   gitlab-runner start
   ```

1. Register your runner in GitLab:
   1. Run the `gitlab-runner register` command for interactive registration.
   1. Enter your GitLab server address. When you see this prompt:

      ```text
      Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com)
      ```

      enter `http://<public_IP_address_of_your_VM>`.
   1. Enter the registration token for the runner. To get it, go to the project page in GitLab, select **Settings** in the left-hand panel, and open the **CI/CD** tab. Then click **Expand** under **Runners**. Under **Set up a specific Runner manually**, copy the token from _Step 3_ and enter it when prompted as follows:

      ```text
      Please enter the gitlab-ci token for this runner
      <token>
      ```

      ![Getting a token](../../_assets/tutorials/gitlab/gitlab4.png)

   1. When you see this prompt:

      ```text
      Please enter the gitlab-ci description for this runner
      ```

      enter a description for the runner: `My runner`.
   1. Leave the tag field empty and press**Enter**. Otherwise, by default, the runner will not run jobs unless the project has matching tags.
   1. Specify the runtime. In our scenario, when prompted:

      ```text
      Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
      ```

      enter: `shell`.

The runner is now installed and configured. If everything is set up correctly, you should see the **Runners activated for this project** section on the page where you copied the registration token, displaying the registered runner.

![Successful setup](../../_assets/tutorials/gitlab/gitlab5.png)

### Create a test pipeline {#create-test-case}

Create a test pipeline for the runner to complete. Describe the pipeline in a dedicated file named `.gitlab-ci.yml` located in the project root directory. According to the pipeline, the runner will compile the project source file, convert it to an executable file, and then run it.

As testing will take place in the VM operating system, you need to install the apps required for testing: `git` to clone the project from the repository and `g++` to compile the project.

To create a test pipeline:
1. Connect to the VM over SSH and install the required apps:

   ```bash
   sudo apt update
   sudo apt install -y git g++
   ```

1. Add a test pipeline:
   1. Open the GitLab web UI.
   1. Open the GitLab project.
   1. On the page that opens, click **Set up CI/CD**.
   1. You will see a page prompting you to add a new file named `.gitlab-ci.yml`, where you need to describe the pipeline in [YAML](https://yaml.org/) format. Add the pipeline configuration:

      ```yaml
      stages:
        - build
        - test
        - pack

      cache:
        paths:
          - hello

      build:
        stage: build
        script: g++ test.cpp -o hello

      test:
        stage: test
        script: ./hello

      pack:
        stage: pack
        script: gzip -c hello > hello.gz
        artifacts:
          paths:
            - hello.gz
      ```

      The pipeline includes three stages that run one after another:
      * `build`: First stage that compiles the project into the `hello` executable.
      * `test`: Second stage that runs the executable.
      * `pack`: Third stage that creates an archive with the executable, which you can download via the GitLab web UI after the pipeline completes successfully. The `artifacts` section lists the files available for download.

      Under `cache`, specify the files and directories to transfer between stages. If you skip it, the `hello` file will not be available at the `test` stage, resulting in an error.

      ![Test pipeline](../../_assets/tutorials/gitlab/gitlab6.png)

   1. Click **Commit changes**.

After committing, the system will automatically start testing the latest commit. To check its results, select **Build** on the left-hand panel in the GitLab project, and then **Pipelines** from the drop-down menu. You should see a line with the first test showing `passed`. By clicking the cloud icon, you can download the build artifacts.

### Create an error in the project {#create}

Now modify the project so it produces an error that the runner can detect during testing. Follow these steps:
1. Go to the project repository and open the `test.cpp` file.
1. Click **Edit**.
1. Update the assert so that 2 multiplied by 2 equals 5. This will cause the program to fail.

   ```cpp
   ...
   assert(2 * 2 == 5);
   ...
   ```

1. Name your commit: `Wrong assert in test.cpp`.
1. Click **Commit changes**.

Open **Build** → **Pipelines**. In the **Stages** column, you can see that the first stage, `build`, completed successfully, while the second stage, `test`, returned an error. The third stage, `pack`, was skipped and the build artifacts were not generated.

If you click the `failed` progress status and go to **Failed Jobs**, you can see the error text saying that `assert` failed:

![Runtime error](../../_assets/tutorials/gitlab/gitlab7.png)

## How to delete the resources you created {#clear-out}

To stop paying for your deployed server, delete the `gitlab` VM you created.

If you reserved a static public IP address for this VM:
1. From your folder, navigate to **Virtual Private Cloud**.
1. Open the **Public IP addresses** tab.
1. Find the IP address, click ![ellipsis](../../_assets/console-icons/ellipsis.svg), and select **Delete**.