Skip to content
Open
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
50 changes: 50 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
name: CI

on:
push:
branches: [main]
pull_request:

permissions:
contents: read

jobs:
test:
name: OTP ${{ matrix.otp }}
runs-on: ubuntu-latest
container:
image: erlang:${{ matrix.otp }}
strategy:
fail-fast: false
matrix:
# 26 is what chef-server currently pins; 27 and 28 are tested so
# regressions show up before the pin moves.
otp: ['26', '27', '28']
steps:
- uses: actions/checkout@v4

- name: Compile
run: rebar3 compile

- name: EUnit
# The network-dependent suites are opt-in via
# OPSCODERL_HTTPC_NETWORK_TESTS; see test/oc_httpc_tests.erl.
run: rebar3 eunit

dialyzer:
name: Dialyzer (informational)
runs-on: ubuntu-latest
container:
image: erlang:26
# Not a merge gate yet. Four warnings are outstanding on main:
# - three from lager's parse transform expanding into lager:do_log/10,
# lager:md/0 and lager_config:get/2, which dialyzer cannot resolve.
# Removing lager clears all three.
# - one for pooler:time_spec/0, which pooler uses internally but never
# exports, so oc_httpc's spec refers to a type that is not public.
# Once both are resolved this should drop continue-on-error and gate.
continue-on-error: true
steps:
- uses: actions/checkout@v4
- name: Dialyzer
run: rebar3 dialyzer
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ rel/opscoderl_httpc
.concrete/DEV_MODE
deps.plt
.eunit

# rebar3
_build/
rebar.lock
16 changes: 0 additions & 16 deletions .travis.yml

This file was deleted.

4 changes: 1 addition & 3 deletions rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@
[
{meck, ".*", {git, "https://github.com/eproxus/meck", {ref, "06192a984750070ace33b60a492ca27ec9bc6806"}}},
{observer_cli, ".*",
{git, "https://github.com/zhongwencool/observer_cli", {ref, "baa70569bccc5508e9839e20768540ef3cdca016"}}},
{eper, ".*",
{git, "https://github.com/massemanet/eper", {ref, "17b0f97ea8287b72e8ebbe7132214db182ff1a1d"}}}
{git, "https://github.com/zhongwencool/observer_cli", {ref, "baa70569bccc5508e9839e20768540ef3cdca016"}}}
]}]}
]}.

Expand Down
37 changes: 35 additions & 2 deletions test/oc_httpc_tests.erl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,22 @@

-include_lib("eunit/include/eunit.hrl").

%% The suites below make live requests to a dozen third-party sites
%% (google.com, sun.com, yaws.hyber.org, jigsaw.w3.org and others) and assert
%% HTTP 200 from them. They are integration tests, not unit tests: they fail
%% whenever one of those hosts is slow, moved or gone, which makes them useless
%% as a merge gate. They stay available and are opted into by setting
%% OPSCODERL_HTTPC_NETWORK_TESTS=1; CI runs the deterministic suites only.
network_tests_enabled() ->
os:getenv("OPSCODERL_HTTPC_NETWORK_TESTS") =/= false.

opscoderl_ibrowse_test_() ->
case network_tests_enabled() of
false -> [];
true -> opscoderl_ibrowse_tests()
end.

opscoderl_ibrowse_tests() ->
{setup,
fun() ->
application:ensure_all_started(ssl),
Expand Down Expand Up @@ -79,7 +94,13 @@ assert_200_req(RootUrl, Endpoint, Method, OptionsInput) ->
?assertMatch({ok, _, _, _}, Result)
end}.

multi_request_test() ->
multi_request_test_() ->
case network_tests_enabled() of
false -> [];
true -> {timeout, 120, fun multi_request/0}
end.

multi_request() ->
RootUrl = "http://jigsaw.w3.org/",
CallbackFun = fun(RequestFun) ->
Paths = ["HTTP/ChunkedScript",
Expand Down Expand Up @@ -108,7 +129,13 @@ multi_request_test() ->
?assertEqual(15, length(Results)),
[?assertMatch({ok, _,_,_}, Result) || Result <- Results].

process_leak_test() ->
process_leak_test_() ->
case network_tests_enabled() of
false -> [];
true -> {timeout, 120, fun process_leak/0}
end.

process_leak() ->
Options = [{connect_timeout, 5000}],
PoolConfig = [{root_url, "http://google.com"}, {init_count, 3}, {max_count, 3},
{ibrowse_options, Options}, {max_connection_requests, 1}],
Expand Down Expand Up @@ -151,7 +178,13 @@ request_error_test_() ->
{foreach,
fun() ->
error_logger:tty(false),
%% pooler has to be running before add_pool/2. This used to be
%% started by opscoderl_ibrowse_test_'s setup, so these cases only
%% passed when that suite ran first; they now stand alone.
{ok, _} = application:ensure_all_started(pooler),
application:start(ibrowse),
%% no request reaches this host: ibrowse is mecked below, so the
%% URL is only pool configuration.
RootUrl = "http://jigsaw.w3.org/",
Options = [{connect_timeout, 5000}],
PoolConfig = [{root_url, RootUrl}, {init_count, 50}, {max_count, 250},
Expand Down