You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by da...@apache.org on 2020/09/10 16:07:38 UTC
[couchdb] branch prototype/fdb-layer-final-final-merge created (now
ec7cfe0)
This is an automated email from the ASF dual-hosted git repository.
davisp pushed a change to branch prototype/fdb-layer-final-final-merge
in repository https://gitbox.apache.org/repos/asf/couchdb.git.
at ec7cfe0 Merge branch 'master' into prototype/fdb-layer-final-final-merge
This branch includes the following new commits:
new ec7cfe0 Merge branch 'master' into prototype/fdb-layer-final-final-merge
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
[couchdb] 01/01: Merge branch 'master' into
prototype/fdb-layer-final-final-merge
Posted by da...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
davisp pushed a commit to branch prototype/fdb-layer-final-final-merge
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit ec7cfe03f184f38aca6ef577cf0d1cc31a785acc
Merge: 6cedf87 e4d577b
Author: Paul J. Davis <pa...@gmail.com>
AuthorDate: Thu Sep 10 11:01:42 2020 -0500
Merge branch 'master' into prototype/fdb-layer-final-final-merge
.credo.exs | 7 +-
.gitignore | 3 +
INSTALL.Unix.md | 2 +-
LICENSE | 2 +-
Makefile | 29 +-
Makefile.win | 14 +-
README.rst | 8 +-
build-aux/Jenkinsfile.full | 59 ++-
build-aux/logfile-uploader.py | 2 +-
dev/run | 32 +-
mix.exs | 4 +-
mix.lock | 4 +-
rebar.config.script | 23 +-
rel/files/couchdb.cmd.in | 3 +-
rel/overlay/bin/remsh | 21 +-
rel/overlay/etc/default.ini | 30 +-
rel/reltool.config | 4 +-
src/chttpd/src/chttpd_auth.erl | 23 +-
src/chttpd/src/chttpd_db.erl | 1 -
src/chttpd/src/chttpd_misc.erl | 2 +-
src/chttpd/test/eunit/chttpd_auth_tests.erl | 129 ++++++
src/chttpd/test/eunit/chttpd_csp_tests.erl | 2 +-
src/couch/include/couch_eunit.hrl | 5 +
src/couch/priv/couch_js/1.8.5/help.h | 2 +-
src/couch/priv/couch_js/60/help.h | 2 +-
src/couch/priv/couch_js/60/http.cpp | 214 ++++-----
src/couch/priv/couch_js/60/main.cpp | 69 ++-
src/couch/priv/couch_js/60/utf8.cpp | 301 ------------
src/couch/priv/couch_js/60/util.cpp | 196 ++++----
src/couch/priv/couch_js/60/util.h | 4 +-
src/couch/priv/couch_js/{1.8.5 => 68}/help.h | 2 +-
src/couch/priv/couch_js/{60 => 68}/http.cpp | 215 ++++-----
src/couch/priv/couch_js/{60/utf8.h => 68/http.h} | 16 +-
src/couch/priv/couch_js/{60 => 68}/main.cpp | 139 ++++--
src/couch/priv/couch_js/{60 => 68}/util.cpp | 205 +++++----
src/couch/priv/couch_js/{60 => 68}/util.h | 5 +-
src/couch/rebar.config.script | 72 +--
src/couch/src/couch.app.src | 1 -
src/couch/src/couch.erl | 1 -
src/couch/src/couch_httpd.erl | 2 +
src/couch/src/couch_httpd_auth.erl | 41 +-
src/couch/src/couch_query_servers.erl | 107 ++++-
src/couch/src/couch_server.erl | 15 +-
src/couch/src/couch_util.erl | 12 +
src/couch/test/eunit/couch_js_tests.erl | 139 +++++-
.../test/eunit/couchdb_cookie_domain_tests.erl | 13 +-
src/couch_index/src/couch_index_server.erl | 16 +-
src/couch_mrview/src/couch_mrview_index.erl | 11 +-
src/couch_mrview/src/couch_mrview_util.erl | 9 +-
src/couch_replicator/src/couch_replicator.erl | 28 +-
.../src/couch_replicator_api_wrap.erl | 2 +-
.../src/couch_replicator_scheduler.erl | 16 +
src/dreyfus/src/dreyfus_fabric_cleanup.erl | 16 +-
src/dreyfus/src/dreyfus_httpd.erl | 24 +-
.../test/elixir/test/partition_search_test.exs | 36 +-
src/dreyfus/test/elixir/test/search_test.exs | 226 +++++++++
src/fabric/src/fabric_rpc.erl | 5 +-
src/fabric/test/eunit/fabric_rpc_tests.erl | 181 ++++++++
src/ioq/src/ioq.erl | 2 +-
src/jwtf/.gitignore | 4 +
src/jwtf/LICENSE | 176 +++++++
src/jwtf/README.md | 18 +
src/jwtf/rebar.config | 2 +
src/jwtf/src/jwtf.app.src | 32 ++
src/jwtf/src/jwtf.erl | 353 ++++++++++++++
src/jwtf/src/jwtf_app.erl | 28 ++
src/jwtf/src/jwtf_keystore.erl | 166 +++++++
src/jwtf/src/jwtf_sup.erl | 38 ++
src/jwtf/test/jwtf_keystore_tests.erl | 64 +++
src/jwtf/test/jwtf_tests.erl | 317 +++++++++++++
src/mango/README.md | 328 +++++++++----
src/mango/TODO.md | 19 +-
src/mango/rebar.config | 2 +
src/mango/src/mango_cursor_text.erl | 17 +-
src/mango/src/mango_cursor_view.erl | 5 +-
src/mango/src/mango_json_bookmark.erl | 2 +-
src/mango/src/mango_selector.erl | 36 +-
src/mango/test/03-operator-test.py | 9 +
src/mango/test/08-text-limit-test.py | 10 +
src/mango/test/21-empty-selector-tests.py | 24 +-
src/mango/test/README.md | 17 +-
src/mango/test/mango.py | 8 +
src/mango/test/user_docs.py | 4 +
src/mem3/src/mem3_reshard_dbdoc.erl | 3 +-
src/mem3/src/mem3_rpc.erl | 2 +-
src/mem3/src/mem3_shards.erl | 22 +-
src/mem3/src/mem3_util.erl | 86 +++-
src/setup/src/setup.erl | 5 +-
support/build_js.escript | 6 +
test/elixir/README.md | 53 +--
test/elixir/lib/couch.ex | 4 +-
test/elixir/lib/couch/db_test.ex | 83 +++-
test/elixir/test/all_docs_test.exs | 1 +
test/elixir/test/attachment_names_test.exs | 1 +
test/elixir/test/attachment_paths_test.exs | 1 +
test/elixir/test/attachment_ranges_test.exs | 1 +
test/elixir/test/attachment_views_test.exs | 1 +
test/elixir/test/attachments_multipart_test.exs | 1 +
test/elixir/test/attachments_test.exs | 1 +
test/elixir/test/auth_cache_test.exs | 16 +-
test/elixir/test/basics_test.exs | 1 +
test/elixir/test/batch_save_test.exs | 1 +
test/elixir/test/bulk_docs_test.exs | 1 +
test/elixir/test/changes_async_test.exs | 1 +
test/elixir/test/changes_test.exs | 1 +
test/elixir/test/cluster_with_quorum_test.exs | 1 +
test/elixir/test/cluster_without_quorum_test.exs | 1 +
test/elixir/test/coffee_test.exs | 1 +
test/elixir/test/compact_test.exs | 13 +-
test/elixir/test/config/test-config.ini | 2 +
test/elixir/test/config_test.exs | 1 +
test/elixir/test/conflicts_test.exs | 1 +
test/elixir/test/cookie_auth_test.exs | 16 +-
test/elixir/test/copy_doc_test.exs | 1 +
test/elixir/test/design_docs_query_test.exs | 274 +++++++++++
test/elixir/test/design_docs_test.exs | 508 ++++++++++++++++++---
test/elixir/test/design_options_test.exs | 75 +++
test/elixir/test/design_paths_test.exs | 77 ++++
test/elixir/test/erlang_views_test.exs | 1 +
test/elixir/test/etags_head_test.exs | 1 +
test/elixir/test/form_submit_test.exs | 1 +
test/elixir/test/helper_test.exs | 3 +
test/elixir/test/http_test.exs | 82 ++++
test/elixir/test/invalid_docids_test.exs | 1 +
test/elixir/test/jsonp_test.exs | 117 +++++
test/elixir/test/jwtauth_test.exs | 218 +++++++++
test/elixir/test/large_docs_text.exs | 2 +
test/elixir/test/local_docs_test.exs | 1 +
test/elixir/test/lots_of_docs_test.exs | 2 +
test/elixir/test/method_override_test.exs | 56 +++
test/elixir/test/multiple_rows_test.exs | 1 +
test/elixir/test/proxyauth_test.exs | 164 +++++++
test/elixir/test/purge_test.exs | 151 ++++++
test/elixir/test/reader_acl_test.exs | 255 +++++++++++
test/elixir/test/recreate_doc_test.exs | 166 +++++++
test/elixir/test/reduce_builtin_test.exs | 1 +
test/elixir/test/reduce_false_test.exs | 1 +
test/elixir/test/reduce_test.exs | 1 +
test/elixir/test/replication_test.exs | 41 +-
test/elixir/test/replicator_db_bad_rep_id_test.exs | 84 ++++
test/elixir/test/replicator_db_by_doc_id_test.exs | 124 +++++
test/elixir/test/rev_stemming_test.exs | 158 +++++++
test/elixir/test/rewrite_test.exs | 1 +
test/elixir/test/security_validation_test.exs | 1 +
test/elixir/test/update_documents_test.exs | 326 +++++++++++++
test/elixir/test/users_db_test.exs | 26 +-
test/elixir/test/utf8_test.exs | 3 +-
test/elixir/test/uuids_test.exs | 3 +
...lation_test.exs => view_collation_raw_test.exs} | 111 +++--
test/elixir/test/view_collation_test.exs | 2 +
test/elixir/test/view_compaction_test.exs | 108 +++++
test/elixir/test/view_multi_key_all_docs_test.exs | 193 ++++++++
test/elixir/test/view_multi_key_design_test.exs | 318 +++++++++++++
test/elixir/test/view_offsets_test.exs | 101 ++++
test/elixir/test/view_pagination_test.exs | 190 ++++++++
test/elixir/test/view_sandboxing_test.exs | 193 ++++++++
test/elixir/test/view_test.exs | 1 +
test/elixir/test/view_update_seq_test.exs | 143 ++++++
test/javascript/cli_runner.js | 23 +-
test/javascript/tests/changes.js | 6 +-
test/javascript/tests/design_docs.js | 2 +
test/javascript/tests/design_docs_query.js | 4 +-
test/javascript/tests/design_options.js | 5 +-
test/javascript/tests/design_paths.js | 3 +-
test/javascript/tests/erlang_views.js | 2 +-
test/javascript/tests/form_submit.js | 1 +
test/javascript/tests/http.js | 3 +-
test/javascript/tests/jsonp.js | 2 +
test/javascript/tests/method_override.js | 2 +
test/javascript/tests/proxyauth.js | 51 +--
test/javascript/tests/purge.js | 2 +-
test/javascript/tests/reader_acl.js | 1 +
test/javascript/tests/recreate_doc.js | 1 +
test/javascript/tests/reduce_builtin.js | 1 +
test/javascript/tests/reduce_false.js | 1 +
test/javascript/tests/reduce_false_temp.js | 1 +
test/javascript/tests/replicator_db_bad_rep_id.js | 1 +
test/javascript/tests/replicator_db_by_doc_id.js | 1 +
test/javascript/tests/rev_stemming.js | 1 +
test/javascript/tests/update_documents.js | 2 +-
test/javascript/tests/view_collation_raw.js | 1 +
test/javascript/tests/view_compaction.js | 1 +
test/javascript/tests/view_multi_key_all_docs.js | 1 +
test/javascript/tests/view_multi_key_design.js | 1 +
test/javascript/tests/view_multi_key_temp.js | 1 +
test/javascript/tests/view_offsets.js | 2 +
test/javascript/tests/view_pagination.js | 2 +
test/javascript/tests/view_sandboxing.js | 1 +
test/javascript/tests/view_update_seq.js | 1 +
189 files changed, 7797 insertions(+), 1378 deletions(-)
diff --cc .gitignore
index 5c42552,6223d73..ead569d
--- a/.gitignore
+++ b/.gitignore
@@@ -11,10 -11,10 +11,12 @@@
.DS_Store
.vscode
.rebar/
+.rebar3/
+.erlfdb/
.eunit/
cover/
+ core
+ debian/
log
apache-couchdb-*/
bin/
diff --cc Makefile
index 2e3cc8a,53cea3b..ae095b6
--- a/Makefile
+++ b/Makefile
@@@ -144,11 -144,10 +144,12 @@@ fauxton: share/ww
################################################################################
-.PHONY: check
+# When we can run all the tests with FDB switch this back to be the default
+# "make check" command
+.PHONY: check-all-tests
# target: check - Test everything
-check: all python-black
+check-all-tests: all python-black
+ @$(MAKE) emilio
@$(MAKE) eunit
@$(MAKE) javascript
@$(MAKE) mango-test
@@@ -237,11 -227,10 +238,25 @@@ python-black-update: .venv/bin/blac
elixir: export MIX_ENV=integration
elixir: export COUCHDB_TEST_ADMIN_PARTY_OVERRIDE=1
elixir: elixir-init elixir-check-formatted elixir-credo devclean
- @dev/run "$(TEST_OPTS)" -a adm:pass -n 1 --enable-erlang-views --no-eval --erlang-config=rel/files/eunit.config 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)'
- @dev/run "$(TEST_OPTS)" -a adm:pass -n 1 \
++ @dev/run "$(TEST_OPTS)" \
++ -a adm:pass \
++ -n 1 \
++ --enable-erlang-views \
++ --locald-config test/elixir/test/config/test-config.ini \
++ --erlang-config rel/files/eunit.config \
++ --no-eval \
++ 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)'
+
+.PHONY: elixir-only
+elixir-only: devclean
- @dev/run "$(TEST_OPTS)" -a adm:pass -n 1 --enable-erlang-views --no-eval --erlang-config=rel/files/eunit.config 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)'
++ @dev/run "$(TEST_OPTS)" \
++ -a adm:pass \
++ -n 1 \
+ --enable-erlang-views \
+ --locald-config test/elixir/test/config/test-config.ini \
- --no-eval 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)'
++ --erlang-config rel/files/eunit.config \
++ --no-eval \
++ 'mix test --trace --exclude without_quorum_test --exclude with_quorum_test $(EXUNIT_OPTS)'
.PHONY: elixir-init
elixir-init: MIX_ENV=test
diff --cc mix.exs
index 480d426,ae42af5..5adccb7
--- a/mix.exs
+++ b/mix.exs
@@@ -68,11 -65,12 +68,13 @@@ defmodule CouchDBTest.Mixfile d
{:junit_formatter, "~> 3.0", only: [:dev, :test, :integration]},
{:httpotion, ">= 3.1.3", only: [:dev, :test, :integration], runtime: false},
{:excoveralls, "~> 0.12", only: :test},
+ {:b64url, path: Path.expand("src/b64url", __DIR__)},
{:jiffy, path: Path.expand("src/jiffy", __DIR__)},
+ {:jwtf, path: Path.expand("src/jwtf", __DIR__)},
{:ibrowse,
path: Path.expand("src/ibrowse", __DIR__), override: true, compile: false},
- {:credo, "~> 1.2.0", only: [:dev, :test, :integration], runtime: false},
- {:credo, "~> 1.4.0", only: [:dev, :test, :integration], runtime: false}
++ {:credo, "~> 1.4.0", only: [:dev, :test, :integration], runtime: false},
+ {:stream_data, "~> 0.4.3", only: [:dev, :test, :integration], runtime: false}
]
end
diff --cc rebar.config.script
index 963d97f,d8afc10..9947944
--- a/rebar.config.script
+++ b/rebar.config.script
@@@ -135,19 -130,16 +135,20 @@@ SubDirs =
"src/ddoc_cache",
"src/dreyfus",
"src/fabric",
+ "src/aegis",
+ "src/couch_jobs",
+ "src/couch_expiring_cache",
"src/global_changes",
"src/ioq",
+ "src/jwtf",
"src/ken",
"src/mango",
"src/rexi",
"src/setup",
"src/smoosh",
+ "src/ebtree",
"rel"
- ],
+ ].
DepDescs = [
%% Independent Apps
@@@ -166,18 -157,14 +167,18 @@@
%% Third party deps
{folsom, "folsom", {tag, "CouchDB-0.8.3"}},
{hyper, "hyper", {tag, "CouchDB-2.2.0-6"}},
-{ibrowse, "ibrowse", {tag, "CouchDB-4.0.1-1"}},
+{ibrowse, "ibrowse", {tag, "CouchDB-4.0.1-2"}},
+{jaeger_passage, "jaeger-passage", {tag, "CouchDB-0.1.14-1"}},
{jiffy, "jiffy", {tag, "CouchDB-1.0.4-1"}},
+{local, "local", {tag, "0.2.1"}},
{mochiweb, "mochiweb", {tag, "v2.20.0"}},
{meck, "meck", {tag, "0.8.8"}},
-{recon, "recon", {tag, "2.5.0"}}
+{recon, "recon", {tag, "2.5.0"}},
+{passage, "passage", {tag, "0.2.6"}},
+{thrift_protocol, "thrift-protocol", {tag, "0.1.5"}}
- ],
+ ].
- WithProper = lists:keyfind(with_proper, 1, CouchConfig) == {with_proper, true},
+ WithProper = lists:keyfind(with_proper, 1, CouchConfig) == {with_proper, true}.
OptionalDeps = case WithProper of
true ->
@@@ -223,13 -210,8 +224,13 @@@ AddConfig =
sasl, setup, ssl, stdlib, syntax_tools, xmerl]},
{warnings, [unmatched_returns, error_handling, race_conditions]}]},
{post_hooks, [{compile, "escript support/build_js.escript"}]}
- ],
+ ].
-C = lists:foldl(fun({K, V}, CfgAcc) ->
- lists:keystore(K, 1, CfgAcc, {K, V})
+lists:foldl(fun({K, V}, CfgAcc) ->
+ case lists:keyfind(K, 1, CfgAcc) of
+ {K, Existent} when is_list(Existent) andalso is_list(V) ->
+ lists:keystore(K, 1, CfgAcc, {K, Existent ++ V});
+ false ->
+ lists:keystore(K, 1, CfgAcc, {K, V})
+ end
end, CONFIG, AddConfig).
diff --cc src/chttpd/src/chttpd_db.erl
index ec4a1a4,b995460..18d663f
--- a/src/chttpd/src/chttpd_db.erl
+++ b/src/chttpd/src/chttpd_db.erl
@@@ -1865,7 -1695,81 +1865,6 @@@ get_md5_header(Req) -
parse_doc_query(Req) ->
lists:foldl(fun parse_doc_query/2, #doc_query_args{}, chttpd:qs(Req)).
-parse_shards_opt(Req) ->
- [
- {n, parse_shards_opt("n", Req, config:get("cluster", "n", "3"))},
- {q, parse_shards_opt("q", Req, config:get("cluster", "q", "8"))},
- {placement, parse_shards_opt(
- "placement", Req, config:get("cluster", "placement"))}
- ].
-
-parse_shards_opt("placement", Req, Default) ->
- Err = <<"The `placement` value should be in a format `zone:n`.">>,
- case chttpd:qs_value(Req, "placement", Default) of
- Default -> Default;
- [] -> throw({bad_request, Err});
- Val ->
- try
- true = lists:all(fun(Rule) ->
- [_, N] = string:tokens(Rule, ":"),
- couch_util:validate_positive_int(N)
- end, string:tokens(Val, ",")),
- Val
- catch _:_ ->
- throw({bad_request, Err})
- end
- end;
-
-parse_shards_opt(Param, Req, Default) ->
- Val = chttpd:qs_value(Req, Param, Default),
- Err = ?l2b(["The `", Param, "` value should be a positive integer."]),
- case couch_util:validate_positive_int(Val) of
- true -> Val;
- false -> throw({bad_request, Err})
- end.
-
-
-parse_engine_opt(Req) ->
- case chttpd:qs_value(Req, "engine") of
- undefined ->
- [];
- Extension ->
- Available = couch_server:get_engine_extensions(),
- case lists:member(Extension, Available) of
- true ->
- [{engine, iolist_to_binary(Extension)}];
- false ->
- throw({bad_request, invalid_engine_extension})
- end
- end.
-
-
-parse_partitioned_opt(Req) ->
- case chttpd:qs_value(Req, "partitioned") of
- undefined ->
- [];
- "false" ->
- [];
- "true" ->
- ok = validate_partitioned_db_enabled(Req),
- [
- {partitioned, true},
- {hash, [couch_partition, hash, []]}
- ];
- _ ->
- throw({bad_request, <<"Invalid `partitioned` parameter">>})
- end.
-
-
-validate_partitioned_db_enabled(Req) ->
- case couch_flags:is_enabled(partitioned, Req) of
- true ->
- ok;
- false ->
- throw({bad_request, <<"Partitioned feature is not enabled.">>})
- end.
-
--
parse_doc_query({Key, Value}, Args) ->
case {Key, Value} of
{"attachments", "true"} ->
diff --cc src/mango/src/mango_cursor_view.erl
index 4960fa1,68d7c3b..44ae220
--- a/src/mango/src/mango_cursor_view.erl
+++ b/src/mango/src/mango_cursor_view.erl
@@@ -112,7 -115,12 +112,10 @@@ base_args(#cursor{index = Idx} = Cursor
reduce = false,
start_key = StartKey,
end_key = EndKey,
- include_docs = true
+ include_docs = true,
+ extra = [
- {callback, {?MODULE, view_cb}},
- {selector, Selector},
+ {ignore_partition_query_limit, true}
+ ]
}.
diff --cc src/mango/test/user_docs.py
index d69e6d6,617b430..c301983
--- a/src/mango/test/user_docs.py
+++ b/src/mango/test/user_docs.py
@@@ -59,8 -59,13 +59,12 @@@ def setup_users(db, **kwargs)
db.save_docs(copy.deepcopy(USERS_DOCS))
+ def teardown_users(db):
+ [db.delete_doc(doc["_id"]) for doc in USERS_DOCS]
+
+
def setup(db, index_type="view", **kwargs):
db.recreate()
- db.save_docs(copy.deepcopy(DOCS))
if index_type == "view":
add_view_indexes(db, kwargs)
elif index_type == "text":
diff --cc test/elixir/lib/couch.ex
index a843941,7819299..094f275
--- a/test/elixir/lib/couch.ex
+++ b/test/elixir/lib/couch.ex
@@@ -129,15 -125,10 +129,15 @@@ defmodule Couch d
end
def set_auth_options(options) do
- if Keyword.get(options, :cookie) == nil do
+ no_auth? = Keyword.get(options, :no_auth) == true
+ cookie? = Keyword.has_key?(options, :cookie)
+ basic_auth? = Keyword.has_key?(options, :basic_auth)
+ if cookie? or no_auth? or basic_auth? do
+ Keyword.delete(options, :no_auth)
+ else
headers = Keyword.get(options, :headers, [])
-
- if headers[:basic_auth] != nil or headers[:authorization] != nil do
+ if headers[:basic_auth] != nil or headers[:authorization] != nil
+ or List.keymember?(headers, :"X-Auth-CouchDB-UserName", 0) do
options
else
username = System.get_env("EX_USERNAME") || "adm"
diff --cc test/elixir/test/replication_test.exs
index 8b657d9,7b462bd..01694a7
--- a/test/elixir/test/replication_test.exs
+++ b/test/elixir/test/replication_test.exs
@@@ -1804,29 -1706,15 +1782,16 @@@ defmodule ReplicationTest d
end
def try_get_task(repl_id) do
- resp = Couch.get("/_active_tasks")
- assert HTTPotion.Response.success?(resp)
- assert is_list(resp.body)
+ resp = Couch.get("/_scheduler/jobs/#{repl_id}")
- Enum.find(resp.body, nil, fn task ->
- task["replication_id"] == repl_id
- end)
+ if HTTPotion.Response.success?(resp) do
+ assert is_map(resp.body)
+ resp.body
+ else
+ nil
+ end
end
- def set_user(uri, userinfo) do
- case URI.parse(uri) do
- %{scheme: nil} ->
- uri
-
- %{userinfo: nil} = uri ->
- URI.to_string(Map.put(uri, :userinfo, userinfo))
-
- _ ->
- uri
- end
- end
-
def get_att1_data do
File.read!(Path.expand("data/lorem.txt", __DIR__))
end