Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

GUILD-619: Test helpers don't automatically reset to test config #120

Merged
merged 12 commits into from
Aug 12, 2021
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## UNRELEASED
### Roadmap :car:

- TestHelper does not automatically reset Deimos config before each test. [#120](https://github.com/flipp-oss/deimos/pull/120)
Copy link
Member

Choose a reason for hiding this comment

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

Should call out in bold that this is a breaking change.


## 1.10.0 - 2021-03-22

Expand Down
35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Built on Phobos and hence Ruby-Kafka.
* [Running Consumers](#running-consumers)
* [Metrics](#metrics)
* [Testing](#testing)
* [Default Deimos config for testing](#default-deimos-config-for-testing)
* [Integration Test Helpers](#integration-test-helpers)
* [Utilities](#utilities)
* [Contributing](#contributing)
Expand Down Expand Up @@ -935,6 +936,18 @@ expect(message).to eq({
topic: 'my-topic',
key: 'my-id'
})

## Configuring Deimos to test settings
Copy link
Member

Choose a reason for hiding this comment

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

So this shouldn't be in the code block with everything else because it likely won't be in the test itself. Also, the previous examples in this block will only work if the test producers are being used, so we should call that out and put this explanation before that block.

You can give an example of a spec_helper that does it:

# spec_helper.rb
RSpec.before(:each) do
  configure_deimos
end

Actually, now that I write this, it would be even better if we can allow this method to take a block and reset the config back to what it was. Then you could use it like this:

RSpec.around(:each) do |ex|
  configure_deimos({...}) do
    ex.run
  end

...and we would be able to ensure that config didn't leak past examples, which is something that's bitten me multiple times. You can deep-dup the config and restore it after the block is run.


# You can reset Deimos to default test config by calling this method.
configure_deimos

# The same method can be used to override settings while still using
# deafults for other fields.
configure_deimos(consumers: { reraise_errors: false },
producers: { topic_prefix: nil },
db_producer: { compact_topics: %w(my-topic my-topic2) },
logger: Rails.logger)
Copy link
Member

Choose a reason for hiding this comment

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

Nice, I like this a lot! I think there might be some other changes to the README that are necessary - e.g. we should be calling out things like the test producer and how to interact with it rather than assuming that when you include TestHelpers you get it for free.

Copy link
Member Author

Choose a reason for hiding this comment

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

@dorner I tried my best to add more info but there might be some that I missed and/or added incorrect information. Please let me know!

```

There is also a helper method that will let you test if an existing schema
Expand All @@ -946,6 +959,28 @@ require 'deimos/test_helpers'
# Can pass a file path, a string or a hash into this:
Deimos::TestHelpers.schemas_compatible?(schema1, schema2)
```
### Default Deimos config for testing

The test helper class provides the default settings for Deimos config.
```ruby
# The following are the test defaults for Deimos that are set
# by calling `configure_deimos`
DEFAULT_TEST_CONFIG = {
logger: Logger.new(STDOUT),
consumers: { reraise_errors: true },
kafka: { seed_brokers: ['test_broker'] },
schema: { backend: Deimos.schema_backend_class.mock_backend },
producers: { backend: :test }
}
```
`:test` is the default backend for producers that saves messages
to an in-memory hash. You can access the sent messages by calling
the following function
```ruby
Deimos::Backends::Test.sent_messages
```
Mock schema backend will perform all the validations but not actually encode any messages.


### Integration Test Helpers

Expand Down
41 changes: 31 additions & 10 deletions lib/deimos/test_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,6 @@ def sent_messages

RSpec.configure do |config|

config.before(:suite) do
Deimos.configure do |d_config|
d_config.logger = Logger.new(STDOUT)
d_config.consumers.reraise_errors = true
d_config.kafka.seed_brokers ||= ['test_broker']
d_config.schema.backend = Deimos.schema_backend_class.mock_backend
d_config.producers.backend = :test
end
end

config.prepend_before(:each) do
client = double('client').as_null_object
allow(client).to receive(:time) do |*_args, &block|
Expand All @@ -45,6 +35,37 @@ def sent_messages

end

# Test default for Deimos
DEFAULT_TEST_CONFIG = {
logger: Logger.new(STDOUT),
consumers: { reraise_errors: true },
kafka: { seed_brokers: ['test_broker'] },
schema: { backend: Deimos.schema_backend_class.mock_backend },
producers: { backend: :test }
}.freeze

# Call in your examples to configure Deimos
# @param options <Hash>
def configure_deimos(options={})
# Merge with the test defaults
options = DEFAULT_TEST_CONFIG.deep_merge(options)

Deimos.configure do |d_config|
options.each do |key, value|
# If the config options are nested.
# Assuming that there is only one level of nesting
if value.is_a?(Hash)
value.each do |k, v|
d_config.send(key.to_sym).send(k.to_sym, v)
end
# If the values are not nested, then simply assign them
else
d_config.send(key.to_sym, value)
end
end
end
end

# @deprecated
def stub_producers_and_consumers!
warn('stub_producers_and_consumers! is no longer necessary and this method will be removed in 3.0')
Expand Down