Skip to content

MTT Cherrypy Server

Howard Pritchard edited this page Dec 19, 2024 · 12 revisions

Description

The MTT Cherrypy Server creates a layer of abstraction between MTT Python Client and the MTT PostgreSQL Database. It has two functions: submitting data and querying data. For submitting data, test results are submitted to the server which is then inserted into the database. For querying data, test results are requested form the server which then queries the database in order to provide the results.

Configuring and starting the server

Both the MTT Cherrypy Server as well as the PostgreSQL database need to be running for the server to work correctly. Below are instructions for setting up the the server and then a hint on testing the setup.

Set up server

  1. Install MTT in /opt. cd to /opt/mtt/server/php/cherrypy
  2. Create a .htpasswd file. See http://www.htaccesstools.com/htpasswd-generator/
  3. The next step will create a new virtual environment in /opt/mtt/server/php/cherrypy/src/env. Navigate to /opt/mtt/server/php/cherrypy then do the following to set up the virtual environment.
    1. python3 -m venv src/env
    2. . src/env/bin/activate
    3. pip3 install -r src/mtt_server_requirements.txt
  4. Navigate to /opt/mtt/server/php/cherrypy and run "python bin/mtt_server_install.py" to install the server.
  5. Modify a copy of /opt/mtt/server/php/cherrypy/.htaccess.tmpl to point to created .htpasswd file. NOTE: This is not implemented. All lines in .htaccess should be commented out.
  6. copy /opt/mtt/server/php/cherrypy/bin/mtt_server.cfg.tmpl to /opt/mtt/server/php/cherrypy/bin/mtt_server.cfg. Edit the new file to have DBNAME, USERNAME, PASSWORD, SERVERNAME, and SERVERPORT of your database'
  7. Navigate to /opt/mtt/server/php/cherrypy and run "python bin/mtt_server_service.py start" to start server

The server can be tested by running this code (assuming dbname, password, and all metadata are set up correctly):

echo "Output of RESTful POST to database test:"
curl -H "Content-Type: application/json" -X POST -d '{"data" : [ {"bitness": 0, "endian": "test", "vpath_mode": "test", "platform_hardware": "test", "platform_type": "test", "os_name": "test", "os_version": "test", "compiler_name": "test", "compiler_version": "test", "mpi_name": "test", "mpi_version": "test", "configure_arguments": "test", "start_timestamp": "Mon Jan 1 00:00:00 2000", "duration": "0 Seconds", "result_message": "test", "test_result": 0, "exit_value": 0, "merge_stdout_stderr": 0, "result_stderr": "test"} ], "metadata" : {"client_serial": 12345, "hostname": "test.test.com", "local_username": "test", "mtt_client_version": "4.0a1", "phase": "MPI Install", "platform_name": "sample_platform", "trial": 1}}' http://localhost:9080/submit --user mtt:******
if [ `psql "dbname=mtt host=localhost user=mtt password=****** port=5432" -c "copy (select start_timestamp from mpi_install where result_stderr like 'test') to stdout" |grep "2000-01-01 00:00:00"` ]; then
    echo "MTT Server is not working correctly"
else
    echo "MTT Server is working correctly"
fi

Linux (systemd)

The above steps to start the MTT server will not insure that the service will get restarted in the event of a process failure or a reboot. One option to address this problem is to run the service using systemd. Here is an example configuration file for systemd:

[Unit]
Description=Open MPI MTT CherryPy service
After=network.target auditd.service

[Service]
ExecStart=/opt/mtt/server/php/cherrypy/src/env/bin/python /opt/mtt/server/php/cherrypy/bin/mtt_server_service.py restart
ExecStop=/opt/mtt/server/php/cherrypy/src/env/bin/python /opt/mtt/server/php/cherrypy/bin/mtt_server_service.py stop
ExecReload=/bin/kill -HUP $MAINPID
KillMode=process
Restart=always
RestartSec=10
PIDFile=/opt/mtt/server/php/cherrypy/src/.mtt_server.pid
#RestartPreventExitStatus=255
Type=Forking
User=root

[Install]
WantedBy=multi-user.target

Specifying the non-default location of the mtt server pid file is important, otherwise systemd gets confused. To set up systemd to run the MTT_cherrypy.service at boot enter:

$ systemctl enable MTT_cherrypy.service

Interfaces

The server uses a JSON RESTful API for communicating with the Python Client and with any other viewer applications. This API is defined in dispatchers.py. Each interface has a class and a POST method which is called every time a request is made to the server. Within this POST method, API in db_pgv3.py is called to submit data to or query data from the database.

The interfaces are Submit, Fields, Detail, and Summary. Two unimplemented interfaces are Info Testsuite and Info Runtime. Submit is the only non-querying interface. The rest of the interfaces provide different ways of querying submitted data.

Submit Interface

Input fields are data and metadata • data: list of dictionaries where each dictionary has key-value pairs of data to be entered into database • metadata: contains relevant information about the data submission, such as "client_serial" connection ID, "hostname" of system where test was run, "local_username" used for submission, "mtt_client_version" of current state of MTT, "phase" of test results being submitted, "platform_name" of type of platform used, and "trial" of whether this is a real test

Sample Submit:

curl -H "Content-Type: application/json" -X POST -d \
'{"data" : [ {"bitness": 0, "endian": "battest", "vpath_mode": "battest", "platform_hardware": "battest", "platform_type": "test", "os_name": "battest", "os_version": "battest", "compiler_name": "battest", "compiler_version": "battest", "mpi_name": "battest", "mpi_version": "battest", "configure_arguments": "battest", "start_timestamp": "Mon Jan 1 00:00:00 2000", "duration": "0 Seconds", "result_message": "battest", "test_result": 0, "exit_value": 0, "merge_stdout_stderr": 0, "result_stderr": "battest"} ],
"metadata" : {"client_serial": 12345, "hostname": "battest.battest.com", "local_username": "battest", "mtt_client_version": "4.0a1", "phase": "MPI Install", "platform_name": "sample_platform", "trial": 1}}' \
http://localhost:9080/submit --user mtt:******

Result:

{"status": 0, "submit_id": 5, "status_message": "Success", "ids": [{"mpi_install_id": 9}]}

Fields Interface

Has no input.

Output returns all accessible fields.

Sample Query:

curl -H "Content-Type: application/json" -X POST -d '{}' http://localhost:9080/fields --user mtt:******

Result:

{"status": 0, "query_data": {"fields": {"submit_timestamp": "TODO", "merge_stdout_stderr": "If the output was merged: 0 = false, 1 = true", "http_username": "TODO", "test_name": "Name of the test", "configure_arguments": "TODO", "vpath_mode": "If the code was compiled using a VPATH build: 1 = relative path, 2 = absolute path, 0 = unknown (default)", "os_name": "Common name for the OS (e.g., \"Linux\")", "test_description": "Description of the test", "duration": "Time taken interval (e.g. \"322 seconds\", default \"0 seconds\")", "resource_manager": "String representation of the resource manager used (e.g. \"slurm\")", "message_size": "TODO", "description": "Text description of this test", "exit_signal": "TODO", "test_suite_description": "A description for the test suite", "network": "String representation of the network (often we just send \"\", server will try to discover from command)", "parameters": "Breakdown the command line parameters (often we just send \"\", server will try to discover from command)", "trial": "Whether this is a trial run: 0 = false, 1 = true", "hostname": "The hostname where the test ras run", "exit_value": "The return code of the process (e.g., \"0\")", "environment": "Any environment variables of note (usually this is blank)", "os_version": "Version information for the OS (e.g., \"Linux 2.6.32-573.12.1.e16.x86_64\")", "bitness": "The bitness of the machine: 1 = 8 bit, 2 = 16 bit, 4 = 32 bit, 6 = 32/64 bit, 8 = 64 bit, 16 = 128 bit, \"unknown\" = unknown bitness", "np": "Number of processes used (input to mpirun command)", "result_message": "A string representation of the test result (e.g., \"Success\" or \"Failed; timeout expired (00:10 DD:HH:MM:SS)\")", "latency_avg": "TODO", "interconnect_name": "TODO", "platform_hardware": "String representation of the hardware (e.g., \"x86_64\")", "mpi_version": "Version strin reported by MPI (e.g., \"v1.10.2-114-gf3bad94\")", "mtt_client_version": "Version of the client you are running", "client_serial": "A valid integer from a previous call to /serial", "suite_name": "A name for the test suite (e.g., \"trivial\")", "bandwidth_min": "TODO", "test_result": "A numerical classification of the test result: 0 = failed, 1 = passed, 2 = skipped, 3 = timed out, -1 = unknown", "latency_min": "TODO", "start_timestamp": "Timestamp when the test started", "compiler_name": "Common name for the compiler (e.g., \"gnu\")", "mpi_name": "A name for the MPI version (e.g., \"ompi-nightly-v1.10\")", "compiler_version": "Version string for the compiler (e.g., \"4.4.7\")", "launcher": "Binary name of what was used to launch the process (e.g., \"mpirun\")", "bandwidth_max": "TODO", "local_username": "The local username of the host", "latency_max": "TODO", "bandwidth_avg": "TODO", "platform_name": "Custom name of the platform (e.g., \"my-cluster\")", "platform_type": "String representation of the platform type (e.g., \"linux-rhel6.7-x86_64\")", "command": "The full command line string used", "result_stdout": "stdout of the process", "result_stderr": "stderr of the process"}}, "status_message": "Success"}

Detail Interface

Input fields are phase, columns, and search.

  • phase: Specifies which phase to query. These include install, test_build, and test_run.
  • columns: Specifies which columns to query. These are specified below in the "List of fields" section.
  • search: Specifies which filters to use. These can be used on any column to filter results on if a column equals a specific value.

Output is a list of query resutls where each query result is a list corresponding to chosen columns.

Sample Query:

curl -H "Content-Type: application/json" -X POST -d '{"phase" : "install", "columns" : ["mpi_version", "start_timestamp", "test_result", "exit_value"], "search" : {"mpi_version" : "battest"}, "metadata" : {}}' http://localhost:9080/detail --user mtt:******

Result:

{"status": 0, "query_data": [{"mpi_version": "battest", "test_result": 0, "exit_value": 0, "start_timestamp": "2000-01-01 00:00:00"}], "status_message": "Success"}

Summary Interface

Input fields are phase, columns, and search. The definitions of these fields are the same as in the Detail Interface.

Output is a list of query results, combining similar results and aggregating statistics on similar results counting how many failed, how many passed, how many skipped, how many timed out, and how many have an unknown status.

Sample Query:

curl -H "Content-Type: application/json" -X POST -d '{"phase" : "install", "columns" : ["mpi_version", "start_timestamp", "test_result", "exit_value"], "search" : {"mpi_version" : "battest"}, "metadata" : {}}' http://localhost:9080/summary --user mtt:******

Result:

{"status": 0, "query_data": [{"mpi_version": "battest", "test_result_skipped": 0, "exit_value": 0, "start_timestamp": "2000-01-01 00:00:00", "test_result_timed_out": 0, "test_result_failed": 1, "test_result_unknown": 0, "test_result_passed": 0, "test_result": 0}], "status_message": "Success"}

Info Testsuite Interface

Not Implemented

Info Runtime Interface

Not Implemented

List of fields

This is a list of fields that are usable in the columns input and are filterable in the search input.

These fields are defined in the top of the db_pgv3.py script.

merge_stdout_stderr

  • Type: bool
  • Desc: If the output was merged: 0 = false, 1 = true

test_suite_description

  • Type: str
  • Desc: A description for the test suite

parameters

  • Type: str
  • Desc: Breakdown the command line parameters (often we just send "", server will try to discover from command)

environment

  • Type: str
  • Desc: Any environment variables of note (usually this is blank)

os_version

  • Type: str
  • Desc: Version information for the OS (e.g., "Linux 2.6.32-573.12.1.e16.x86_64")

bitness

  • Type: int
  • Desc: The bitness of the machine: 1 = 8 bit, 2 = 16 bit, 4 = 32 bit, 6 = 32/64 bit, 8 = 64 bit, 16 = 128 bit, "unknown" = unknown bitness

result_message

  • Type: str
  • Desc: A string representation of the test result (e.g., "Success" or "Failed; timeout expired (00:10 DD:HH:MM:SS)")

latency_min

  • Type: float_list
  • Desc: TODO

interconnect_name

  • Type: str
  • Desc: TODO

platform_hardware

  • Type: str
  • Desc: String representation of the hardware (e.g., "x86_64")

compiler_name

  • Type: str
  • Desc: Common name for the compiler (e.g., "gnu")

client_serial

  • Type: int
  • Desc: A valid integer from a previous call to /serial

suite_name

  • Type: str
  • Desc: A name for the test suite (e.g., "trivial")

bandwidth_min

  • Type: float_list
  • Desc: TODO

latency_avg

  • Type: float_list
  • Desc: TODO

mpi_version

  • Type: str
  • Desc: Version strin reported by MPI (e.g., "v1.10.2-114-gf3bad94")

compiler_version

  • Type: str
  • Desc: Version string for the compiler (e.g., "4.4.7")

mpi_name

  • Type: str
  • Desc: A name for the MPI version (e.g., "ompi-nightly-v1.10")

launcher

  • Type: str
  • Desc: Binary name of what was used to launch the process (e.g., "mpirun")

bandwidth_max

  • Type: float_list
  • Desc: TODO

local_username

  • Type: str
  • Desc: The local username of the host

latency_max

  • Type: float_list
  • Desc: TODO

platform_type

  • Type: str
  • Desc: String representation of the platform type (e.g., "linux-rhel6.7-x86_64")

result_stderr

  • Type: str
  • Desc: stderr of the process

submit_timestamp

  • Type: str
  • Desc: TODO

configure_arguments

  • Type: str
  • Desc: TODO

http_username

  • Type: str
  • Desc: TODO

resource_manager

  • Type: str
  • Desc: String representation of the resource manager used (e.g. "slurm")

vpath_mode

  • Type: int
  • Desc: If the code was compiled using a VPATH build: 1 = relative path, 2 = absolute path, 0 = unknown (default)

duration

  • Type: str
  • Desc: Time taken interval (e.g. "322 seconds", default "0 seconds")

bandwidth_avg

  • Type: float_list
  • Desc: TODO

network

  • Type: str
  • Desc: String representation of the network (often we just send "", server will try to discover from command)

hostname

  • Type: str
  • Desc: The hostname where the test ras run

exit_value

  • Type: int
  • Desc: The return code of the process (e.g., "0")

exit_signal

  • Type: int
  • Desc: TODO

np

  • Type: int
  • Desc: Number of processes used (input to mpirun command)

command

  • Type: str
  • Desc: The full command line string used

os_name

  • Type: str
  • Desc: Common name for the OS (e.g., "Linux")

test_description

  • Type: str
  • Desc: Description of the test

description

  • Type: str
  • Desc: Text description of this test

mtt_client_version

  • Type: str
  • Desc: Version of the client you are running

test_name

  • Type: str
  • Desc: Name of the test

test_result

  • Type: int
  • Desc: A numerical classification of the test result: 0 = failed, 1 = passed, 2 = skipped, 3 = timed out, -1 = unknown

start_timestamp

  • Type: str
  • Desc: Timestamp when the test started

result_stdout

  • Type: str
  • Desc: stdout of the process

message_size

  • Type: int_list
  • Desc: TODO

platform_name

  • Type: str
  • Desc: Custom name of the platform (e.g., "my-cluster")

trial

  • Type: bool
  • Desc: Whether this is a trial run: 0 = false, 1 = true