GithubHelp home page GithubHelp logo

smoke.sh's Introduction

smoke.sh

A minimal smoke testing framework in Bash.

Features:

  • Response body checks
  • Response code checks
  • Response header checks
  • GET/POST on endpoints
  • CSRF tokens
  • Reporting and sane exit codes

smoke sh

Example

Checking if the Google Search home page works and contains the word "search":

#!/bin/bash

. smoke.sh

smoke_url_ok "http://google.com/"
    smoke_assert_body "search"
smoke_report

Running:

$ ./smoke-google
> http://google.com/
    [ OK ] 2xx Response code
    [ OK ] Body contains "search"
OK (2/2)

For a more advanced and complete example, see below.

Setup and usage

The recommended setup includes copying the smoke.sh file in the appropriate place and creating a new file in the same directory that you will write your tests in.

 $ tree -n
 .
 ├── smoke-google
 └── smoke.sh

In your file containing the tests, start with sourcing the smoke.sh file and end with calling smoke_report if you want a final report + appropriate exit code.

#!/bin/bash

. smoke.sh

# your test assertions go here

smoke_report

GET a URL and check the response code

The minimal smoke test will check if a URL returns with a 200 response code:

smoke_url_ok "http://google.com"

POST a URL and check the response code

A more advanced smoke test will POST data to a URL. Such a test can be used to for example check if the login form is functional:

smoke_form_ok "http://example.org/login" path/to/postdata

And the POST data (path/to/postdata):

username=smoke&password=test

Checking if the response body contains a certain string

By checking if the response body contains certain strings you can rule out that your server is serving a 200 OK, which seems fine, while it is actually serving the apache default page:

smoke_assert_body "Password *"

Checking if the response headers contain a certain string

By checking response headers, you can make sure to get the correct content type:

smoke_assert_headers "Content-Type: text/html; charset=utf-8"

Configuring a base URL

It is possible to setup a base URL that is prepended for each URL that is requested.

smoke_url_prefix "http://example.org"
smoke_url_ok "/"
smoke_url_ok "/login"

Overriding the host

If the server requires a certain host header to be set, override the host from the URL with

smoke_host "example.org"

To un-override, set it empty:

smoke_host ""

Overriding request headers

It's possible to set additional request headers, like X-Forwarded-Proto for local tests.

smoke_header "X-Forwarded-Host: orginal.example.org"
smoke_header "X-Forwarded-Proto: https"

Existing custom headers can be unset with remove_smoke_headers.

CSRF tokens

Web applications that are protected with CSRF tokens will need to extract a CSRF token from the responses. The CSRF token will then be used in each POST request issued by smoke.sh.

Setup an after response callback to extract the token and set it. Example:

#!/bin/bash

. smoke.sh

_extract_csrf() {
    CSRF=$(smoke_response_body | grep OUR_CSRF_TOKEN | grep -oE "[a-f0-9]{40}")

    if [[ $CSRF != "" ]]; then
        smoke_csrf "$CSRF" # set the new CSRF token
    fi
}

SMOKE_AFTER_RESPONSE="_extract_csrf"

When the CSRF token is set, smoke.sh will replace the string __SMOKE_CSRF_TOKEN__ in your post data with the given token:

username=smoke&password=test&csrf=__SMOKE_CSRF_TOKEN__

To get data from the last response, three helper functions are available:

smoke_response_code    # e.g. 200, 201, 400...
smoke_response_body    # raw body (html/json/...)
smoke_response_headers # list of headers

Advanced example

More advanced example showing all features of smoke.sh:

#!/bin/bash

BASE_URL="$1"

if [[ -z "$1" ]]; then
    echo "Usage:" $(basename $0) "<base_url>"
    exit 1
fi

. smoke.sh

_extract_csrf() {
    CSRF=$(smoke_response_body | grep OUR_CSRF_TOKEN | grep -oE "[a-f0-9]{40}")

    if [[ $CSRF != "" ]]; then
        smoke_csrf "$CSRF" # set the new CSRF token
    fi
}

SMOKE_AFTER_RESPONSE="_extract_csrf"

smoke_url_prefix "$BASE_URL"
smoke_host "example.org"

smoke_url_ok "/"
    smoke_assert_body "Welcome"
    smoke_assert_body "Login"
    smoke_assert_body "Password"
    smoke_assert_headers "Content-Type: text/html; charset=utf-8"
smoke_form_ok "/login" postdata/login
    smoke_assert_body "Hi John Doe"
    smoke_assert_headers "Content-Type: text/html; charset=utf-8"
smoke_report

API

function description
smoke_assert_body <string> assert that the body contains <string>
smoke_assert_code <code> assert that there was a <code> response code
smoke_assert_code_ok assert that there was a 2xx response code
smoke_assert_headers <string> assert that the headers contain <string>
smoke_csrf <token> set the csrf token to use in POST requests
smoke_form <url> <datafile> POST data on url
smoke_form_ok <url> <datafile> POST data on url and check for a 2xx response code
smoke_report prints the report and exits
smoke_response_body body of the last response
smoke_response_code code of the last response
smoke_response_headers headers of the last response
smoke_url <url> GET a url
smoke_url_ok <url> GET a url and check for a 2xx response code
smoke_url_prefix <prefix> set the prefix to use for every url (e.g. domain)
smoke_host <host> set the host header to use
smoke_header <header> set additional request header
smoke_tcp_ok <host> <port> open a tcp connection and check for a Connected response

smoke.sh's People

Contributors

asm89 avatar grobie avatar helsont avatar lpicanco avatar wjzijderveld avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

smoke.sh's Issues

Using on alpine

Hi, I am trying to use smoke.sh in my CI env which is based on alpine linux. (/bin/sh)

Unfortunately I am getting an error on line smoke.sh#176

.smoke/test.sh: .smoke/smoke.sh: line 176: syntax error: unexpected "(" (expecting "}")

Is there maybe a way to fix it for /bin/sh?

Assert response codes

Hi mate,

Nice work re your shell lib.

Would be nice to have helper function to assert response codes - my use/test case is to verify that 403 is returned and now have to use something like:

smoke_url "http://example.com/something/"
    code=`smoke_response_code`
    if [ $code -ne "403" ]; then
        _smoke_fail "Expected 403 but was $code."
    fi

which probably is not how I should use _smoke_fail ;)(

Capture body of failed tests

It would be interesting to store this body along with the counters, for debugging purposes like a smoke_debug function that would print what happened. Would be interested in a pull request for that?

Run with `set -e`

When I run with the bash -e option (stop at first command with a return code different from 0), the tests terminate at the first check because of this increment:

+ _smoke_success '2xx Response code'
+ REASON='2xx Response code'
+ _smoke_print_success '2xx Response code'
+ TEXT='2xx Response code'
+ echo '    [ OK ] 2xx Response code'
    [ OK ] 2xx Response code
+ ((  SMOKE_TESTS_RUN++  ))

I think this could be tweaked because incrementing 0 returns a 1 code which stops the script.

The example provided doesn't give the same response

I tried the example but only got the correct response code test.

> http://google.com/
    [ OK ] 2xx Response code

File content:

#!/bin/bash

. smoke.sh

smoke_url_ok "http://google.com/"
    smoke_assert_body "search"

System: Linux 3.8.0-19-generic #30-Ubuntu (Ubuntu 13.04 raring)

Any idea?

Use short form of grep's quiet flag

In one of our projects we are using Alpine Linux and the version of grep included does not recognize the long form of the quiet flag ('--quiet'). Perhaps it is better to use the shorthand form as that seems to be more supported (unconfirmed with other versions or OS though).

OS version: Alpine Linux v3.16
Linux: Linux 081aed2eda30 6.2.8-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 22 Mar 2023 22:52:35 +0000 x86_64 Linux

Output from our smoke test script running under Alpine Linux

grep: unrecognized option: quiet
BusyBox v1.35.0 (2022-08-01 15:14:44 UTC) multi-call binary.
Usage: grep [-HhnlLoqvsrRiwFE] [-m N] [-A|B|C N] { PATTERN | -e PATTERN... | -f FILE... } [FILE]...
Search for PATTERN in FILEs (or stdin)
	-H	Add 'filename:' prefix
	-h	Do not add 'filename:' prefix
	-n	Add 'line_no:' prefix
	-l	Show only names of files that match
	-L	Show only names of files that don't match
	-c	Show only count of matching lines
	-o	Show only the matching part of line
	-q	Quiet. Return 0 if PATTERN is found, 1 otherwise
	-v	Select non-matching lines
	-s	Suppress open and read errors
	-r	Recurse
	-R	Recurse and dereference symlinks
	-i	Ignore case
	-w	Match whole words only
	-x	Match whole lines only
	-F	PATTERN is a literal (not regexp)
	-E	PATTERN is an extended regexp
	-m N	Match up to N times per file
	-A N	Print N lines of trailing context
	-B N	Print N lines of leading context
	-C N	Same as '-A N -B N'
	-e PTRN	Pattern to match
	-f FILE	Read pattern from file

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.