Skip to content

Commit

Permalink
add spec support for Node 13 and 14
Browse files Browse the repository at this point in the history
  • Loading branch information
Danielle Adams committed Apr 27, 2020
1 parent e05a4d7 commit ddb2af6
Show file tree
Hide file tree
Showing 12 changed files with 240 additions and 3 deletions.
25 changes: 25 additions & 0 deletions spec/ci/node_13_metrics_spec.rb
@@ -0,0 +1,25 @@
require_relative '../spec_helper'

describe "Node Metrics for v13.x" do
context "test metrics for Node v13.x app" do
let(:app) {
Hatchet::Runner.new(
"spec/fixtures/repos/node-13-metrics",
config: {
"HEROKU_METRICS_URL" => "http://localhost:3000",
"METRICS_INTERVAL_OVERRIDE" => "10000"
}
)
}

it "should deploy" do
app.deploy do |app|
data = successful_json_body(app)
expect(data["gauges"]["node.eventloop.delay.ms.max"]).to be >= 2000
expect(data["counters"]["node.gc.collections"]).to be >= 0
expect(data["counters"]["node.gc.young.collections"]).to be >= 0
expect(data["counters"]["node.gc.old.collections"]).to be >= 0
end
end
end
end
16 changes: 16 additions & 0 deletions spec/ci/node_13_spec.rb
@@ -0,0 +1,16 @@
require_relative '../spec_helper'

describe "Hello World for Node v13.x" do
context "a single-process Node v13.x app" do
let(:app) {
Hatchet::Runner.new("spec/fixtures/repos/node-13")
}

it "should deploy successfully" do
app.deploy do |app|
expect(successful_body(app).strip).to eq("Hello, world!")
end
end

end
end
25 changes: 25 additions & 0 deletions spec/ci/node_14_metrics_spec.rb
@@ -0,0 +1,25 @@
require_relative '../spec_helper'

describe "Node Metrics for v14.x" do
context "test metrics for Node v14.x app" do
let(:app) {
Hatchet::Runner.new(
"spec/fixtures/repos/node-14-metrics",
config: {
"HEROKU_METRICS_URL" => "http://localhost:3000",
"METRICS_INTERVAL_OVERRIDE" => "10000"
}
)
}

it "should deploy" do
app.deploy do |app|
data = successful_json_body(app)
expect(data["gauges"]["node.eventloop.delay.ms.max"]).to be >= 2000
expect(data["counters"]["node.gc.collections"]).to be >= 0
expect(data["counters"]["node.gc.young.collections"]).to be >= 0
expect(data["counters"]["node.gc.old.collections"]).to be >= 0
end
end
end
end
16 changes: 16 additions & 0 deletions spec/ci/node_14_spec.rb
@@ -0,0 +1,16 @@
require_relative '../spec_helper'

describe "Hello World for Node v14.x" do
context "a single-process Node v14.x app" do
let(:app) {
Hatchet::Runner.new("spec/fixtures/repos/node-14")
}

it "should deploy successfully" do
app.deploy do |app|
expect(successful_body(app).strip).to eq("Hello, world!")
end
end

end
end
1 change: 1 addition & 0 deletions spec/fixtures/repos/node-14-metrics/Procfile
@@ -0,0 +1 @@
web: node index.js
72 changes: 72 additions & 0 deletions spec/fixtures/repos/node-14-metrics/index.js
@@ -0,0 +1,72 @@
#!/usr/bin/env node

const http = require('http');
const EventEmitter = require('events');

const PORT = process.env.PORT || 5000;
const Events = new EventEmitter();

// This will block the event loop for ~lengths of time
function blockCpuFor(ms) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log(`blocking the event loop for ${ms}ms`);
let now = new Date().getTime();
let result = 0
while(true) {
result += Math.random() * Math.random();
if (new Date().getTime() > now + ms)
break;
}
resolve();
}, 100);
});
}

function getNextMetricsEvent() {
return new Promise((resolve, reject) => Events.once('metrics', resolve));
}

const server = http.createServer((req, res) => {
// wait for the next metrics event
getNextMetricsEvent()
.then(blockCpuFor(2000))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
.then(blockCpuFor(100))
// gather the next metrics data which should include these pauses
.then(getNextMetricsEvent())
.then(data => {
res.setHeader('Content-Type', 'application/json');
res.end(data);
})
.catch(() => {
res.statusCode = 500;
res.end("Something went wrong");
});
});

server.listen(PORT, () => console.log(`Listening on ${PORT}`));

// Create a second server that intercepts the HTTP requests
// sent by the metrics plugin
const metricsListener = http.createServer((req, res) => {
if (req.method == 'POST') {
let body = '';
req.on('data', (data) => body += data);
req.on('end', () => {
res.statusCode = 200;
res.end();
Events.emit('metrics', body)
});
}
});

metricsListener.listen(3000, () => console.log('Listening for metrics on 3000'));
11 changes: 11 additions & 0 deletions spec/fixtures/repos/node-14-metrics/package.json
@@ -0,0 +1,11 @@
{
"name": "node-metrics-test-app",
"version": "1.0.0",
"engines": {
"node": "14.x"
},
"main": "index.js",
"license": "MIT",
"devDependencies": {},
"dependencies": {}
}
1 change: 1 addition & 0 deletions spec/fixtures/repos/node-14/Procfile
@@ -0,0 +1 @@
web: node index.js
3 changes: 3 additions & 0 deletions spec/fixtures/repos/node-14/app.json
@@ -0,0 +1,3 @@
{
"name": "hello-world"
}
46 changes: 46 additions & 0 deletions spec/fixtures/repos/node-14/index.js
@@ -0,0 +1,46 @@
#!/usr/bin/env node

const http = require('http');
const crypto = require('crypto');

const PORT = process.env.PORT || 5000;

// This will block the event loop for ~lengths of time
function blockCpuFor(ms) {
var now = new Date().getTime();
var result = 0
while(true) {
result += Math.random() * Math.random();
if (new Date().getTime() > now +ms)
return;
}
}

// block the event loop for 100ms every second
setInterval(() => {
blockCpuFor(100);
}, 1000)

// block the event loop for 1sec every 30 seconds
setInterval(() => {
blockCpuFor(1000);
}, 30000)

// Allocate and erase memory on an interval
let store = [];

setInterval(() => {
store.push(crypto.randomBytes(1000000).toString('hex'));
}, 500);

setInterval(() => {
store = [];
}, 60000);

const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end("Hello, world!");
})

server.listen(PORT, () => console.log(`Listening on ${PORT}`));
21 changes: 21 additions & 0 deletions spec/fixtures/repos/node-14/package.json
@@ -0,0 +1,21 @@
{
"name": "hello-world",
"version": "1.0.0",
"engines": {
"node": "14.x"
},
"scripts": {
"prettify": "prettier --single-quote --trailing-comma all --write 'bin/*' 'src/**/*.js'",
"test": "jest --silent",
"dev": "nodemon --watch . --watch src/* src/index.js",
"build": "echo NODE_OPTIONS: $NODE_OPTIONS"
},
"main": "index.js",
"license": "MIT",
"devDependencies": {
"jest": "^19.0.2",
"nodemon": "^1.19.4",
"prettier": "^0.22.0"
},
"dependencies": {}
}
6 changes: 3 additions & 3 deletions spec/spec_helper.rb
Expand Up @@ -63,12 +63,12 @@ def resolve_all_supported_node_versions(options = {})
result = run!("#{resolve_binary_path} list node")
list = result.lines().map { |line| line.split(' ').first }
list.select do |n|
SemVersion.new(n).satisfies?('>= 6.0.0')
SemVersion.new(n).satisfies?('>= 10.0.0')
end
end

def version_supports_metrics(version)
SemVersion.new(version).satisfies?('>= 8.0.0') && SemVersion.new(version).satisfies?('< 14.0.0')
SemVersion.new(version).satisfies?('>= 10.0.0') && SemVersion.new(version).satisfies?('< 15.0.0')
end

def get_test_versions
Expand All @@ -77,7 +77,7 @@ def get_test_versions
elsif ENV['TEST_ALL_NODE_VERSIONS'] == 'true'
versions = resolve_all_supported_node_versions()
else
versions = resolve_node_version(['6.x', '8.x', '9.x', '10.x', '11.x'])
versions = resolve_node_version(['10.x', '12.x', '13.x', '14.x'])
end
puts("Running tests for Node versions: #{versions.join(', ')}")
versions
Expand Down

0 comments on commit ddb2af6

Please sign in to comment.