### ----------------------------------------------------
### -- MongoDB
### -- Licenses: Artistic-2.0
### -- Authors: Marcel Timmerman, Paweł Pabian
### -- File: xt/TestDocs/test-setup.md
### ----------------------------------------------------
# Introduction

The test setup is completely changed due to its complexity. The main reason is that I want to run tests which are destructive for the users database. Examples are;
* Start and stop a server
* Add and remove accounts
* Work on other collections than the test database and collection
* Add and remove data
* Run tests which need more than one server, like e.g;
  * Setup replica sets
  * Use sharded servers
  * Other type of servers

So first of all, the tests the user get to run when installing the package is only a load of the modules. This is a Raku compile test.

The tests I want to do to test the package are done on my system in a Linux Fedora environment. Also I want to test the software in a docker environment created by **JJ Merelo**, which can be done in two ways, here or on `github actions`. That environment is an Ubuntu Linux system.
TODO; `github actions` has also the possibility to test directly but is failing to find the `rakudo` program after installing. This would be the way to also be able to test for `Windows` or `MacOS`.

# Setup

## Directory **t**
The `t` directory is used to run tests when installing the driver. These tests are simple.

## Directory **xt**
The `xt` directory is used for the other tests. These are not run when installing the driver.

* `xt/TestServers` is used to store the **mongod** and **mongos** servers of different versions and the run time environment of those servers as well as the configuration of it.
* `xt/Tests` is used to store the test programs
* `xt/TestDocs` is for the documentation and results
* `xt/wrapper.raku` is the test control program

![file system](file-system.svg)

## Wrapper steps
* Configuration and start
  * The program `wrapper.raku` reads a configuration file `TestServers/config.yaml`.
  * Using the provided information it generates the `TestServers/ServerData/<server-name>/<version>/server-config.conf`. The `server-name` is a key used to find info in the config file. The `version` is used to select the proper server binary.
  * Start the server. The server will fill the directory `TestServers/ServerData/<server-name>/<version>/db` with data generated by the server.

* Tests
  * Each test is started using `rakudo` and not `prove6`. The tests are given the arguments `log-path`, `version` and `server ports`.
      ```
      my Str $log-path = @*ARGS[0];
      my Version $version .= new(@*ARGS[1]);
      my @server-ports = @*ARGS[2..*];
      ```
  * The test must use the log path to send messages to. This is done like;
      ```
      drop-send-to('mongodb');
      drop-send-to('screen');
      #modify-send-to( 'screen', :level(MongoDB::MdbLoglevels::Trace));
      my $handle = $log-path.IO.open( :mode<wo>, :append);
      add-send-to(
        'mdb', :to($handle), :min-level(MongoDB::MdbLoglevels::Trace)
      );
      set-filter(
        |<ObserverEmitter Timer Monitor Socket SocketPool Server ServerPool>
      );

      info-message("Test $?FILE start");
      ```
  * Then preparations for tests which may differ
      ```
      my BSON::Document $req;
      my BSON::Document $doc;
      #my MongoDB::Cursor $cursor;

      # single server tests => one server key
      my Str $uri = "mongodb://localhost:@server-ports[0]";
      my MongoDB::Client $client .= new(:$uri);
      my MongoDB::Database $database = $client.database('test');
      my MongoDB::Database $db-admin = $client.database('admin');

      # Create collection and insert data in it!
      my MongoDB::Collection $collection = $database.collection('cl1');
      isa-ok( $collection, 'MongoDB::Collection');

      $database.run-command: (drop => $collection.name,);
      ```

* Finishing tests
  * Stop server
  * Cleanup database
  * Examine log file
  * Display results of tests, the test programs run and show a list of used `run-command()` calls at the end.


# Conclusion

Above tests are done against single server setups. The wrapper must be changed a bit to cope with more complex tests like creating replicasets and sharded servers.


