Skip to content

Commit 11c1ccf

Browse files
authored
Merge pull request #242 from applandinc/ci/faster-testing
Faster testing in CI
2 parents cc42f91 + 6844d5e commit 11c1ccf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+235
-999
lines changed

.travis.yml

+4-16
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
language: ruby
22
dist: bionic
3+
cache:
4+
- bundle
5+
- yarn
36

47
# NB: if you update the ruby versions here, you also need to update
58
# them in the Rakefile.
@@ -9,25 +12,10 @@ rbenv:
912
- 3.0
1013
- 3.1
1114

12-
addons:
13-
apt:
14-
packages:
15-
# https://docs.travis-ci.com/user/docker/#installing-a-newer-docker-version
16-
- docker-ce
17-
1815
services:
19-
- docker
16+
- postgresql
2017

2118
before_install:
22-
- sudo apt-get update && sudo apt-get install apt-transport-https ca-certificates -y && sudo update-ca-certificates
23-
# see https://blog.travis-ci.com/docker-rate-limits
24-
# and also https://www.docker.com/blog/what-you-need-to-know-about-upcoming-docker-hub-rate-limiting/
25-
# if we do not use authorized account,
26-
# the pulls-per-IP quota is shared with other Travis users
27-
- >
28-
if [ ! -z "$DOCKERHUB_PASSWORD" ] && [ ! -z "$DOCKERHUB_USERNAME" ]; then
29-
echo "$DOCKERHUB_PASSWORD" | docker login -u "$DOCKERHUB_USERNAME" --password-stdin ;
30-
fi
3119
- |
3220
nvm install --lts \
3321
&& nvm use --lts \

Dockerfile.appmap

-5
This file was deleted.
File renamed without changes.

README.md

+14-44
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ Visit the [AppMap for Ruby](https://appland.com/docs/reference/appmap-ruby.html)
2828

2929
**Configuration**
3030

31-
*appmap.yml* is loaded into an `AppMap::Config`.
31+
*appmap.yml* is loaded into an `AppMap::Config`.
3232

3333
**Hooking**
3434

@@ -39,7 +39,7 @@ method with calls that record the parameters and return value.
3939
**Builtins**
4040

4141
`Hook` begins by iterating over builtin classes and modules defined in the `Config`. Builtins include code
42-
like `openssl` and `net/http`. This code is not dependent on any external libraries being present, and
42+
like `openssl` and `net/http`. This code is not dependent on any external libraries being present, and
4343
`appmap` cannot guarantee that it will be loaded before builtins. Therefore, it's necessary to require it and
4444
hook it by looking up the classes and modules as constants in the `Object` namespace.
4545

@@ -81,50 +81,20 @@ The fixture apps in `test/fixtures` are plain Ruby projects that exercise the ba
8181

8282
The fixture apps in `spec/fixtures` are simple Rack, Rails5, and Rails6 apps.
8383
You can use them to interactively develop and test the recording features of the `appmap` gem.
84-
These fixture apps are more sophisticated than `test/fixtures`, because they include additional
85-
resources such as a PostgreSQL database.
84+
These fixture apps are more sophisticated than `test/fixtures`, because they include additional
85+
resources such as a PostgreSQL database. Still, you can simply enter the fixture directory and `bundle`.
8686

87-
To build the fixture container images, first run:
87+
If you don't have PostgreSQL on the local (default) socket, you can export `DATABASE_URL` to
88+
point to the database server you want to use.
8889

89-
```sh-session
90-
$ bundle exec rake build:fixtures:all
91-
```
92-
93-
This will build the `appmap.gem`, along with a Docker image for each fixture app.
94-
95-
Then move to the directory of the fixture you want to use, and provision the environment.
96-
In this example, we use Ruby 2.6.
97-
98-
```sh-session
99-
$ export RUBY_VERSION=2.6
100-
$ docker-compose up -d pg
101-
$ sleep 10s # Or some reasonable amount of time
102-
$ docker-compose run --rm app ./create_app
103-
```
90+
You can launch a database like this:
10491

105-
Now you can start a development container.
106-
107-
```sh-session
108-
$ docker-compose run --rm -v $PWD:/app -v $PWD/../../..:/src/appmap-ruby app bash
109-
Starting rails_users_app_pg_1 ... done
110-
root@6fab5f89125f:/app# cd /src/appmap-ruby
111-
root@6fab5f89125f:/src/appmap-ruby# rm ext/appmap/*.so ext/appmap/*.o
112-
root@6fab5f89125f:/src/appmap-ruby# bundle
113-
root@6fab5f89125f:/src/appmap-ruby# bundle exec rake compile
114-
root@6fab5f89125f:/src/appmap-ruby# cd /src/app
115-
root@6fab5f89125f:/src/app# bundle config local.appmap /src/appmap-ruby
116-
root@6fab5f89125f:/src/app# bundle
11792
```
118-
119-
At this point, the bundle is built with the `appmap` gem located in `/src/appmap`, which is volume-mounted from the host.
120-
So you can edit the fixture code and the appmap code and run test commands such as `rspec` in the container.
121-
For example:
122-
123-
```sh-session
124-
root@6fab5f89125f:/src/app# APPMAP=true bundle exec rspec
125-
Configuring AppMap from path appmap.yml
126-
....
127-
128-
Finished in 0.07357 seconds (files took 2.1 seconds to load)
129-
4 examples, 0 failures
93+
➜ docker-compose -p appmap-ruby up -d
94+
... stuff
95+
➜ docker-compose ps pg
96+
Name Command State Ports
97+
-----------------------------------------------------------------------------------------
98+
appmap-ruby_pg_1 docker-entrypoint.sh postgres Up (healthy) 0.0.0.0:59134->5432/tcp
99+
➜ export DATABASE_URL=postgres://postgres@localhost:59134
130100
```

README_CI.md

-7
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44
* `GEM_HOST_API_KEY`: rubygems API key
55
* `GEM_ALTERNATIVE_NAME` (optional): used for testing of CI flows,
66
to avoid publication of test releases under official package name
7-
* `DOCKERHUB\_USERNAME`, `DOCKERHUB_PASSWORD`: optional dockerhub credentials,
8-
to avoid throttling of dockerhub anonymous pulls
9-
10-
Note: for security reasons, it's better to use dedicated (not personal)
11-
Dockerhub account,
12-
and also use [access tokens](https://docs.docker.com/docker-hub/access-tokens/)
13-
instead of primary password
147

158
# Release command
169

Rakefile

+12-150
Original file line numberDiff line numberDiff line change
@@ -1,165 +1,29 @@
11
$: << File.join(__dir__, 'lib')
2-
require 'appmap/version'
3-
GEM_VERSION = AppMap::VERSION
4-
5-
# Make sure the local version is not behind the one on
6-
# rubygems.org (it's ok if they're the same).
7-
#
8-
# If it is behind, the fixture images won't get updated with the gem
9-
# built from the local source, so you'll wind up testing the rubygems
10-
# version instead.
11-
unless ENV['SKIP_VERSION_CHECK']
12-
require 'json'
13-
require 'net/http'
14-
rubygems_version = JSON.parse(Net::HTTP.get(URI.parse('https://rubygems.org/api/v1/gems/appmap.json')))['version']
15-
if Gem::Version.new(GEM_VERSION) < Gem::Version.new(rubygems_version)
16-
raise "#{GEM_VERSION} < #{rubygems_version}. Rebase to avoid build issues."
17-
end
18-
end
192

3+
require 'rspec/core/rake_task'
204
require 'rake/testtask'
215
require 'rdoc/task'
22-
23-
require 'open3'
246
require 'rake/extensiontask'
257

268
desc 'build the native extension'
279
Rake::ExtensionTask.new("appmap") do |ext|
2810
ext.lib_dir = "lib/appmap"
2911
end
3012

31-
RUBY_VERSIONS=%w[2.6 2.7 3.0 3.1].select do |version|
32-
travis_ruby_version = ENV['TRAVIS_RUBY_VERSION']
33-
next true unless travis_ruby_version
34-
35-
if travis_ruby_version.index(version) == 0
36-
warn "Testing Ruby version #{version}, since it matches TRAVIS_RUBY_VERSION=#{travis_ruby_version}"
37-
next true
38-
end
39-
40-
false
41-
end
42-
FIXTURE_APPS=[:rack_users_app, :rails6_users_app, :rails5_users_app, :rails7_users_app => {:ruby_version => '>= 2.7'}]
43-
44-
def run_cmd(*cmd)
45-
$stderr.puts "Running: #{cmd}"
46-
out, s = Open3.capture2e(*cmd)
47-
unless s.success?
48-
$stderr.puts <<-END
49-
Command failed:
50-
<<< Output:
51-
#{out}
52-
>>> End of output
53-
END
54-
raise 'Docker build failed'
55-
end
56-
end
57-
58-
def build_base_image(ruby_version)
59-
run_cmd "docker build" \
60-
" --build-arg RUBY_VERSION=#{ruby_version}" \
61-
" --build-arg GEM_VERSION=#{GEM_VERSION}" \
62-
" -t appmap:#{GEM_VERSION} -f Dockerfile.appmap ."
63-
end
64-
65-
def build_app_image(app, ruby_version)
66-
Dir.chdir "spec/fixtures/#{app}" do
67-
env = {"RUBY_VERSION" => ruby_version, "GEM_VERSION" => GEM_VERSION}
68-
run_cmd(env,
69-
"docker-compose build" \
70-
" --build-arg RUBY_VERSION=#{ruby_version}" \
71-
" --build-arg GEM_VERSION=#{GEM_VERSION}" )
72-
end
73-
end
74-
7513
desc 'Install non-Ruby dependencies'
7614
task :install do
7715
system 'yarn install' or raise 'yarn install failed'
7816
end
7917

80-
namespace :build do
81-
namespace :base do
82-
RUBY_VERSIONS.each do |ruby_version|
83-
desc ruby_version
84-
task ruby_version do
85-
run_system = ->(cmd) { system(cmd) or raise "Command failed: #{cmd}" }
86-
87-
run_system.call 'mkdir -p pkg'
88-
run_system.call "gem build appmap.gemspec --output pkg/appmap-#{GEM_VERSION}.gem"
89-
build_base_image(ruby_version)
90-
end.tap do |t|
91-
desc "Build all images"
92-
task all: t
93-
end
94-
end
95-
end
96-
97-
namespace :fixtures do
98-
RUBY_VERSIONS.each do |ruby_version|
99-
namespace ruby_version do
100-
desc "build:fixtures:#{ruby_version}"
101-
FIXTURE_APPS.each do |app_spec|
102-
app = if app_spec.instance_of?(Hash)
103-
app_spec = app_spec.flatten
104-
version_rqt = Gem::Requirement.create(app_spec[1][:ruby_version])
105-
next unless version_rqt =~ (Gem::Version.new(ruby_version))
106-
app = app_spec[0]
107-
else
108-
app = app_spec
109-
end.to_s
110-
111-
112-
desc app
113-
task app => ["base:#{ruby_version}"] do
114-
build_app_image(app, ruby_version)
115-
end.tap do |t|
116-
desc "Build all fixture images for #{ruby_version}"
117-
task all: t
118-
end
119-
end
120-
end
121-
122-
desc "Build all fixture images"
123-
task all: ["#{ruby_version}:all"]
124-
end
125-
end
126-
127-
task all: ["fixtures:all"]
128-
end
129-
130-
def run_specs(ruby_version, task_args)
131-
require 'rspec/core/rake_task'
132-
require 'climate_control'
133-
# Define an rspec rake task for the specified Ruby version. It's hidden (i.e. doesn't have a
134-
# description), because it's not intended to be invoked directly
135-
RSpec::Core::RakeTask.new("rspec_#{ruby_version}", [:specs]) do |task, args|
136-
task.exclude_pattern = 'spec/fixtures/**/*_spec.rb'
137-
task.rspec_opts = '-f doc'
138-
if args.count > 0
139-
# There doesn't appear to be a value for +pattern+ that will
140-
# cause it to be ignored. Setting it to '' or +nil+ causes an
141-
# empty argument to get passed to rspec, which confuses it.
142-
task.pattern = 'never match this'
143-
task.rspec_opts += " " + args.to_a.join(' ')
144-
end
145-
end
146-
147-
# Set up the environment, then execute the rspec task we
148-
# created above.
149-
ClimateControl.modify(RUBY_VERSION: ruby_version) do
150-
Rake::Task["rspec_#{ruby_version}"].execute(task_args)
151-
end
152-
end
153-
154-
namespace :spec do
155-
RUBY_VERSIONS.each do |ruby_version|
156-
desc ruby_version
157-
task ruby_version, [:specs] => ["install", "compile", "build:fixtures:#{ruby_version}:all"] do |_, task_args|
158-
run_specs(ruby_version, task_args)
159-
end.tap do |t|
160-
desc "Run all specs"
161-
task :all, [:specs] => t
162-
end
18+
RSpec::Core::RakeTask.new spec: %i[compile install] do |task, args|
19+
task.exclude_pattern = 'spec/fixtures/**/*_spec.rb'
20+
task.rspec_opts = '-f doc'
21+
if args.count > 0
22+
# There doesn't appear to be a value for +pattern+ that will
23+
# cause it to be ignored. Setting it to '' or +nil+ causes an
24+
# empty argument to get passed to rspec, which confuses it.
25+
task.pattern = 'never match this'
26+
task.rspec_opts += [nil, *args].join(' ')
16327
end
16428
end
16529

@@ -169,14 +33,12 @@ Rake::RDocTask.new do |rd|
16933
rd.title = 'AppMap'
17034
end
17135

172-
Rake::TestTask.new(minitest: 'compile') do |t|
36+
Rake::TestTask.new(minitest: :compile) do |t|
17337
t.libs << 'test'
17438
t.libs << 'lib'
17539
t.test_files = FileList['test/*_test.rb']
17640
end
17741

178-
task spec: %i[spec:all]
179-
180-
task test: %i[spec:all minitest]
42+
task test: %i[spec minitest]
18143

18244
task default: :test

appmap.gemspec

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
55
require 'appmap/version'
66

77
Gem::Specification.new do |spec|
8-
# ability to parameterize gem name is added intentionally,
8+
# ability to parameterize gem name is added intentionally,
99
# to support the possibility of unofficial releases, e.g. during CI tests
1010
spec.name = (ENV['GEM_ALTERNATIVE_NAME'].to_s.empty? ? 'appmap' : ENV["GEM_ALTERNATIVE_NAME"] )
1111
spec.version = AppMap::VERSION
@@ -32,7 +32,7 @@ Gem::Specification.new do |spec|
3232
spec.add_dependency 'reverse_markdown'
3333

3434
spec.add_development_dependency 'bundler', '>= 1.16'
35-
spec.add_development_dependency 'minitest', '~> 5.14'
35+
spec.add_development_dependency 'minitest', '~> 5.15'
3636
spec.add_development_dependency 'pry-byebug'
3737
spec.add_development_dependency 'rake', '>= 12.3.3'
3838
spec.add_development_dependency 'rdoc'
@@ -48,5 +48,6 @@ Gem::Specification.new do |spec|
4848
spec.add_development_dependency 'webdrivers', '~> 4.0'
4949
spec.add_development_dependency 'timecop'
5050
spec.add_development_dependency 'hashie'
51+
spec.add_development_dependency 'random-port', '~> 0.5.1'
5152
spec.add_development_dependency 'webrick'
5253
end

docker-compose.yml

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
version: "3"
2+
services:
3+
pg:
4+
build:
5+
context: .
6+
dockerfile: Dockerfile.pg
7+
ports:
8+
- "5432"
9+
environment:
10+
POSTGRES_HOST_AUTH_METHOD: trust

spec/config_spec.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
require 'rails_spec_helper'
44
require 'appmap/config'
55

6-
describe AppMap::Config, docker: false do
6+
describe AppMap::Config do
77
it 'loads as expected' do
88
config_data = {
99
name: 'test',

0 commit comments

Comments
 (0)