{"id":19390844,"url":"https://github.com/tecnickcom/natstest","last_synced_at":"2026-02-27T03:33:59.966Z","repository":{"id":66250103,"uuid":"152957211","full_name":"tecnickcom/natstest","owner":"tecnickcom","description":"NATS Bus Functional Test Component","archived":false,"fork":false,"pushed_at":"2025-05-13T14:28:19.000Z","size":330,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-05T03:46:09.763Z","etag":null,"topics":["bus","golang","json","nats","reflection","test"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tecnickcom.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":["https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ"]}},"created_at":"2018-10-14T09:13:12.000Z","updated_at":"2025-05-13T14:28:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"fe49fd94-8f59-45c9-9bf6-8dc0680467e1","html_url":"https://github.com/tecnickcom/natstest","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/tecnickcom/natstest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecnickcom%2Fnatstest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecnickcom%2Fnatstest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecnickcom%2Fnatstest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecnickcom%2Fnatstest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tecnickcom","download_url":"https://codeload.github.com/tecnickcom/natstest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tecnickcom%2Fnatstest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29883778,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-26T23:51:21.483Z","status":"online","status_checked_at":"2026-02-27T02:00:06.759Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bus","golang","json","nats","reflection","test"],"created_at":"2024-11-10T10:23:34.655Z","updated_at":"2026-02-27T03:33:59.941Z","avatar_url":"https://github.com/tecnickcom.png","language":"Go","funding_links":["https://www.paypal.com/donate/?hosted_button_id=NZUEC5XS8MFBJ"],"categories":[],"sub_categories":[],"readme":"# natstest\n\n*NATS Bus Functional Test Component*\n\n[![Master Branch](https://img.shields.io/badge/-master:-gray.svg)](https://github.com/tecnickcom/natstest/tree/master)\n[![Master Build Status](https://secure.travis-ci.org/tecnickcom/natstest.png?branch=master)](https://travis-ci.org/tecnickcom/natstest?branch=master)\n[![Master Coverage Status](https://coveralls.io/repos/tecnickcom/natstest/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/tecnickcom/natstest?branch=master)\n[![Go Report Card](https://goreportcard.com/badge/github.com/tecnickcom/natstest)](https://goreportcard.com/report/github.com/tecnickcom/natstest)\n\n* **category**:    Service\n* **author**:      Nicola Asuni \u003cinfo@tecnick.com\u003e\n* **copyright**:   2016-2017 MIRACL UK LTD\n* **license**:     ASL 2.0 - http://www.apache.org/licenses/LICENSE-2.0\n* **link**:        https://github.com/tecnickcom/natstest\n\n## Description\n\n*NATS Bus Test Component.*\n\nThis program provides a RESTful HTTP JSON API service to test services connected to a [NATS](http://nats.io) bus.\nIt has been designed to test any system composed by services that exchange JSON messages via a NATS bus.\n\nIt is capable of sending arbitrary sequences of raw JSON messages to the NATS bus and compare the responses with the expected ones.\nThe test sequences are defined using the JSON format and can be either stored as configuration files or sent via the HTTP interface.\n\n![Main Schema](doc/images/natstest_schema.png)\n\n\n## Requirements\n\nAn additional Python program is used to check the validity of the JSON configuration files against a JSON schema:\n\n```\nsudo pip install json-spec \n```\n\n## Quick Start\n\nThis project includes a Makefile that allows you to test and build the project in a Linux-compatible system with simple commands.  \nAll the artifacts and reports produced using this Makefile are stored in the *target* folder.  \n\nAll the packages listed in the *resources/DockerDev/Dockerfile* file are required in order to build and test all the library options in the current environment. Alternatively, everything can be built inside a [Docker](https://www.docker.com) container using the command \"make dbuild\".\n\nTo see all available options:\n```\nmake help\n```\n\nTo build the project inside a Docker container (requires Docker):\n```\nmake dbuild\n```\n\nTo build a particular set of options inside a Docker container:\n```\nMAKETARGET='buildall' make dbuild\n```\nThe list of pre-defined options can be listed by typing ```make```\n\n\nThe base Docker building environment is defined in the following Dockerfile:\n```\nresources/DockerDev/Dockerfile\n```\n\nTo execute all the default test builds and generate reports in the current environment:\n```\nmake qa\n```\n\nTo format the code (please use this command before submitting any pull request):\n```\nmake format\n```\n\n## Useful Docker commands\n\nTo manually create the container you can execute:\n```\ndocker build --tag=\"tecnickcom/natstestdev\" .\n```\n\nTo log into the newly created container:\n```\ndocker run -t -i tecnickcom/natstestdev /bin/bash\n```\n\nTo get the container ID:\n```\nCONTAINER_ID=`docker ps -a | grep tecnickcom/natstestdev | cut -c1-12`\n```\n\nTo delete the newly created docker container:\n```\ndocker rm -f $CONTAINER_ID\n```\n\nTo delete the docker image:\n```\ndocker rmi -f tecnickcom/natstestdev\n```\n\nTo delete all containers\n```\ndocker rm $(docker ps -a -q)\n```\n\nTo delete all images\n```\ndocker rmi $(docker images -q)\n```\n\n\n## Usage\n\n```\nUsage:\n  natstest [flags]\n  natstest [command]\n\nAvailable Commands:\n  version     print this program version\n\nFlags:\n  -c, --configDir     string  Configuration directory to be added on top of the search list\n  -l, --logLevel      string  Log level: EMERGENCY, ALERT, CRITICAL, ERROR, WARNING, NOTICE, INFO, DEBUG\n  -n, --natsAddress   string  NATS bus Address (nats://ip:port) (default \"nats://127.0.0.1:4222\")\n  -s, --serverAddress string  HTTP API URL (ip:port) or just (:port) (default \":8081\")\n\nUse \"natstest [command] --help\" for more information about a command.\n```\n\n## How it works\n\nThe service can be started by issuing the following command (*with the right parameters*):\n\n```\nnatstest --serverAddress=\":8080\" --natsAddress=\"nats://127.0.0.1:4222 --logLevel=DEBUG\"\n```\n\nIf no command-line parameters are specified, then the ones in the configuration file (**config.json**) will be used.  \nThe configuration files can be stored in the current directory or in any of the following (in order of precedence):\n* ./\n* config/\n* $HOME/natstest/\n* /etc/natstest/\n\n\nThis service also support secure remote configuration via [Consul](https://www.consul.io/) or [Etcd](https://github.com/coreos/etcd).  \nThe remote configuration server can be defined either in the local configuration file using the following parameters, or with environment variables:\n\n* **remoteConfigProvider** : remote configuration source (\"consul\", \"etcd\");\n* **remoteConfigEndpoint** : remote configuration URL (ip:port);\n* **remoteConfigPath** : remote configuration path where to search fo the configuration file (e.g. \"/config/natstest\");\n* **remoteConfigSecretKeyring** : path to the openpgp secret keyring used to decript the remote configuration data (e.g. \"/etc/natstest/configkey.gpg\"); if empty a non secure connection will be used instead;\n\nThe equivalent environment variables are:\n\n* NATSTEST_REMOTECONFIGPROVIDER\n* NATSTEST_REMOTECONFIGENDPOINT\n* NATSTEST_REMOTECONFIGPATH\n* NATSTEST_REMOTECONFIGSECRETKEYRING\n\n\nOnce the service is started without errors, a RESTful HTTP JSON API server will listen on the configured **address:port** for the following entry points:\n\n| ENTRY POINT                   | METHOD | DESCRIPTION                                                    |\n|:----------------------------- |:------:|:-------------------------------------------------------------- |\n|\u003cnobr\u003e /                \u003c/nobr\u003e| GET    |\u003cnobr\u003e return a list of available entry points and tests \u003c/nobr\u003e|\n|\u003cnobr\u003e /status          \u003c/nobr\u003e| GET    |\u003cnobr\u003e return the status of the service                  \u003c/nobr\u003e|\n|\u003cnobr\u003e /test/TESTNAME   \u003c/nobr\u003e| GET    |\u003cnobr\u003e execute the test identified by the TESTNAME       \u003c/nobr\u003e|\n|\u003cnobr\u003e /test/all        \u003c/nobr\u003e| GET    |\u003cnobr\u003e execute all the available tests                   \u003c/nobr\u003e|\n|\u003cnobr\u003e /reload          \u003c/nobr\u003e| GET    |\u003cnobr\u003e reload and reset all test configuration files     \u003c/nobr\u003e|\n|\u003cnobr\u003e /new/TESTNAME    \u003c/nobr\u003e| PUT    |\u003cnobr\u003e upload and execute a new test                     \u003c/nobr\u003e|\n|\u003cnobr\u003e /delete/TESTNAME \u003c/nobr\u003e| DELETE |\u003cnobr\u003e delete the specified test                         \u003c/nobr\u003e|\n\n\nThe natstest HTTP RESTful API always returns a JSON message with the following fields:\n\n![HTTP JSON API Response Format](doc/images/natstest_httpjson.png)\n\nThe available tests are specified using JSON configuration files with the following naming syntax:  \n**test_TESTNAME.json**  \nThe TESTNAME may contains characters from 'a' to 'z', numbers from '0' to '9' and the character '@' used only for internal testing.\n\n![Test format](doc/images/natstest_test_format.png)\n\nEach configuration file contains a sequence (an array or slice) of RAW messages for the NATS bus with:\n* **Topic** : the message will be processed by the service listening to the specified topic;\n* **Request** : the raw JSON message content to send;\n* **Response** : the expected response message template.\n\nEach field in the *Request* and *Response* section of a test message supports templates in addition to fixed values:\n\n* **Regular Expression** (only for Response)  \nA regular expression is identified by the “~re:” prefix.  \nFor example, the following regular expression matches any integer number:  \n*\"fieldA\" : \"~re:[0-­9]+\"*\n\n* **External Comparison** (only for Response)  \nAn external command-line tool used to compare the expected with the actual value is identified by the “~xc:” prefix, followed by the command (e.g. /usr/bin/mycomparetool), a colon (:) and the string-encoded expected value.\nThe external tool must accept two arguments, the first one is the expected value and the second one is the actual value.\nThe actual value will be automatically JSON-encoded if it is not a simple string.  \nFor example:  \n*\"fieldA\" : \"~xc:/usr/bin/mycomparetool.sh:expected_value\"*\n\n* **TimeStamp**  \nWe can add the current UTC timestamp by using the “~ts:” prefix followed by the time format as defined in https://golang.org/pkg/time, or without format to get the Unix timestamp in seconds.  \nFor example:  \n*\"unixTimestamp\" : \"~ts:\",  \n*\"time\" : \"~ts:15:04:05\"  \n\n* **Previous Value**  \nWe can refer to any previously returned value by using the “~pv:” prefix followed by the path to the the reference field.  \nFor example, the following refers to the value of someField in the Response section of the fourth message (the message index starts from zero):  \n*\"fieldB\" : \"~pv:3.Response.someField\"*\n\n* **Tranformed Previous Value**  \nThe Previous Values as described above can be transformed by an external command-line application using the syntax as in the following example:  \n*\"fieldC\" : \"~pv:6.Response.anotherField\u003e/bin/echo -­n %v\"*  \nIn this example the command line application is “/bin/echo” and the previous value is passed as argument (”%v” placeholder).  \nThe allowed external command-line applications are defined in the configuration file.\nIf the argument is not a single value, then it will be passed as JSON string.\n\n## Command-line API Examples\n\n```\n$ curl -X GET http://127.0.0.1:8080/\n{\"program\":\"natstest\",\"version\":\"4.7.1\",\"release\":\"1\",\"datetime\":\"2016-10-06T15:00:39Z\",\"timestamp\":1475766039290853316,\"status\":\"success\",\"code\":200,\"message\":\"OK\",\"data\":{\"busy\":false,\"duration\":40.08854651,\"routes\":[{\"method\":\"GET\",\"path\":\"/status\",\"description\":\"check this service status\"},{\"method\":\"GET\",\"path\":\"/test/:name\",\"description\":\"execute the specified test\"},{\"method\":\"GET\",\"path\":\"/reload\",\"description\":\"reset and reload the test configuration files\"},{\"method\":\"PUT\",\"path\":\"/new/:name\",\"description\":\"load and execute the specified test configuration\"},{\"method\":\"DELETE\",\"path\":\"/delete/:name\",\"description\":\"remove the specified test configuration\"}],\"tests\":[\"@cli\",\"@example\",\"@internal\"]}}\n\n$ curl -X GET http://127.0.0.1:8080/status\n{\"program\":\"natstest\",\"version\":\"4.7.1\",\"release\":\"1\",\"datetime\":\"2016-10-06T15:00:39Z\",\"timestamp\":1475766039290853316,\"status\":\"success\",\"code\":200,\"message\":\"OK\",\"data\":{\"busy\":false,\"duration\":40.230439379,\"nats\":true,\"message\":\"The service is healthy\"}}\n\n$ curl -X GET http://127.0.0.1:8080/test/@internal\n{\"program\":\"natstest\",\"version\":\"4.7.1\",\"release\":\"1\",\"datetime\":\"2016-10-06T15:00:39Z\",\"timestamp\":1475766039290853316,\"status\":\"success\",\"code\":200,\"message\":\"OK\",\"data\":{\"tests\":1,\"duration\":0.00665151,\"message\":\"All tests completed successfully\"}}\n\n$ curl -H \"Content-Type: application/json\" -X PUT -d '[{\"Topic\":\"@ab.cd\",\"Request\":{\"a\":\"b\"},\"Response\":{\"a\":\"b\"}}]' http://127.0.0.1:8080/new/@abcd\n{\"program\":\"natstest\",\"version\":\"4.7.1\",\"release\":\"1\",\"datetime\":\"2016-10-06T15:00:39Z\",\"timestamp\":1475766039290853316,\"status\":\"success\",\"code\":200,\"message\":\"OK\",\"data\":{\"tests\":1,\"duration\":0.00424797,\"message\":\"All tests completed successfully\"}}\n\n$ curl -X GET http://127.0.0.1:8080/test/all\n{\"program\":\"natstest\",\"version\":\"4.7.1\",\"release\":\"1\",\"datetime\":\"2016-10-06T15:00:39Z\",\"timestamp\":1475766039290853316,\"status\":\"success\",\"code\":200,\"message\":\"OK\",\"data\":{\"tests\":0,\"duration\":1.8450000000000001e-06,\"message\":\"All tests completed successfully\"}}\n\n$ curl -X DELETE http://127.0.0.1:8080/delete/@abcd\n{\"program\":\"natstest\",\"version\":\"4.7.1\",\"release\":\"1\",\"datetime\":\"2016-10-06T15:00:39Z\",\"timestamp\":1475766039290853316,\"status\":\"success\",\"code\":200,\"message\":\"OK\",\"data\":\"the test @abcd has been successfully removed\"}\n\n$ curl -X GET http://127.0.0.1:8080/reload\n{\"program\":\"natstest\",\"version\":\"4.7.1\",\"release\":\"1\",\"datetime\":\"2016-10-06T15:00:39Z\",\"timestamp\":1475766039290853316,\"status\":\"success\",\"code\":200,\"message\":\"OK\",\"data\":\"the test configuration files were successfully reloaded\"}\n```\n\n## Testing approach\n\nEven if *natstest* allows to add and delete tests dynamically at runtime, the preferred approach is to store the tests in the configuration directory, so they can be used consistently as *regression tests*. The ability to add and delete tests via the HTTP interface should be used mainly during the development of the tests and for debugging.\n\nThe tests can be triggered manually via the HTTP interface, automatically via CI/CD when a new version of a service is deployed, or periodically using a cron job.\n\nThe types of test to be performed can be divided in two categories:\n\n* **Topic testing**  \nThe aim of this is to test in isolation each topic of each service attached to the *NATS* bus.  \nThis requires a test configuration file for each individual service, containing one or more messages for each topic to test. The test should be named: *test_servicename.json*  \nThis type of test can be seen as analogue to *unit testing*, so the developer should be responsible for keeping it consistent with the code base.  \nIf a particular topic message requires the information provided by another service and it is not possible to mock it, then it should be tested using the *functional testing* described hereinafter.\n\n* **Functional testing**  \nThe aim of this is to test functionalities which involve the use of multiple services.  \nThis requires a test configuration file for each functionality to test. The test should be named: *test_functionname.json*  \nAs in the traditional functional testing, each test is equivalent to a scenario.  \nIt is likely that the *Request* messages contains values or transformation of values returned by previous message interactions. In this case the developers should provide the required command-line transformation applications. The full path of each authorized transformation application needs to be added in the *\"validTransfCmd\"* list inside the *config.json* configuration file.\n\n\n## Logs\n\nThis service logs the log messages in JSON format.\nFor example:\n\n```\n{\"URI\":\"/new/@alpha\",\"code\":200,\"datetime\":\"2016-10-06T15:00:39Z\",\"hostname\":\"myserver\",\"level\":\"info\",\"msg\":\"request\",\"program\":\"natstest\",\"release\":\"1\",\"timestamp\":1475766039290853316,\"type\":\"PUT\",\"version\":\"4.7.1\"}\n\n```\n\n## Developer(s) Contact\n\n* Nicola Asuni \u003cinfo@tecnick.com\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftecnickcom%2Fnatstest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftecnickcom%2Fnatstest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftecnickcom%2Fnatstest/lists"}