Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
c96daca
Network Utility Tool in a separate folder. Yet to add specs.
rchougule May 29, 2020
4f3645b
unit test setup using mocha, chai and sinon. utils half covered. Util…
rchougule May 29, 2020
7ddf0c1
more tests for utils
rchougule May 29, 2020
f8fa072
spec for mac stats partial.
rchougule May 30, 2020
536fa9d
fixed minor and patch versions for dev deps
rchougule May 30, 2020
cb97f78
mac network stats unit test
rchougule May 30, 2020
99954d3
more specs and fixes
rchougule Jun 1, 2020
a93ffde
nock for mocking http requests. connectivity check without proxy tests.
rchougule Jun 1, 2020
4cb990f
connectivity checks specs with proxy cases and error case
rchougule Jun 1, 2020
a4ba616
specs for server done. win mem stats specs remain. dummy initializers…
rchougule Jun 2, 2020
3ce1015
windows mem stats specs add
rchougule Jun 2, 2020
ab17047
detecting win32 via regex for win systems
rchougule Jun 2, 2020
9edd094
comments across files and individual functions. CLI Command usage exp…
rchougule Jun 2, 2020
704542e
EOLs
rchougule Jun 2, 2020
735e977
npm start script
rchougule Jun 2, 2020
e69adbd
pkg downgrade to support node 4. added the executables for all platfo…
rchougule Jun 2, 2020
5d220ae
timeout increased for connectivity checks. readme added. cli help upd…
rchougule Jun 2, 2020
dc40734
readme updated for steps to build the executables
rchougule Jun 2, 2020
50f77c8
logging improved while starting the tool
rchougule Jun 3, 2020
859db8e
custom logs directory. improved args helper. specs added for the chan…
rchougule Jun 4, 2020
746cc06
better error messaging in case path for logs directory is invalid
rchougule Jun 4, 2020
13ea1ae
condition refactor for logs directory error
rchougule Jun 4, 2020
1a7f51e
helper for specs moved to testHelper. Better messaging while initiati…
rchougule Jun 7, 2020
02587ed
linter setup. readme update
rchougule Jun 7, 2020
7752471
EOF. Linter rule for EOF
rchougule Jun 7, 2020
f43f54c
build scripts in package.json. README update
rchougule Jun 7, 2020
8425060
nyc exclude folders
rchougule Jun 7, 2020
7095c03
retries for request fired by the tool. Yet to decide the status codes…
rchougule Jun 14, 2020
f8bb5bd
Migration
rchougule Jun 29, 2020
619f4d0
Merge branch from source into initial-release
rchougule Jun 29, 2020
3e47ca8
Migration cleanups and README updates
rchougule Jun 29, 2020
c9b15ec
README updated with how to use section
rchougule Jun 29, 2020
1c669ae
Custom header for debugging and usage check at BrowserStack. Added mo…
rchougule Jun 29, 2020
647dbb5
README update
rchougule Jun 29, 2020
e5b4efe
Logging improved with flow of events. Name updates.
rchougule Jun 30, 2020
8ceef78
README updated with logs type & explanation. CLI args help updated.
rchougule Jun 30, 2020
d6804a8
Note for Windows CPU stats
rchougule Jun 30, 2020
b932b3d
README update
rchougule Jun 30, 2020
21f36f5
Tags & their meanings update of logs.
rchougule Jun 30, 2020
5187b44
pre-push hook to run npm tests. build commands updated for ease.
rchougule Jun 30, 2020
6e3361f
added --version argument to check the version of the tool
rchougule Jul 1, 2020
7962c43
EOF for hook
rchougule Jul 1, 2020
d914beb
copy hooks for each git push
rchougule Jul 1, 2020
b6bf238
Tool's Proxy port via CLI arg. README update for the same. Specs adde…
rchougule Jul 1, 2020
54145ab
Added delay mechanism for retry for requests. specs around the same. …
rchougule Jul 1, 2020
66c5b41
Installation instruction updated
rchougule Jul 1, 2020
9b9bd0c
configurable timeout for requests fired by the tool. specs for the ti…
rchougule Jul 1, 2020
55a73cd
proxy-port check in expected range. tests for the same. collect netwo…
rchougule Jul 1, 2020
65244ee
moved all static messages to their constants. response error check.
rchougule Jul 2, 2020
2ecd7c7
camelCase naming consistency
rchougule Jul 2, 2020
f8c928d
rename node.js to requestsDebugger.js
rchougule Jul 2, 2020
6d746b5
test case for default ideal length
rchougule Jul 2, 2020
0c64d93
broke initLoggers into sub parts. Compatible with node 4.4.0. camelCa…
rchougule Jul 2, 2020
36a1f87
comment update for initLoggers
rchougule Jul 2, 2020
c63633d
comment update. lexical change for handler
rchougule Jul 2, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = {
"parserOptions": {
'sourceType': 'script',
'ecmaVersion': 5
},
"env": {
"node": true,
"commonjs": true,
"mocha": true,
},
"globals": {
"Promise": true
},
"extends": "eslint:recommended",
"rules": {
"indent": ["error", 2],
"linebreak-style": [ "error", "unix"],
"semi": ["error", "always"],
"eol-last": ["error", "always"]
},
"overrides": [{
"files": ["src/requestsDebugger.js", "src/commandLine.js", "test/**/*.test.js"],
"rules": {
"no-console": "off"
}
}]
};
110 changes: 110 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
RequestsDebuggerLogs

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov

# Coverage directory used by tools like istanbul
coverage
*.lcov

# nyc test coverage
.nyc_output

# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt

# Bower dependency directory (https://bower.io/)
bower_components

# node-waf configuration
.lock-wscript

# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
typings/

# TypeScript cache
*.tsbuildinfo

# Optional npm cache directory
.npm

# Optional eslint cache
.eslintcache

# Microbundle cache
.rpt2_cache/
.rts2_cache_cjs/
.rts2_cache_es/
.rts2_cache_umd/

# Optional REPL history
.node_repl_history

# Output of 'npm pack'
*.tgz

# Yarn Integrity file
.yarn-integrity

# dotenv environment variables file
.env
.env.test

# parcel-bundler cache (https://parceljs.org/)
.cache

# Next.js build output
.next

# Nuxt.js build / generate output
.nuxt
dist

# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and *not* Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public

# vuepress build output
.vuepress/dist

# Serverless directories
.serverless/

# FuseBox cache
.fusebox/

# DynamoDB Local files
.dynamodb/

# TernJS port file
.tern-port

# Executables
RequestsDebugger-Mac
RequestsDebugger.exe
RequestsDebugger-Linux
98 changes: 96 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,96 @@
# requests-debugger
Tool for debugging client side failure of requests, leading to requests getting dropped or not reaching BrowserStack. For internal reference : https://browserstack.atlassian.net/wiki/spaces/ENG/pages/1561081359/Network+Utility+Tool
## Requests Debugger
### Tool for debugging client side failure of requests, leading to requests getting dropped or not reaching BrowserStack.

## Features
- Proxy Server to intercept requests fired by client bindings to keep track of their flow.
- Connectivity Checker : To check for the reachability of BrowserStack components, i.e. Rails & Hub.
- Multi-Platform Stats Compatibility : Ability to collect stats of CPU, Network & Memory Stats.
- Retry Mechanism in case a request fails at the client side

## How to run
- Code
- Install all the required packages: `npm install`
- Start Requests Debugger with the required arguments: `npm run start -- <args>`.
- Supported `args`:
- `--port <port>`: Port on which the Requests Debugger Tool's Proxy will run. Default: 9687
- `--proxy-host <hostname>`: Hostname of the Upstream Proxy
- `--proxy-port <port>`: Port of the Upstream Proxy. Default: 3128 (if hostname is provided)
- `--proxy-user <username>`: Username for auth of the Upstream Proxy
- `--proxy-pass <password>`: Password for auth of the Upstream Proxy. Default: empty (if username is provided)
- `--retry-delay <milliseconds>`: Delay for the retry of a failed request. Default: 1000ms
- `--request-timeout <milliseconds>`: Hard timeout for killing the requests being fired from the tool before receiving any response. Default: 260000ms.
- `--logs-path <relative/absolute path>`: Directory where the 'RequestsDebuggerLogs' folder will be created for storing logs. Default: Current Working Directory
- `--del-logs`: Deletes any existing logs from the RequestsDebuggerLogs/ directory and initializes new files for logging
- `--help`: Help for Requests Debugger Tool
- `--version`: Version of the Requests Debugger Tool
- Executable
- Run the Platform Specific executable via terminal/cmd:
- Mac: `./RequestsDebugger-Mac <args>`
- Linux: `./RequestsDebugger-Linux <args>`
- Windows: `RequestsDebugger.exe <args>`

## How to use
- Since the tool acts like a proxy, you will have to set the proxy to be used by your client binding to `localhost:9687`. i.e.
- For Java:
- ```
System.getProperties().put("http.proxyHost", "localhost");
System.getProperties().put("http.proxyPort", "9687");
```
- For Ruby:
- Set your system's env variable `http_proxy=localhost:9687` and Ruby's Selenium Client Binding will pick the value. Or,
- Run you test by giving the environment variable to your command itself, i.e. `http_proxy=localhost:9687 ruby <your_script.rb>`
- Similarly, you can also set proxy for other client bindings.

## Steps to build the executables
- Linux
- `npm run build:linux`
- Mac OS X
- `npm run build:mac`
- Windows
- `npm run build:win`

## What each log file consists of?
- `Connectivitiy.log`
- It consists the logs of all the connectivity checks which were performed in terms of reachability with BrowserStack componenets, i.e. Hub and Rails.
- The report includes HTTP & HTTPS requests by passing the requests via any upstream proxy (if provided).
- New checks are performed whenever a request fails.
- `CPUStats.log`
- It consists of the load and usage stats of user's CPU while booting up the Requests Debugger Tool. It lists down the top 10 processes which were using the highest CPU at that moment. Note: For Windows, it only includes the `loadPercentage` at that moment.
- `MemStats.log`
- It consists of the memory stats of the user's machine while booting up the tool. It includes:
- Total Memory
- Free Memory
- Used Memory
- Swap Total
- Swap Free
- Swap Used
- `NetworkStats.log`
- It consists the list of connections/sockets being established/listening via the user's machine.
- It also includes the report of ping checks with Hub & Rails.
- New stats are appended whenever a request fails.
- `Requests.log`
- It includes the logs of requests being passed via the Requests Debugger Tool.
- Example Logs:
- ```
TIMESTAMP_IN_UTC [#2::UNIQUE_IDENTIFIER] [Request Start] [INFO] POST http://<URL>/wd/hub/status, {"headers":{"......."}}
TIMESTAMP_IN_UTC [#2::UNIQUE_IDENTIFIER] [Request End] [INFO] POST http://<URL>/wd/hub/status, {"data":"{\"key\": \"value\"}"}
TIMESTAMP_IN_UTC [#2::UNIQUE_IDENTIFIER] [Tool Request - Retries Left: 1] [INFO] POST http://<URL>/wd/hub/status, {"method":"POST","headers":{".......","Proxy-Authorization":"Basic AaBbCcDdEeFfGg==","X-Requests-Debugger":"2::UNIQUE_IDENTIFIER"},"host":"<EXTERNAL_PROXY_URL>","port":"3130","path":"http://<URL>/wd/hub/status","data":"{\"key\": \"value\"}"}
TIMESTAMP_IN_UTC [#2::UNIQUE_IDENTIFIER] [Tool Request - Retries Left: 1] [ERROR] POST http://<URL>/wd/hub/status, {"errorMessage":"Error: getaddrinfo ENOTFOUND <EXTERNAL_PROXY_URL> <EXTERNAL_PROXY_URL>:3130"}
TIMESTAMP_IN_UTC [#2::UNIQUE_IDENTIFIER] [Tool Request - Retries Left: 0] [ERROR] POST http://<URL>/wd/hub/status, {"errorMessage":"Error: getaddrinfo ENOTFOUND <EXTERNAL_PROXY_URL> <EXTERNAL_PROXY_URL>:3130"}
TIMESTAMP_IN_UTC [#2::UNIQUE_IDENTIFIER] [Response End] [ERROR] POST http://<URL>/wd/hub/status, Status Code: 500, {"message":"Error: getaddrinfo ENOTFOUND <EXTERNAL_PROXY_URL> <EXTERNAL_PROXY_URL>:3130. Request Failed At Requests Debugger","error":"Request Failed At Requests Debugger"}
- Tags & their meaning:
- **TIMESTAMP_IN_UTC** : Timestamp of each event in UTC.
- **#2** : This represents the `nth` request which the tool served from the time it was started.
- **UNIQUE_IDENTIFIER** : `uuid` for the request. This is used in `X-Requests-Debugger` custom header for usage & debugging at BrowserStack's end.
- **Request Start** : Client request entering the Requests Debugger Tool.
- **Request End** : This is logged when the client request is finished, i.e. in case of `POST` request, when the client request has pushed all the data.
- **Tool Request - Retries Left: X** : Request which was fired from the tool for the respective client request. It also mentions the retries left for the request. Max retries = 1. A request is retried in case it fails at the tool itself, i.e `ENOTFOUND` etc.
- **Response End** : This specifies the response which was finally sent to the client.
- `RDT_Error.log`
- This is to log any unexpected errors which might occur while using the tool.


## Note
- The tool is written in a manner to make it compatible with Node 4.4.0.
- `npm test` sets up a server which runs on port 8787.
- Building the executables require Node >=4.9.1.
95 changes: 95 additions & 0 deletions config/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
module.exports.VERSION = '1.0.0';
module.exports.HUB_STATUS_URL = 'http://hub-cloud.browserstack.com/wd/hub/status';
module.exports.RAILS_AUTOMATE = 'http://automate.browserstack.com';
module.exports.CONNECTIVITY_REQ_TIMEOUT = 30000;
module.exports.DEFAULT_PROXY_PORT = 3128;
module.exports.MAX_RETRIES = 1;
module.exports.LOGS_FOLDER = 'RequestsDebuggerLogs';
module.exports.PORTS = {
MAX: 65535,
MIN: 1
};

module.exports.LOGS = Object.freeze({
NETWORK: 'NetworkStats.log',
CPU: 'CPUStats.log',
MEM: 'MemStats.log',
REQUESTS: 'Requests.log',
CONNECTIVITY: 'Connectivity.log',
ERROR: 'RDT_Error.log'
});

module.exports.RdGlobalConfig = {
RETRY_DELAY: 1000, // in ms
RD_HANDLER_PORT: process.env.NODE_ENV === 'test' ? 8787 : 9687,
CLIENT_REQ_TIMEOUT: 260000, // in ms
};

module.exports.COMMON = Object.freeze({
PING_HUB: 'ping -c 5 hub-cloud.browserstack.com',
PING_AUTOMATE: 'ping -c 5 automate.browserstack.com'
});

module.exports.MAC = Object.freeze({
TCP_LISTEN_ESTABLISHED: 'lsof -PiTCP',
TOP_3_SAMPLES: 'top -n 10 -l 3 -stats pid,command,cpu,cpu_others,time,threads,ports,mem,vsize,pgrp,ppid,cycles',
SWAP_USAGE: 'sysctl -n vm.swapusage'
});

module.exports.LINUX = Object.freeze({
TCP_LISTEN_ESTABLISHED: 'lsof -PiTCP',
TOP_3_SAMPLES: 'top -bn 3',
PROC_MEMINFO: '/proc/meminfo'
});

module.exports.WIN = Object.freeze({
NETSTAT_TCP: 'netstat -anosp tcp',
NETSTAT_ROUTING_TABLE: 'netstat -r',
IPCONFIG_ALL: 'ipconfig /all',
SWAP_USAGE: 'pagefile get AllocatedBaseSize, CurrentUsage', // this is a WMIC command. Prefix with WMIC Path
PING_HUB: 'ping -n 5 hub-cloud.browserstack.com',
PING_AUTOMATE: 'ping -n 5 automate.browserstack.com',
LOAD_PERCENTAGE: 'cpu get loadpercentage', // prefix wmic path
});

module.exports.ERROR_CODES = Object.freeze({
EEXIST: 'EEXIST'
});

module.exports.TOPICS = Object.freeze({
LINUX_MEM: 'Linux-Mem',
MAC_MEM: 'Mac-Mem',
WIN_MEM: 'Win-Mem',
TOOL_REQUEST_WITH_RETRIES: 'Tool Request - Retries Left: ',
TOOL_RESPONSE_ERROR: 'Tool Response',
CLIENT_REQUEST_WITH_RETRIES: 'Request - Retries Left: ',
CLIENT_REQUEST_END: 'Request End',
CLIENT_REQUEST_START: 'Request Start',
CLIENT_RESPONSE_END: 'Response End',
NO_TOPIC: 'NO_TOPIC',
UNEXPECTED_ERROR: 'UNEXPECTED_ERROR'
});

module.exports.STATIC_MESSAGES = Object.freeze({
STARTING_TOOL: 'Starting Requests Debugger Tool',
CHECK_CPU_STATS: 'Stats : Checking CPU Stats',
CHECK_NETWORK_STATS: 'Stats : Checking Network Stats',
CHECK_MEMORY_STATS: 'Stats : Checking Memory Stats',
CHECK_CONNECTIVITY: 'Checks : Checking Connectivity With BrowserStack',
ERR_STARTING_TOOL: 'Error in starting Requests Debugger Tool Proxy: ',
TOOL_STARTED_ON_PORT: 'Requests Debugger Tool Proxy Started on Port: ',
CPU_STATS_COLLECTED: 'Stats : Initial CPU Stats Collected',
NETWORK_STATS_COLLECTED: 'Stats : Initial Network Stats Collected',
MEMORY_STATS_COLLECTED: 'Stats : Initial Memory Stats Collected',
CONNECTIVITY_CHECKS_DONE: 'Checks : Connectivity Checks Performed with BrowserStack',
NO_REPORT_GENERATED: 'COULD NOT GENERATE REPORT FOR : ',
REQ_TIMED_OUT: 'Request Timed Out. Did not get any response for ',
REQ_FAILED_MSG: 'Request Failed At Requests Debugger',
BASE_STATS_DESC: 'Base Object for System & Network Stats',
CPU_STATS_NOT_IMPLEMENTED: 'CPU Stats Not Yet Implemented',
MEM_STATS_NOT_IMPLEMENTED: 'Mem Stats Not Yet Implemented',
NETWORK_STATS_NOT_IMPLEMENTED: 'Network Stats Not Yet Implemented',
LINUX_STATS_DESC: 'System and Network Stats for Linux',
MAC_STATS_DESC: 'System and Network Stats for Mac',
WIN_STATS_DESC: 'System and Network Stats for Windows'
});
10 changes: 10 additions & 0 deletions hooks/pre-push
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

# copy the hook again
npm run copyhooks

# run the npm tests
npm test

# return the 'npm test' exit code
exit $?
Loading