npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

cuchito

v1.0.2

Published

proxy that multiplies the requests, record the sesion, and replays it

Downloads

1

Readme

cuchito

TitM (test in the middle) - made easy

cuchito-logo

WARNING

This software is under intense development, this documentation it's not stable at all. Everithing could change.

Do not use in production. Use it to try out the concept, to give feedback and to help with the development.

What is cuchito?

Cuchito is a test in the middle tool that helps developers, QAs and devops, in their daily tasks with a complete set of helpful features:

  • Manual stress test: Connect cuchito between the front and the back, and make it multiply your API calls as many times as you need.
  • Automated stress test: Save manual stress sessions so they can run later as unatended automated stress tests.
  • API schema validation: Use @hapi/joi schema validations in the requests or responses to catch bugs
  • API test: write tests easier than ever, and run then manually or automatically.
  • API mocking: Replace or mutate request and responses, to try new features or edge cases for both the front and the back.
  • re-routing: Re-route the paths, so you can merge different servers, environment, versions and endpoints in one API.
  • Real time config reload: Change your session configuration on the fly.

Quick guides

First steps

Initialize a cuchito project

npm init cuchito foo
cd foo

Edit the file named cuchito.js to:

  • set the field host to point to the API you want to stress.
  • set the IP and port you want your cuchito server to listen to.

Start a a manual session

npm start

Manual sessions proxies the API.

Eventhough the requests and responses can be multiplied, mutated, validated, tested, logged, and re-routed, cuchito works transparentely so any client should will as expected.

You just need to connect the client to the ip and port that you has been set in ./cuchito.js.

Run a saved session

npm test

Replay a sessions to send the saved requests to the host, in mostly the same fashion (multiplying, mutating, validating, testing, loging, and/or rerouting).

There are two differences:

  • Requests are not validated nor tested, only responses.
  • If any response validation or test fails, the reproduction stops with an error.

Basic manual Stress Test

Edit the file ./cuchito.js

  • config the request multiplication:
    • add the methods don't you want to multiply to the skipMethod object, as truthy.
    • count sets the amount of times each incoming request will be sent to the host
    • interval sets the waiting milliseconds between those extra request
...
  multiply: {
    count: 50,
    interval: 500,
    skipMethods: {
      'POST': 1,
      'PUT': 1,
      'DELETE': 1
    },
  },
...

This example configures cuchito to resend any request 50 times, in intervals of 500 milliseconds, skipping those whose method are POST, PUT or DELETE.

Basic automated stress tests

Unless you have changed the record configuration, every manual stress test you have done has been recorded.

These recorded sessions can be replayed with the following command:

npm test

new saved session does not replace or overwrite the current save session, but merge into it.

Please be aware that all recorded sessions would be reproduced simultaneously.

Basic forensics

cuchito dumps log files with the whole request and response, for each not cloned requests.

This logs are stored in both modes, manual an automated.

The file name is a csv row, with the next: timestamp, method, path, status, test result. For instance: ./logs/1592566705414,GET,⁄foo⁄bar?baz=qux,200,ok.yml

The file is a yml with the fields request, response, and optionally originalRequest, originalResponse, error and logs

request:
  path: /foo/bar?baz=qux
  params:
    fooId: bar
  query:
    baz: qux
  headers:
    content-type: application/json
  method: GET
  body: {}
response:
  headers:
    content-type: application/json; charset=utf-8
  status: 200
  body:
    result: ok
    code: 200

We will learn about the optional fields in the sections about mutations, advanced tests, and advanced logs.

Request schema validation

When you are running a manual session (and only in manual sessions), you can validate the incoming requests.

In the folder ./endpoints create a test.js file in a path that mimics the endpoint's route and method you want to test. For instance ./endpoints/foo/bar/POST/test.js

You can also set up dinamic urls, wrapping the parameter name with brackets, like ./endpoints/foo/[fooId]/PUT/test.js

To validate the schema of the request this file needs to export a @hapi/joi object as requestSchema

const joi = require('@hapi/joi');

exports.requestSchema = joi.object({
  headers: joi.object(
    'content-type': joi.valid('application/json'),
  ),
  body: ...
  params: ...,
  query: ...,
})

If the request's body is json and the content type is application/json, body will be a javascript object. Otherwise it will be a string.

params is an object with the route params. So if the file is ./endpoints/foo/[fooId]/PUT/test.js and the request is PUT /foo/bar params will be { foodId: 'bar' }

query is an object with the query params So if thethe request is PUT /foo/bar?baz=qux query will be { baz: 'qux' }

No coercion is done, the values in params and query are always strings.

The validation errors will show up red in the console. The session will not stop, and the request is not skiped. It will reach the host.

On top of that, the logs and recordings of the requests whose validation has failed will have the extension .error.yml instead of .ok.yml

Response schema validation

The response schema validation works much like the request schema validation.

The differences are:

  • The @hapi/joi validations must be exported as responseSchema, and obviously the same .../test.js can export request validations and respons evalidations.

  • The response schema validation runs on both modes, manual and automated.

  • Automated sessions stop when any response schema validation fails.

const joi = require('@hapi/joi');

exports.responseSchema = joi.object({
  status: joi.valid(200),
  headers: ...,
  body: ...,
})

If the body is json and the content type is application/json, body will be a javascript object. Otherwise it will be a string.

advanced guides

configuration

The main config file is ./cuchito.js

This javascript is executed, in can includes any logic you need to create dinamic configurations.

Just export a javascript object with all the configuration you need.

  • host: Host to reverse-proxy the request to
  • ip: Ip to listen to
  • port: port to listen to
  • maxTimeSpan: Send an error to the client when the request takes more than maxTimeSpan milliseconds. 0 or falsy to disable the feature and wait forever.

If your configuration depends on some asynchronous source, or it could changes on run time you have to include a oChange function that accept a handler, that you can call with the actualized configuration as many times as you want.

You can disable the logging by removing the field logs in the file cuchito.js or by renaming it to logs_ for instance.

You can configure the logs independently for each endpoint or endpoint groups, by creating a conf.js in the endpoints folder in a path that mimics the endpoints' route you want to configure.

The fields of the ./endpoints/foo/[fooId]/GET/conf.js overwrite the fields of the cuchito.js file.

skip-all log-some strategy.

You can disable all the logs in ./cuchito.js and enable it for some endpoint in ./endpoints/some/endpoint/GET/conf.js

log-all skip-some strategy

You can disable all the logs in ./cuchito.js and enable it for some endpoint in ./endpoints/some/endpoint/GET/conf.js

Mutate requests

Mutate responses