Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add spec support for Node 13 and 14 #766

Merged
merged 2 commits into from
Apr 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
- Up feature flag test groups ([#758](https://github.com/heroku/heroku-buildpack-nodejs/pull/758))
- Add Heroku-20 to the Travis test matrix ([#763](https://github.com/heroku/heroku-buildpack-nodejs/pull/763))
- Add Node 14 plugin and rebuild 10, 12, and 13; Remove rebuilding of 8, 9, and 11 ([#767](https://github.com/heroku/heroku-buildpack-nodejs/pull/767))
- Add spec support for Node 13 and 14 ([#766](https://github.com/heroku/heroku-buildpack-nodejs/pull/766))

## v170 (2020-03-31)
- Bump rake from 12.3.1 to 12.3.3 ([#742](https://github.com/heroku/heroku-buildpack-nodejs/pull/742))
Expand Down
25 changes: 25 additions & 0 deletions spec/ci/node_13_metrics_spec.rb
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: node index.js
72 changes: 72 additions & 0 deletions spec/fixtures/repos/node-14-metrics/index.js
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: node index.js
3 changes: 3 additions & 0 deletions spec/fixtures/repos/node-14/app.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"name": "hello-world"
}
46 changes: 46 additions & 0 deletions spec/fixtures/repos/node-14/index.js
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
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