Fix esplora testing - #433

Closed
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing
Closed

Fix esplora testing#433
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing

Conversation

@tcharding

@tchardingtcharding commented Aug 31, 2021

Copy link
Copy Markdown
Contributor

Description

Currently testing of esplora/reqwest is broken because of incorrect usage of, or lack of, async.

Enable testing of esplora/reqwest by using maybe_await! macro in tests and declaring all unit tests in blockchain_tests.rs to be async. This adds a dev dependency on tokio.

With this patch applied one can successfully run:

cargo test --features=test-esplora,use-esplora-reqwest --no-default-features

Notes to the reviewers

This is, in my opinion, a better fix to #431 than #430 (i.e., supercedes #430)

The primary advantage of this PR over #430 is it does not introduce a hard dependency on tokio.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

Currently the esplora module testing is broken.
Enable testing of the esplora/ureq features, with this patch applied one
can run:
cargo test --features=test-esplora,use-esplora-ureq --no-default-features
Note, testing of esplora/reqwest is currently broken.
Currently testing of esplora/reqwest is broken because of incorrect
usage of, or lack of, `async`.
Enable testing of esplora/reqwest by using `maybe_await!` macro in tests
and declaring all unit tests in `blockchain_tests.rs` to be async. This
adds a dev dependency on `tokio`.
With this patch applied one can successfully run:
cargo test --features=test-esplora,use-esplora-reqwest --no-default-features
@notmandatory

Copy link
Copy Markdown
Member

This also looks like a good approach. Either way I agree if we only need tokio for testing it should be a dev-dependency. This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest, I think can copy from @rajarshimaitra PR. I'll check it out more closely tomorrow for a proper review.


#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to move this to esplora/mod.rs as in your original #415 (and remove from esplora/reqwest.rs).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to be able to test both eslpora/reqwest and esplora/ureq we need this to be in the ureq/reqwest submodules. I originally only put it in mod.rs thinking testing both was unnecessary, in hindsight this was wrong. With this change testing can be done by enabling feature test-esplora as well as the feature to enable the backend we want to test (e.g. use-esplora-reqwest).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I locally tried moving this chunk to esplora/mod.rs and removing from reqwest.rs and ureq.rs and tests run fine with these commands:

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
cargo test --no-default-features --features test-esplora,use-esplora-reqwest esplora::bdk_blockchain_tests

@tcharding

Copy link
Copy Markdown
ContributorAuthor

This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest

Oh, yes, my bad. Will add, thanks.

@tcharding

tcharding commented Sep 2, 2021

Copy link
Copy Markdown
ContributorAuthor

Patch 655560f Enable testing Esplora backends in CI needs careful review please. The patch is pure cargo cult programing.

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
Finished test [unoptimized + debuginfo] target(s) in 0.05s
Running unittests (/home/tobin/.cache/cargo/debug/deps/bdk-0eaddf4dc688116f)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 213 filtered out; finished in 0.00s

And without the test filter I get just the unit tests running

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
...
test result: ok. 41 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 20.21s

With the recent changes we can now test both the Esplora HTTP backends
individually. Configure the CI pipeline to run test for both `ureq` and
`reqwest` Esplora blockchain backends.
@tchardingtcharding mentioned this pull request Sep 2, 2021
9 tasks
@RCasatta

Copy link
Copy Markdown
Contributor

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

You have to give the right initial namespace, for example:

cargo test --no-default-features --features test-esplora,use-esplora-ureq blockchain::esplora

toolchain: stable
override: true
- name: Test
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests

@notmandatorynotmandatorySep 3, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @RCasatta suggested, this will work:

Suggested change
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::${{ matrix.backend.name }}::bdk_blockchain_tests

Or I think the better solution is to move the below chunk to esplora/mod.rs and remove it from reqwest.rs and ureq.rs (I confirmed it works):

#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {
fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
}
}

And then the above CI line does not need to change.

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK.

Agreed with the concept that reqwest user should not have to have tokio just for testing.

All the tests passes as expected.

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.
Cargo.lock after build:

...
[[package]]
name = "tokio"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"pin-project-lite",
"tokio-macros",
"winapi 0.3.9",
]
[[package]]
name = "tokio-macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]

I am not entirely sure whether there is any difference between "hard dependency" and "dependency of a dependency". Just by looking at Cargo.locks from builds of both #433 and #430, it seems like it doesn't matter to our dependency tree. tokio is gonna be there in release mode whether we ask for it or not. reqwest depends on it (among few other crates).

Another minor concern I have is over code repetition. And there is really no other workaround if we choose not use await_or_block!() macro. This might create maintenance burden. But good thing is at least they are in testsutils only.

So far I haven't able to form any hard opinion on either approach. I think we should choose whichever makes our lives easier down the line. Maintaining a consistent async interfaces is a tricky thing for sure.

@LLFourn

Copy link
Copy Markdown
Collaborator

I just had a chat with @tcharding where we tried to come up with a way around the sprawling complexity of having multiple http backends. The result of the discussion was something like why not just have our own HttpClient and implement both async and non-async versions. This would just include get, post methods and return the body a Result<Vec<u8>, HttpError>

In blockchain tests we would only use the blocking one and therefore not test request there. However the only logic in the http backend would be making a http request and returning the result so there is no real reason to test this as there is no business logic.

At this point I think HttpClient should be a trait and esplora would use it like Esplora<C: HttpClient>. This also enables BYO http client (I know of one person who said they want this). This would make the http client a separate choice for the user to consider which might make the feature flags more coherent anyway.

I think I will take on this work myself starting next week if nobody has any objections.

@LLFourn

Copy link
Copy Markdown
Collaborator

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.

note that reqwest has a hard dependency on tokio so this is what you should see.

@notmandatory

Copy link
Copy Markdown
Member

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

@LLFourn

LLFourn commented Sep 8, 2021

Copy link
Copy Markdown
Collaborator

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

My idea would be to have a http-client-blocking and http-client-async features and ureq and reqwest would not be re-exported anywhere at all in the api. bdk-cli would not have to worry at all about this (much) but downstream crates would have to have their own http dependency if they need to make http requests which I think is fine.

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

yes

@tcharding
tcharding marked this pull request as draft September 8, 2021 22:21
@tcharding

Copy link
Copy Markdown
ContributorAuthor

Converted this to draft while development of the proposed HttpClient takes place. Cheers.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

@tcharding

Copy link
Copy Markdown
ContributorAuthor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

Go for it

@tcharding

tcharding commented Nov 5, 2021

Copy link
Copy Markdown
ContributorAuthor

I think we can close this now, no further progress or discussion on this PR seems necessary.

@tcharding
tcharding deleted the fix-esplora-testing branch October 13, 2023 00:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@tcharding@notmandatory@RCasatta@LLFourn@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Fix esplora testing - #433

Closed
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing
Closed

Fix esplora testing#433
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing

Conversation

@tcharding

@tchardingtcharding commented Aug 31, 2021

Copy link
Copy Markdown
Contributor

Description

Currently testing of esplora/reqwest is broken because of incorrect usage of, or lack of, async.

Enable testing of esplora/reqwest by using maybe_await! macro in tests and declaring all unit tests in blockchain_tests.rs to be async. This adds a dev dependency on tokio.

With this patch applied one can successfully run:

cargo test --features=test-esplora,use-esplora-reqwest --no-default-features

Notes to the reviewers

This is, in my opinion, a better fix to #431 than #430 (i.e., supercedes #430)

The primary advantage of this PR over #430 is it does not introduce a hard dependency on tokio.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

Currently the esplora module testing is broken.
Enable testing of the esplora/ureq features, with this patch applied one
can run:
cargo test --features=test-esplora,use-esplora-ureq --no-default-features
Note, testing of esplora/reqwest is currently broken.
Currently testing of esplora/reqwest is broken because of incorrect
usage of, or lack of, `async`.
Enable testing of esplora/reqwest by using `maybe_await!` macro in tests
and declaring all unit tests in `blockchain_tests.rs` to be async. This
adds a dev dependency on `tokio`.
With this patch applied one can successfully run:
cargo test --features=test-esplora,use-esplora-reqwest --no-default-features
@notmandatory

Copy link
Copy Markdown
Member

This also looks like a good approach. Either way I agree if we only need tokio for testing it should be a dev-dependency. This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest, I think can copy from @rajarshimaitra PR. I'll check it out more closely tomorrow for a proper review.


#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to move this to esplora/mod.rs as in your original #415 (and remove from esplora/reqwest.rs).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to be able to test both eslpora/reqwest and esplora/ureq we need this to be in the ureq/reqwest submodules. I originally only put it in mod.rs thinking testing both was unnecessary, in hindsight this was wrong. With this change testing can be done by enabling feature test-esplora as well as the feature to enable the backend we want to test (e.g. use-esplora-reqwest).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I locally tried moving this chunk to esplora/mod.rs and removing from reqwest.rs and ureq.rs and tests run fine with these commands:

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
cargo test --no-default-features --features test-esplora,use-esplora-reqwest esplora::bdk_blockchain_tests

@tcharding

Copy link
Copy Markdown
ContributorAuthor

This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest

Oh, yes, my bad. Will add, thanks.

@tcharding

tcharding commented Sep 2, 2021

Copy link
Copy Markdown
ContributorAuthor

Patch 655560f Enable testing Esplora backends in CI needs careful review please. The patch is pure cargo cult programing.

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
Finished test [unoptimized + debuginfo] target(s) in 0.05s
Running unittests (/home/tobin/.cache/cargo/debug/deps/bdk-0eaddf4dc688116f)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 213 filtered out; finished in 0.00s

And without the test filter I get just the unit tests running

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
...
test result: ok. 41 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 20.21s

With the recent changes we can now test both the Esplora HTTP backends
individually. Configure the CI pipeline to run test for both `ureq` and
`reqwest` Esplora blockchain backends.
@tchardingtcharding mentioned this pull request Sep 2, 2021
9 tasks
@RCasatta

Copy link
Copy Markdown
Contributor

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

You have to give the right initial namespace, for example:

cargo test --no-default-features --features test-esplora,use-esplora-ureq blockchain::esplora

toolchain: stable
override: true
- name: Test
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests

@notmandatorynotmandatorySep 3, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @RCasatta suggested, this will work:

Suggested change
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::${{ matrix.backend.name }}::bdk_blockchain_tests

Or I think the better solution is to move the below chunk to esplora/mod.rs and remove it from reqwest.rs and ureq.rs (I confirmed it works):

#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {
fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
}
}

And then the above CI line does not need to change.

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK.

Agreed with the concept that reqwest user should not have to have tokio just for testing.

All the tests passes as expected.

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.
Cargo.lock after build:

...
[[package]]
name = "tokio"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"pin-project-lite",
"tokio-macros",
"winapi 0.3.9",
]
[[package]]
name = "tokio-macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]

I am not entirely sure whether there is any difference between "hard dependency" and "dependency of a dependency". Just by looking at Cargo.locks from builds of both #433 and #430, it seems like it doesn't matter to our dependency tree. tokio is gonna be there in release mode whether we ask for it or not. reqwest depends on it (among few other crates).

Another minor concern I have is over code repetition. And there is really no other workaround if we choose not use await_or_block!() macro. This might create maintenance burden. But good thing is at least they are in testsutils only.

So far I haven't able to form any hard opinion on either approach. I think we should choose whichever makes our lives easier down the line. Maintaining a consistent async interfaces is a tricky thing for sure.

@LLFourn

Copy link
Copy Markdown
Collaborator

I just had a chat with @tcharding where we tried to come up with a way around the sprawling complexity of having multiple http backends. The result of the discussion was something like why not just have our own HttpClient and implement both async and non-async versions. This would just include get, post methods and return the body a Result<Vec<u8>, HttpError>

In blockchain tests we would only use the blocking one and therefore not test request there. However the only logic in the http backend would be making a http request and returning the result so there is no real reason to test this as there is no business logic.

At this point I think HttpClient should be a trait and esplora would use it like Esplora<C: HttpClient>. This also enables BYO http client (I know of one person who said they want this). This would make the http client a separate choice for the user to consider which might make the feature flags more coherent anyway.

I think I will take on this work myself starting next week if nobody has any objections.

@LLFourn

Copy link
Copy Markdown
Collaborator

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.

note that reqwest has a hard dependency on tokio so this is what you should see.

@notmandatory

Copy link
Copy Markdown
Member

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

@LLFourn

LLFourn commented Sep 8, 2021

Copy link
Copy Markdown
Collaborator

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

My idea would be to have a http-client-blocking and http-client-async features and ureq and reqwest would not be re-exported anywhere at all in the api. bdk-cli would not have to worry at all about this (much) but downstream crates would have to have their own http dependency if they need to make http requests which I think is fine.

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

yes

@tcharding
tcharding marked this pull request as draft September 8, 2021 22:21
@tcharding

Copy link
Copy Markdown
ContributorAuthor

Converted this to draft while development of the proposed HttpClient takes place. Cheers.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

@tcharding

Copy link
Copy Markdown
ContributorAuthor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

Go for it

@tcharding

tcharding commented Nov 5, 2021

Copy link
Copy Markdown
ContributorAuthor

I think we can close this now, no further progress or discussion on this PR seems necessary.

@tcharding
tcharding deleted the fix-esplora-testing branch October 13, 2023 00:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@tcharding@notmandatory@RCasatta@LLFourn@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix esplora testing - #433

Closed
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing
Closed

Fix esplora testing#433
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing

Conversation

@tcharding

@tchardingtcharding commented Aug 31, 2021

Copy link
Copy Markdown
Contributor

Description

Currently testing of esplora/reqwest is broken because of incorrect usage of, or lack of, async.

Enable testing of esplora/reqwest by using maybe_await! macro in tests and declaring all unit tests in blockchain_tests.rs to be async. This adds a dev dependency on tokio.

With this patch applied one can successfully run:

cargo test --features=test-esplora,use-esplora-reqwest --no-default-features

Notes to the reviewers

This is, in my opinion, a better fix to #431 than #430 (i.e., supercedes #430)

The primary advantage of this PR over #430 is it does not introduce a hard dependency on tokio.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

Currently the esplora module testing is broken.
Enable testing of the esplora/ureq features, with this patch applied one
can run:
cargo test --features=test-esplora,use-esplora-ureq --no-default-features
Note, testing of esplora/reqwest is currently broken.
Currently testing of esplora/reqwest is broken because of incorrect
usage of, or lack of, `async`.
Enable testing of esplora/reqwest by using `maybe_await!` macro in tests
and declaring all unit tests in `blockchain_tests.rs` to be async. This
adds a dev dependency on `tokio`.
With this patch applied one can successfully run:
cargo test --features=test-esplora,use-esplora-reqwest --no-default-features
@notmandatory

Copy link
Copy Markdown
Member

This also looks like a good approach. Either way I agree if we only need tokio for testing it should be a dev-dependency. This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest, I think can copy from @rajarshimaitra PR. I'll check it out more closely tomorrow for a proper review.


#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to move this to esplora/mod.rs as in your original #415 (and remove from esplora/reqwest.rs).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to be able to test both eslpora/reqwest and esplora/ureq we need this to be in the ureq/reqwest submodules. I originally only put it in mod.rs thinking testing both was unnecessary, in hindsight this was wrong. With this change testing can be done by enabling feature test-esplora as well as the feature to enable the backend we want to test (e.g. use-esplora-reqwest).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I locally tried moving this chunk to esplora/mod.rs and removing from reqwest.rs and ureq.rs and tests run fine with these commands:

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
cargo test --no-default-features --features test-esplora,use-esplora-reqwest esplora::bdk_blockchain_tests

@tcharding

Copy link
Copy Markdown
ContributorAuthor

This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest

Oh, yes, my bad. Will add, thanks.

@tcharding

tcharding commented Sep 2, 2021

Copy link
Copy Markdown
ContributorAuthor

Patch 655560f Enable testing Esplora backends in CI needs careful review please. The patch is pure cargo cult programing.

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
Finished test [unoptimized + debuginfo] target(s) in 0.05s
Running unittests (/home/tobin/.cache/cargo/debug/deps/bdk-0eaddf4dc688116f)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 213 filtered out; finished in 0.00s

And without the test filter I get just the unit tests running

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
...
test result: ok. 41 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 20.21s

With the recent changes we can now test both the Esplora HTTP backends
individually. Configure the CI pipeline to run test for both `ureq` and
`reqwest` Esplora blockchain backends.
@tchardingtcharding mentioned this pull request Sep 2, 2021
9 tasks
@RCasatta

Copy link
Copy Markdown
Contributor

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

You have to give the right initial namespace, for example:

cargo test --no-default-features --features test-esplora,use-esplora-ureq blockchain::esplora

toolchain: stable
override: true
- name: Test
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests

@notmandatorynotmandatorySep 3, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @RCasatta suggested, this will work:

Suggested change
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::${{ matrix.backend.name }}::bdk_blockchain_tests

Or I think the better solution is to move the below chunk to esplora/mod.rs and remove it from reqwest.rs and ureq.rs (I confirmed it works):

#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {
fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
}
}

And then the above CI line does not need to change.

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK.

Agreed with the concept that reqwest user should not have to have tokio just for testing.

All the tests passes as expected.

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.
Cargo.lock after build:

...
[[package]]
name = "tokio"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"pin-project-lite",
"tokio-macros",
"winapi 0.3.9",
]
[[package]]
name = "tokio-macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]

I am not entirely sure whether there is any difference between "hard dependency" and "dependency of a dependency". Just by looking at Cargo.locks from builds of both #433 and #430, it seems like it doesn't matter to our dependency tree. tokio is gonna be there in release mode whether we ask for it or not. reqwest depends on it (among few other crates).

Another minor concern I have is over code repetition. And there is really no other workaround if we choose not use await_or_block!() macro. This might create maintenance burden. But good thing is at least they are in testsutils only.

So far I haven't able to form any hard opinion on either approach. I think we should choose whichever makes our lives easier down the line. Maintaining a consistent async interfaces is a tricky thing for sure.

@LLFourn

Copy link
Copy Markdown
Collaborator

I just had a chat with @tcharding where we tried to come up with a way around the sprawling complexity of having multiple http backends. The result of the discussion was something like why not just have our own HttpClient and implement both async and non-async versions. This would just include get, post methods and return the body a Result<Vec<u8>, HttpError>

In blockchain tests we would only use the blocking one and therefore not test request there. However the only logic in the http backend would be making a http request and returning the result so there is no real reason to test this as there is no business logic.

At this point I think HttpClient should be a trait and esplora would use it like Esplora<C: HttpClient>. This also enables BYO http client (I know of one person who said they want this). This would make the http client a separate choice for the user to consider which might make the feature flags more coherent anyway.

I think I will take on this work myself starting next week if nobody has any objections.

@LLFourn

Copy link
Copy Markdown
Collaborator

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.

note that reqwest has a hard dependency on tokio so this is what you should see.

@notmandatory

Copy link
Copy Markdown
Member

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

@LLFourn

LLFourn commented Sep 8, 2021

Copy link
Copy Markdown
Collaborator

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

My idea would be to have a http-client-blocking and http-client-async features and ureq and reqwest would not be re-exported anywhere at all in the api. bdk-cli would not have to worry at all about this (much) but downstream crates would have to have their own http dependency if they need to make http requests which I think is fine.

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

yes

@tcharding
tcharding marked this pull request as draft September 8, 2021 22:21
@tcharding

Copy link
Copy Markdown
ContributorAuthor

Converted this to draft while development of the proposed HttpClient takes place. Cheers.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

@tcharding

Copy link
Copy Markdown
ContributorAuthor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

Go for it

@tcharding

tcharding commented Nov 5, 2021

Copy link
Copy Markdown
ContributorAuthor

I think we can close this now, no further progress or discussion on this PR seems necessary.

@tcharding
tcharding deleted the fix-esplora-testing branch October 13, 2023 00:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@tcharding@notmandatory@RCasatta@LLFourn@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix esplora testing - #433

Closed
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing
Closed

Fix esplora testing#433
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing

Conversation

@tcharding

@tchardingtcharding commented Aug 31, 2021

Copy link
Copy Markdown
Contributor

Description

Currently testing of esplora/reqwest is broken because of incorrect usage of, or lack of, async.

Enable testing of esplora/reqwest by using maybe_await! macro in tests and declaring all unit tests in blockchain_tests.rs to be async. This adds a dev dependency on tokio.

With this patch applied one can successfully run:

cargo test --features=test-esplora,use-esplora-reqwest --no-default-features

Notes to the reviewers

This is, in my opinion, a better fix to #431 than #430 (i.e., supercedes #430)

The primary advantage of this PR over #430 is it does not introduce a hard dependency on tokio.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

Currently the esplora module testing is broken.
Enable testing of the esplora/ureq features, with this patch applied one
can run:
cargo test --features=test-esplora,use-esplora-ureq --no-default-features
Note, testing of esplora/reqwest is currently broken.
Currently testing of esplora/reqwest is broken because of incorrect
usage of, or lack of, `async`.
Enable testing of esplora/reqwest by using `maybe_await!` macro in tests
and declaring all unit tests in `blockchain_tests.rs` to be async. This
adds a dev dependency on `tokio`.
With this patch applied one can successfully run:
cargo test --features=test-esplora,use-esplora-reqwest --no-default-features
@notmandatory

Copy link
Copy Markdown
Member

This also looks like a good approach. Either way I agree if we only need tokio for testing it should be a dev-dependency. This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest, I think can copy from @rajarshimaitra PR. I'll check it out more closely tomorrow for a proper review.


#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to move this to esplora/mod.rs as in your original #415 (and remove from esplora/reqwest.rs).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to be able to test both eslpora/reqwest and esplora/ureq we need this to be in the ureq/reqwest submodules. I originally only put it in mod.rs thinking testing both was unnecessary, in hindsight this was wrong. With this change testing can be done by enabling feature test-esplora as well as the feature to enable the backend we want to test (e.g. use-esplora-reqwest).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I locally tried moving this chunk to esplora/mod.rs and removing from reqwest.rs and ureq.rs and tests run fine with these commands:

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
cargo test --no-default-features --features test-esplora,use-esplora-reqwest esplora::bdk_blockchain_tests

@tcharding

Copy link
Copy Markdown
ContributorAuthor

This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest

Oh, yes, my bad. Will add, thanks.

@tcharding

tcharding commented Sep 2, 2021

Copy link
Copy Markdown
ContributorAuthor

Patch 655560f Enable testing Esplora backends in CI needs careful review please. The patch is pure cargo cult programing.

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
Finished test [unoptimized + debuginfo] target(s) in 0.05s
Running unittests (/home/tobin/.cache/cargo/debug/deps/bdk-0eaddf4dc688116f)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 213 filtered out; finished in 0.00s

And without the test filter I get just the unit tests running

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
...
test result: ok. 41 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 20.21s

With the recent changes we can now test both the Esplora HTTP backends
individually. Configure the CI pipeline to run test for both `ureq` and
`reqwest` Esplora blockchain backends.
@tchardingtcharding mentioned this pull request Sep 2, 2021
9 tasks
@RCasatta

Copy link
Copy Markdown
Contributor

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

You have to give the right initial namespace, for example:

cargo test --no-default-features --features test-esplora,use-esplora-ureq blockchain::esplora

toolchain: stable
override: true
- name: Test
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests

@notmandatorynotmandatorySep 3, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @RCasatta suggested, this will work:

Suggested change
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::${{ matrix.backend.name }}::bdk_blockchain_tests

Or I think the better solution is to move the below chunk to esplora/mod.rs and remove it from reqwest.rs and ureq.rs (I confirmed it works):

#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {
fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
}
}

And then the above CI line does not need to change.

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK.

Agreed with the concept that reqwest user should not have to have tokio just for testing.

All the tests passes as expected.

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.
Cargo.lock after build:

...
[[package]]
name = "tokio"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"pin-project-lite",
"tokio-macros",
"winapi 0.3.9",
]
[[package]]
name = "tokio-macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]

I am not entirely sure whether there is any difference between "hard dependency" and "dependency of a dependency". Just by looking at Cargo.locks from builds of both #433 and #430, it seems like it doesn't matter to our dependency tree. tokio is gonna be there in release mode whether we ask for it or not. reqwest depends on it (among few other crates).

Another minor concern I have is over code repetition. And there is really no other workaround if we choose not use await_or_block!() macro. This might create maintenance burden. But good thing is at least they are in testsutils only.

So far I haven't able to form any hard opinion on either approach. I think we should choose whichever makes our lives easier down the line. Maintaining a consistent async interfaces is a tricky thing for sure.

@LLFourn

Copy link
Copy Markdown
Collaborator

I just had a chat with @tcharding where we tried to come up with a way around the sprawling complexity of having multiple http backends. The result of the discussion was something like why not just have our own HttpClient and implement both async and non-async versions. This would just include get, post methods and return the body a Result<Vec<u8>, HttpError>

In blockchain tests we would only use the blocking one and therefore not test request there. However the only logic in the http backend would be making a http request and returning the result so there is no real reason to test this as there is no business logic.

At this point I think HttpClient should be a trait and esplora would use it like Esplora<C: HttpClient>. This also enables BYO http client (I know of one person who said they want this). This would make the http client a separate choice for the user to consider which might make the feature flags more coherent anyway.

I think I will take on this work myself starting next week if nobody has any objections.

@LLFourn

Copy link
Copy Markdown
Collaborator

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.

note that reqwest has a hard dependency on tokio so this is what you should see.

@notmandatory

Copy link
Copy Markdown
Member

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

@LLFourn

LLFourn commented Sep 8, 2021

Copy link
Copy Markdown
Collaborator

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

My idea would be to have a http-client-blocking and http-client-async features and ureq and reqwest would not be re-exported anywhere at all in the api. bdk-cli would not have to worry at all about this (much) but downstream crates would have to have their own http dependency if they need to make http requests which I think is fine.

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

yes

@tcharding
tcharding marked this pull request as draft September 8, 2021 22:21
@tcharding

Copy link
Copy Markdown
ContributorAuthor

Converted this to draft while development of the proposed HttpClient takes place. Cheers.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

@tcharding

Copy link
Copy Markdown
ContributorAuthor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

Go for it

@tcharding

tcharding commented Nov 5, 2021

Copy link
Copy Markdown
ContributorAuthor

I think we can close this now, no further progress or discussion on this PR seems necessary.

@tcharding
tcharding deleted the fix-esplora-testing branch October 13, 2023 00:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@tcharding@notmandatory@RCasatta@LLFourn@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Fix esplora testing - #433

Closed
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing
Closed

Fix esplora testing#433
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing

Conversation

@tcharding

@tchardingtcharding commented Aug 31, 2021

Copy link
Copy Markdown
Contributor

Description

Currently testing of esplora/reqwest is broken because of incorrect usage of, or lack of, async.

Enable testing of esplora/reqwest by using maybe_await! macro in tests and declaring all unit tests in blockchain_tests.rs to be async. This adds a dev dependency on tokio.

With this patch applied one can successfully run:

cargo test --features=test-esplora,use-esplora-reqwest --no-default-features

Notes to the reviewers

This is, in my opinion, a better fix to #431 than #430 (i.e., supercedes #430)

The primary advantage of this PR over #430 is it does not introduce a hard dependency on tokio.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

Currently the esplora module testing is broken.
Enable testing of the esplora/ureq features, with this patch applied one
can run:
cargo test --features=test-esplora,use-esplora-ureq --no-default-features
Note, testing of esplora/reqwest is currently broken.
Currently testing of esplora/reqwest is broken because of incorrect
usage of, or lack of, `async`.
Enable testing of esplora/reqwest by using `maybe_await!` macro in tests
and declaring all unit tests in `blockchain_tests.rs` to be async. This
adds a dev dependency on `tokio`.
With this patch applied one can successfully run:
cargo test --features=test-esplora,use-esplora-reqwest --no-default-features
@notmandatory

Copy link
Copy Markdown
Member

This also looks like a good approach. Either way I agree if we only need tokio for testing it should be a dev-dependency. This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest, I think can copy from @rajarshimaitra PR. I'll check it out more closely tomorrow for a proper review.


#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to move this to esplora/mod.rs as in your original #415 (and remove from esplora/reqwest.rs).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to be able to test both eslpora/reqwest and esplora/ureq we need this to be in the ureq/reqwest submodules. I originally only put it in mod.rs thinking testing both was unnecessary, in hindsight this was wrong. With this change testing can be done by enabling feature test-esplora as well as the feature to enable the backend we want to test (e.g. use-esplora-reqwest).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I locally tried moving this chunk to esplora/mod.rs and removing from reqwest.rs and ureq.rs and tests run fine with these commands:

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
cargo test --no-default-features --features test-esplora,use-esplora-reqwest esplora::bdk_blockchain_tests

@tcharding

Copy link
Copy Markdown
ContributorAuthor

This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest

Oh, yes, my bad. Will add, thanks.

@tcharding

tcharding commented Sep 2, 2021

Copy link
Copy Markdown
ContributorAuthor

Patch 655560f Enable testing Esplora backends in CI needs careful review please. The patch is pure cargo cult programing.

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
Finished test [unoptimized + debuginfo] target(s) in 0.05s
Running unittests (/home/tobin/.cache/cargo/debug/deps/bdk-0eaddf4dc688116f)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 213 filtered out; finished in 0.00s

And without the test filter I get just the unit tests running

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
...
test result: ok. 41 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 20.21s

With the recent changes we can now test both the Esplora HTTP backends
individually. Configure the CI pipeline to run test for both `ureq` and
`reqwest` Esplora blockchain backends.
@tchardingtcharding mentioned this pull request Sep 2, 2021
9 tasks
@RCasatta

Copy link
Copy Markdown
Contributor

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

You have to give the right initial namespace, for example:

cargo test --no-default-features --features test-esplora,use-esplora-ureq blockchain::esplora

toolchain: stable
override: true
- name: Test
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests

@notmandatorynotmandatorySep 3, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @RCasatta suggested, this will work:

Suggested change
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::${{ matrix.backend.name }}::bdk_blockchain_tests

Or I think the better solution is to move the below chunk to esplora/mod.rs and remove it from reqwest.rs and ureq.rs (I confirmed it works):

#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {
fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
}
}

And then the above CI line does not need to change.

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK.

Agreed with the concept that reqwest user should not have to have tokio just for testing.

All the tests passes as expected.

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.
Cargo.lock after build:

...
[[package]]
name = "tokio"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"pin-project-lite",
"tokio-macros",
"winapi 0.3.9",
]
[[package]]
name = "tokio-macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]

I am not entirely sure whether there is any difference between "hard dependency" and "dependency of a dependency". Just by looking at Cargo.locks from builds of both #433 and #430, it seems like it doesn't matter to our dependency tree. tokio is gonna be there in release mode whether we ask for it or not. reqwest depends on it (among few other crates).

Another minor concern I have is over code repetition. And there is really no other workaround if we choose not use await_or_block!() macro. This might create maintenance burden. But good thing is at least they are in testsutils only.

So far I haven't able to form any hard opinion on either approach. I think we should choose whichever makes our lives easier down the line. Maintaining a consistent async interfaces is a tricky thing for sure.

@LLFourn

Copy link
Copy Markdown
Collaborator

I just had a chat with @tcharding where we tried to come up with a way around the sprawling complexity of having multiple http backends. The result of the discussion was something like why not just have our own HttpClient and implement both async and non-async versions. This would just include get, post methods and return the body a Result<Vec<u8>, HttpError>

In blockchain tests we would only use the blocking one and therefore not test request there. However the only logic in the http backend would be making a http request and returning the result so there is no real reason to test this as there is no business logic.

At this point I think HttpClient should be a trait and esplora would use it like Esplora<C: HttpClient>. This also enables BYO http client (I know of one person who said they want this). This would make the http client a separate choice for the user to consider which might make the feature flags more coherent anyway.

I think I will take on this work myself starting next week if nobody has any objections.

@LLFourn

Copy link
Copy Markdown
Collaborator

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.

note that reqwest has a hard dependency on tokio so this is what you should see.

@notmandatory

Copy link
Copy Markdown
Member

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

@LLFourn

LLFourn commented Sep 8, 2021

Copy link
Copy Markdown
Collaborator

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

My idea would be to have a http-client-blocking and http-client-async features and ureq and reqwest would not be re-exported anywhere at all in the api. bdk-cli would not have to worry at all about this (much) but downstream crates would have to have their own http dependency if they need to make http requests which I think is fine.

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

yes

@tcharding
tcharding marked this pull request as draft September 8, 2021 22:21
@tcharding

Copy link
Copy Markdown
ContributorAuthor

Converted this to draft while development of the proposed HttpClient takes place. Cheers.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

@tcharding

Copy link
Copy Markdown
ContributorAuthor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

Go for it

@tcharding

tcharding commented Nov 5, 2021

Copy link
Copy Markdown
ContributorAuthor

I think we can close this now, no further progress or discussion on this PR seems necessary.

@tcharding
tcharding deleted the fix-esplora-testing branch October 13, 2023 00:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@tcharding@notmandatory@RCasatta@LLFourn@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix esplora testing - #433

Closed
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing
Closed

Fix esplora testing#433
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing

Conversation

@tcharding

@tchardingtcharding commented Aug 31, 2021

Copy link
Copy Markdown
Contributor

Description

Currently testing of esplora/reqwest is broken because of incorrect usage of, or lack of, async.

Enable testing of esplora/reqwest by using maybe_await! macro in tests and declaring all unit tests in blockchain_tests.rs to be async. This adds a dev dependency on tokio.

With this patch applied one can successfully run:

cargo test --features=test-esplora,use-esplora-reqwest --no-default-features

Notes to the reviewers

This is, in my opinion, a better fix to #431 than #430 (i.e., supercedes #430)

The primary advantage of this PR over #430 is it does not introduce a hard dependency on tokio.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

Currently the esplora module testing is broken.
Enable testing of the esplora/ureq features, with this patch applied one
can run:
cargo test --features=test-esplora,use-esplora-ureq --no-default-features
Note, testing of esplora/reqwest is currently broken.
Currently testing of esplora/reqwest is broken because of incorrect
usage of, or lack of, `async`.
Enable testing of esplora/reqwest by using `maybe_await!` macro in tests
and declaring all unit tests in `blockchain_tests.rs` to be async. This
adds a dev dependency on `tokio`.
With this patch applied one can successfully run:
cargo test --features=test-esplora,use-esplora-reqwest --no-default-features
@notmandatory

Copy link
Copy Markdown
Member

This also looks like a good approach. Either way I agree if we only need tokio for testing it should be a dev-dependency. This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest, I think can copy from @rajarshimaitra PR. I'll check it out more closely tomorrow for a proper review.


#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to move this to esplora/mod.rs as in your original #415 (and remove from esplora/reqwest.rs).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to be able to test both eslpora/reqwest and esplora/ureq we need this to be in the ureq/reqwest submodules. I originally only put it in mod.rs thinking testing both was unnecessary, in hindsight this was wrong. With this change testing can be done by enabling feature test-esplora as well as the feature to enable the backend we want to test (e.g. use-esplora-reqwest).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I locally tried moving this chunk to esplora/mod.rs and removing from reqwest.rs and ureq.rs and tests run fine with these commands:

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
cargo test --no-default-features --features test-esplora,use-esplora-reqwest esplora::bdk_blockchain_tests

@tcharding

Copy link
Copy Markdown
ContributorAuthor

This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest

Oh, yes, my bad. Will add, thanks.

@tcharding

tcharding commented Sep 2, 2021

Copy link
Copy Markdown
ContributorAuthor

Patch 655560f Enable testing Esplora backends in CI needs careful review please. The patch is pure cargo cult programing.

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
Finished test [unoptimized + debuginfo] target(s) in 0.05s
Running unittests (/home/tobin/.cache/cargo/debug/deps/bdk-0eaddf4dc688116f)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 213 filtered out; finished in 0.00s

And without the test filter I get just the unit tests running

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
...
test result: ok. 41 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 20.21s

With the recent changes we can now test both the Esplora HTTP backends
individually. Configure the CI pipeline to run test for both `ureq` and
`reqwest` Esplora blockchain backends.
@tchardingtcharding mentioned this pull request Sep 2, 2021
9 tasks
@RCasatta

Copy link
Copy Markdown
Contributor

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

You have to give the right initial namespace, for example:

cargo test --no-default-features --features test-esplora,use-esplora-ureq blockchain::esplora

toolchain: stable
override: true
- name: Test
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests

@notmandatorynotmandatorySep 3, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @RCasatta suggested, this will work:

Suggested change
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::${{ matrix.backend.name }}::bdk_blockchain_tests

Or I think the better solution is to move the below chunk to esplora/mod.rs and remove it from reqwest.rs and ureq.rs (I confirmed it works):

#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {
fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
}
}

And then the above CI line does not need to change.

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK.

Agreed with the concept that reqwest user should not have to have tokio just for testing.

All the tests passes as expected.

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.
Cargo.lock after build:

...
[[package]]
name = "tokio"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"pin-project-lite",
"tokio-macros",
"winapi 0.3.9",
]
[[package]]
name = "tokio-macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]

I am not entirely sure whether there is any difference between "hard dependency" and "dependency of a dependency". Just by looking at Cargo.locks from builds of both #433 and #430, it seems like it doesn't matter to our dependency tree. tokio is gonna be there in release mode whether we ask for it or not. reqwest depends on it (among few other crates).

Another minor concern I have is over code repetition. And there is really no other workaround if we choose not use await_or_block!() macro. This might create maintenance burden. But good thing is at least they are in testsutils only.

So far I haven't able to form any hard opinion on either approach. I think we should choose whichever makes our lives easier down the line. Maintaining a consistent async interfaces is a tricky thing for sure.

@LLFourn

Copy link
Copy Markdown
Collaborator

I just had a chat with @tcharding where we tried to come up with a way around the sprawling complexity of having multiple http backends. The result of the discussion was something like why not just have our own HttpClient and implement both async and non-async versions. This would just include get, post methods and return the body a Result<Vec<u8>, HttpError>

In blockchain tests we would only use the blocking one and therefore not test request there. However the only logic in the http backend would be making a http request and returning the result so there is no real reason to test this as there is no business logic.

At this point I think HttpClient should be a trait and esplora would use it like Esplora<C: HttpClient>. This also enables BYO http client (I know of one person who said they want this). This would make the http client a separate choice for the user to consider which might make the feature flags more coherent anyway.

I think I will take on this work myself starting next week if nobody has any objections.

@LLFourn

Copy link
Copy Markdown
Collaborator

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.

note that reqwest has a hard dependency on tokio so this is what you should see.

@notmandatory

Copy link
Copy Markdown
Member

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

@LLFourn

LLFourn commented Sep 8, 2021

Copy link
Copy Markdown
Collaborator

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

My idea would be to have a http-client-blocking and http-client-async features and ureq and reqwest would not be re-exported anywhere at all in the api. bdk-cli would not have to worry at all about this (much) but downstream crates would have to have their own http dependency if they need to make http requests which I think is fine.

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

yes

@tcharding
tcharding marked this pull request as draft September 8, 2021 22:21
@tcharding

Copy link
Copy Markdown
ContributorAuthor

Converted this to draft while development of the proposed HttpClient takes place. Cheers.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

@tcharding

Copy link
Copy Markdown
ContributorAuthor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

Go for it

@tcharding

tcharding commented Nov 5, 2021

Copy link
Copy Markdown
ContributorAuthor

I think we can close this now, no further progress or discussion on this PR seems necessary.

@tcharding
tcharding deleted the fix-esplora-testing branch October 13, 2023 00:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@tcharding@notmandatory@RCasatta@LLFourn@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Fix esplora testing - #433

Closed
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing
Closed

Fix esplora testing#433
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing

Conversation

@tcharding

@tchardingtcharding commented Aug 31, 2021

Copy link
Copy Markdown
Contributor

Description

Currently testing of esplora/reqwest is broken because of incorrect usage of, or lack of, async.

Enable testing of esplora/reqwest by using maybe_await! macro in tests and declaring all unit tests in blockchain_tests.rs to be async. This adds a dev dependency on tokio.

With this patch applied one can successfully run:

cargo test --features=test-esplora,use-esplora-reqwest --no-default-features

Notes to the reviewers

This is, in my opinion, a better fix to #431 than #430 (i.e., supercedes #430)

The primary advantage of this PR over #430 is it does not introduce a hard dependency on tokio.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

Currently the esplora module testing is broken.
Enable testing of the esplora/ureq features, with this patch applied one
can run:
cargo test --features=test-esplora,use-esplora-ureq --no-default-features
Note, testing of esplora/reqwest is currently broken.
Currently testing of esplora/reqwest is broken because of incorrect
usage of, or lack of, `async`.
Enable testing of esplora/reqwest by using `maybe_await!` macro in tests
and declaring all unit tests in `blockchain_tests.rs` to be async. This
adds a dev dependency on `tokio`.
With this patch applied one can successfully run:
cargo test --features=test-esplora,use-esplora-reqwest --no-default-features
@notmandatory

Copy link
Copy Markdown
Member

This also looks like a good approach. Either way I agree if we only need tokio for testing it should be a dev-dependency. This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest, I think can copy from @rajarshimaitra PR. I'll check it out more closely tomorrow for a proper review.


#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to move this to esplora/mod.rs as in your original #415 (and remove from esplora/reqwest.rs).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to be able to test both eslpora/reqwest and esplora/ureq we need this to be in the ureq/reqwest submodules. I originally only put it in mod.rs thinking testing both was unnecessary, in hindsight this was wrong. With this change testing can be done by enabling feature test-esplora as well as the feature to enable the backend we want to test (e.g. use-esplora-reqwest).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I locally tried moving this chunk to esplora/mod.rs and removing from reqwest.rs and ureq.rs and tests run fine with these commands:

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
cargo test --no-default-features --features test-esplora,use-esplora-reqwest esplora::bdk_blockchain_tests

@tcharding

Copy link
Copy Markdown
ContributorAuthor

This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest

Oh, yes, my bad. Will add, thanks.

@tcharding

tcharding commented Sep 2, 2021

Copy link
Copy Markdown
ContributorAuthor

Patch 655560f Enable testing Esplora backends in CI needs careful review please. The patch is pure cargo cult programing.

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
Finished test [unoptimized + debuginfo] target(s) in 0.05s
Running unittests (/home/tobin/.cache/cargo/debug/deps/bdk-0eaddf4dc688116f)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 213 filtered out; finished in 0.00s

And without the test filter I get just the unit tests running

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
...
test result: ok. 41 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 20.21s

With the recent changes we can now test both the Esplora HTTP backends
individually. Configure the CI pipeline to run test for both `ureq` and
`reqwest` Esplora blockchain backends.
@tchardingtcharding mentioned this pull request Sep 2, 2021
9 tasks
@RCasatta

Copy link
Copy Markdown
Contributor

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

You have to give the right initial namespace, for example:

cargo test --no-default-features --features test-esplora,use-esplora-ureq blockchain::esplora

toolchain: stable
override: true
- name: Test
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests

@notmandatorynotmandatorySep 3, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @RCasatta suggested, this will work:

Suggested change
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::${{ matrix.backend.name }}::bdk_blockchain_tests

Or I think the better solution is to move the below chunk to esplora/mod.rs and remove it from reqwest.rs and ureq.rs (I confirmed it works):

#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {
fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
}
}

And then the above CI line does not need to change.

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK.

Agreed with the concept that reqwest user should not have to have tokio just for testing.

All the tests passes as expected.

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.
Cargo.lock after build:

...
[[package]]
name = "tokio"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"pin-project-lite",
"tokio-macros",
"winapi 0.3.9",
]
[[package]]
name = "tokio-macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]

I am not entirely sure whether there is any difference between "hard dependency" and "dependency of a dependency". Just by looking at Cargo.locks from builds of both #433 and #430, it seems like it doesn't matter to our dependency tree. tokio is gonna be there in release mode whether we ask for it or not. reqwest depends on it (among few other crates).

Another minor concern I have is over code repetition. And there is really no other workaround if we choose not use await_or_block!() macro. This might create maintenance burden. But good thing is at least they are in testsutils only.

So far I haven't able to form any hard opinion on either approach. I think we should choose whichever makes our lives easier down the line. Maintaining a consistent async interfaces is a tricky thing for sure.

@LLFourn

Copy link
Copy Markdown
Collaborator

I just had a chat with @tcharding where we tried to come up with a way around the sprawling complexity of having multiple http backends. The result of the discussion was something like why not just have our own HttpClient and implement both async and non-async versions. This would just include get, post methods and return the body a Result<Vec<u8>, HttpError>

In blockchain tests we would only use the blocking one and therefore not test request there. However the only logic in the http backend would be making a http request and returning the result so there is no real reason to test this as there is no business logic.

At this point I think HttpClient should be a trait and esplora would use it like Esplora<C: HttpClient>. This also enables BYO http client (I know of one person who said they want this). This would make the http client a separate choice for the user to consider which might make the feature flags more coherent anyway.

I think I will take on this work myself starting next week if nobody has any objections.

@LLFourn

Copy link
Copy Markdown
Collaborator

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.

note that reqwest has a hard dependency on tokio so this is what you should see.

@notmandatory

Copy link
Copy Markdown
Member

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

@LLFourn

LLFourn commented Sep 8, 2021

Copy link
Copy Markdown
Collaborator

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

My idea would be to have a http-client-blocking and http-client-async features and ureq and reqwest would not be re-exported anywhere at all in the api. bdk-cli would not have to worry at all about this (much) but downstream crates would have to have their own http dependency if they need to make http requests which I think is fine.

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

yes

@tcharding
tcharding marked this pull request as draft September 8, 2021 22:21
@tcharding

Copy link
Copy Markdown
ContributorAuthor

Converted this to draft while development of the proposed HttpClient takes place. Cheers.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

@tcharding

Copy link
Copy Markdown
ContributorAuthor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

Go for it

@tcharding

tcharding commented Nov 5, 2021

Copy link
Copy Markdown
ContributorAuthor

I think we can close this now, no further progress or discussion on this PR seems necessary.

@tcharding
tcharding deleted the fix-esplora-testing branch October 13, 2023 00:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@tcharding@notmandatory@RCasatta@LLFourn@rajarshimaitra
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Fix esplora testing - #433

Closed
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing
Closed

Fix esplora testing#433
tcharding wants to merge 3 commits into
bitcoindevkit:masterfrom
tcharding:fix-esplora-testing

Conversation

@tcharding

@tchardingtcharding commented Aug 31, 2021

Copy link
Copy Markdown
Contributor

Description

Currently testing of esplora/reqwest is broken because of incorrect usage of, or lack of, async.

Enable testing of esplora/reqwest by using maybe_await! macro in tests and declaring all unit tests in blockchain_tests.rs to be async. This adds a dev dependency on tokio.

With this patch applied one can successfully run:

cargo test --features=test-esplora,use-esplora-reqwest --no-default-features

Notes to the reviewers

This is, in my opinion, a better fix to #431 than #430 (i.e., supercedes #430)

The primary advantage of this PR over #430 is it does not introduce a hard dependency on tokio.

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo fmt and cargo clippy before committing

Bugfixes:

  • This pull request breaks the existing API
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

Currently the esplora module testing is broken.
Enable testing of the esplora/ureq features, with this patch applied one
can run:
cargo test --features=test-esplora,use-esplora-ureq --no-default-features
Note, testing of esplora/reqwest is currently broken.
Currently testing of esplora/reqwest is broken because of incorrect
usage of, or lack of, `async`.
Enable testing of esplora/reqwest by using `maybe_await!` macro in tests
and declaring all unit tests in `blockchain_tests.rs` to be async. This
adds a dev dependency on `tokio`.
With this patch applied one can successfully run:
cargo test --features=test-esplora,use-esplora-reqwest --no-default-features
@notmandatory

Copy link
Copy Markdown
Member

This also looks like a good approach. Either way I agree if we only need tokio for testing it should be a dev-dependency. This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest, I think can copy from @rajarshimaitra PR. I'll check it out more closely tomorrow for a proper review.


#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you meant to move this to esplora/mod.rs as in your original #415 (and remove from esplora/reqwest.rs).

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we want to be able to test both eslpora/reqwest and esplora/ureq we need this to be in the ureq/reqwest submodules. I originally only put it in mod.rs thinking testing both was unnecessary, in hindsight this was wrong. With this change testing can be done by enabling feature test-esplora as well as the feature to enable the backend we want to test (e.g. use-esplora-reqwest).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I locally tried moving this chunk to esplora/mod.rs and removing from reqwest.rs and ureq.rs and tests run fine with these commands:

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
cargo test --no-default-features --features test-esplora,use-esplora-reqwest esplora::bdk_blockchain_tests

@tcharding

Copy link
Copy Markdown
ContributorAuthor

This PR also needs to have the CI pipeline updated to run the blockchain tests for esplora with ureq and reqwest

Oh, yes, my bad. Will add, thanks.

@tcharding

tcharding commented Sep 2, 2021

Copy link
Copy Markdown
ContributorAuthor

Patch 655560f Enable testing Esplora backends in CI needs careful review please. The patch is pure cargo cult programing.

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
Finished test [unoptimized + debuginfo] target(s) in 0.05s
Running unittests (/home/tobin/.cache/cargo/debug/deps/bdk-0eaddf4dc688116f)
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 213 filtered out; finished in 0.00s

And without the test filter I get just the unit tests running

cargo test --no-default-features --features test-esplora,use-esplora-ureq esplora::bdk_blockchain_tests
...
test result: ok. 41 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 20.21s

With the recent changes we can now test both the Esplora HTTP backends
individually. Configure the CI pipeline to run test for both `ureq` and
`reqwest` Esplora blockchain backends.
@tchardingtcharding mentioned this pull request Sep 2, 2021
9 tasks
@RCasatta

Copy link
Copy Markdown
Contributor

When I attempt to run the esplora integration test as it appears it will be run on CI, nothing runs?

You have to give the right initial namespace, for example:

cargo test --no-default-features --features test-esplora,use-esplora-ureq blockchain::esplora

toolchain: stable
override: true
- name: Test
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests

@notmandatorynotmandatorySep 3, 2021

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As @RCasatta suggested, this will work:

Suggested change
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::bdk_blockchain_tests
run: cargo test --no-default-features --features test-esplora,use-esplora-${{ matrix.backend.name }} esplora::${{ matrix.backend.name }}::bdk_blockchain_tests

Or I think the better solution is to move the below chunk to esplora/mod.rs and remove it from reqwest.rs and ureq.rs (I confirmed it works):

#[cfg(test)]
#[cfg(feature = "test-esplora")]
crate::bdk_blockchain_tests! {
fn test_instance(test_client: &TestClient) -> EsploraBlockchain {
EsploraBlockchain::new(&format!("http://{}",test_client.electrsd.esplora_url.as_ref().unwrap()), 20)
}
}

And then the above CI line does not need to change.

@rajarshimaitrarajarshimaitra left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tACK.

Agreed with the concept that reqwest user should not have to have tokio just for testing.

All the tests passes as expected.

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.
Cargo.lock after build:

...
[[package]]
name = "tokio"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "570c2eb13b3ab38208130eccd41be92520388791207fde783bda7c1e8ace28d4"
dependencies = [
"autocfg",
"bytes",
"libc",
"memchr",
"mio",
"pin-project-lite",
"tokio-macros",
"winapi 0.3.9",
]
[[package]]
name = "tokio-macros"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"log",
"pin-project-lite",
"tokio",
]

I am not entirely sure whether there is any difference between "hard dependency" and "dependency of a dependency". Just by looking at Cargo.locks from builds of both #433 and #430, it seems like it doesn't matter to our dependency tree. tokio is gonna be there in release mode whether we ask for it or not. reqwest depends on it (among few other crates).

Another minor concern I have is over code repetition. And there is really no other workaround if we choose not use await_or_block!() macro. This might create maintenance burden. But good thing is at least they are in testsutils only.

So far I haven't able to form any hard opinion on either approach. I think we should choose whichever makes our lives easier down the line. Maintaining a consistent async interfaces is a tricky thing for sure.

@LLFourn

Copy link
Copy Markdown
Collaborator

I just had a chat with @tcharding where we tried to come up with a way around the sprawling complexity of having multiple http backends. The result of the discussion was something like why not just have our own HttpClient and implement both async and non-async versions. This would just include get, post methods and return the body a Result<Vec<u8>, HttpError>

In blockchain tests we would only use the blocking one and therefore not test request there. However the only logic in the http backend would be making a http request and returning the result so there is no real reason to test this as there is no business logic.

At this point I think HttpClient should be a trait and esplora would use it like Esplora<C: HttpClient>. This also enables BYO http client (I know of one person who said they want this). This would make the http client a separate choice for the user to consider which might make the feature flags more coherent anyway.

I think I will take on this work myself starting next week if nobody has any objections.

@LLFourn

Copy link
Copy Markdown
Collaborator

I am observing though, even in a release build cargo build --release --features=use-esplora-reqwest --no-default-features, tokio dependencies are still in the dependency tree because other dependencies already use it.

note that reqwest has a hard dependency on tokio so this is what you should see.

@notmandatory

Copy link
Copy Markdown
Member

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

@LLFourn

LLFourn commented Sep 8, 2021

Copy link
Copy Markdown
Collaborator

I think an HttpClient trait in the esplora module sounds like a good way decouple things, similar to having a Database trait with different backends. In this case will bdk still offer optional esplora-ureq or esplora-reqwest features? or will we just include the ureq as dev-dependencies for the esplora blockchain tests? and in this case an end user (like bdk-cli) would implement it's own ureq based (or which ever) HttpClient?

My idea would be to have a http-client-blocking and http-client-async features and ureq and reqwest would not be re-exported anywhere at all in the api. bdk-cli would not have to worry at all about this (much) but downstream crates would have to have their own http dependency if they need to make http requests which I think is fine.

One other thing to keep in mind for the HttpClient trait is to support socks5 proxies, see #429.

yes

@tcharding
tcharding marked this pull request as draft September 8, 2021 22:21
@tcharding

Copy link
Copy Markdown
ContributorAuthor

Converted this to draft while development of the proposed HttpClient takes place. Cheers.

@rajarshimaitra

Copy link
Copy Markdown
Contributor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

@tcharding

Copy link
Copy Markdown
ContributorAuthor

Since this is converted into draft can we have #430 merged for the mean time? I have some downstream bdk-cli PRs pending on the esplora fix.

Go for it

@tcharding

tcharding commented Nov 5, 2021

Copy link
Copy Markdown
ContributorAuthor

I think we can close this now, no further progress or discussion on this PR seems necessary.

@tcharding
tcharding deleted the fix-esplora-testing branch October 13, 2023 00:41
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

@tcharding@notmandatory@RCasatta@LLFourn@rajarshimaitra