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

Add a filter plugin add_insert_ids. #246

Merged
merged 7 commits into from
Aug 29, 2018
Merged

Add a filter plugin add_insert_ids. #246

merged 7 commits into from
Aug 29, 2018

Conversation

qingling128
Copy link
Contributor

No description provided.

README.rdoc Outdated
of your Fluentd configuration file, for example:

<filter **>
type add_insert_ids
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need a prefixed @?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

expected_insert_id = record[DEFAULT_INSERT_ID_KEY] if index == 0
assert_equal expected_insert_id, record[DEFAULT_INSERT_ID_KEY],
"Index #{index} failed."
expected_insert_id = expected_insert_id.next
Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think about checking to see if this is a unique value instead of mimicking the implementation?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What's a better alternative? I've been contemplating this and ended up adding the following line:

      assert_true record[DEFAULT_INSERT_ID_KEY] < expected_insert_id,
                  "Index #{index} failed. #{record[DEFAULT_INSERT_ID_KEY]}" \
                  " < #{expected_insert_id} is false."

Are you suggesting something like hashing all the insertIds and make sure we have 1000 unique ones?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, hashing or counting a set of distinct values SGTM

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a check against 1000 unique insertIds.

record = event[2]
assert_true record.is_a?(Hash), "Index #{index} failed. Log record" \
' should be a hash.'
assert_equal index, record['id'], "Index #{index} failed."
Copy link
Contributor

Choose a reason for hiding this comment

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

This line seems to be testing the test itself, do we really need it?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This line makes sure the log entries come in order. On top of this we check the insertId is growing. It's meaningful IMO.

Copy link
Contributor

Choose a reason for hiding this comment

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

SGTM

Copy link
Member

Choose a reason for hiding this comment

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

Can we reflect this in the error message?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

def filter(tag, time, record)
# Only generate and add an insertId field If the record is a hash and
# the insert ID field is not already set.
if record.is_a?(Hash) && !record.key?(@insert_id_key)
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we check for empty values as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

is_a? checks that already.

2.4.3 :004 > ''.is_a?(Hash)
 => false
2.4.3 :005 > nil.is_a?(Hash)
 => false

Copy link
Contributor

Choose a reason for hiding this comment

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

Synced offline, checking the actual value within the record to make sure it's not blank. It might be over-optimizing, if the user really wants blank, that would be strange, but maybe it's intentional? I'll let you make the judgement call here as to whether or not blank values are an important scenario to auto-generate ids.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a check against an empty string.

Copy link
Contributor Author

@qingling128 qingling128 left a comment

Choose a reason for hiding this comment

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

PTAL

README.rdoc Outdated
of your Fluentd configuration file, for example:

<filter **>
type add_insert_ids
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

def filter(tag, time, record)
# Only generate and add an insertId field If the record is a hash and
# the insert ID field is not already set.
if record.is_a?(Hash) && !record.key?(@insert_id_key)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

is_a? checks that already.

2.4.3 :004 > ''.is_a?(Hash)
 => false
2.4.3 :005 > nil.is_a?(Hash)
 => false

record = event[2]
assert_true record.is_a?(Hash), "Index #{index} failed. Log record" \
' should be a hash.'
assert_equal index, record['id'], "Index #{index} failed."
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This line makes sure the log entries come in order. On top of this we check the insertId is growing. It's meaningful IMO.

expected_insert_id = record[DEFAULT_INSERT_ID_KEY] if index == 0
assert_equal expected_insert_id, record[DEFAULT_INSERT_ID_KEY],
"Index #{index} failed."
expected_insert_id = expected_insert_id.next
Copy link
Contributor Author

Choose a reason for hiding this comment

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

What's a better alternative? I've been contemplating this and ended up adding the following line:

      assert_true record[DEFAULT_INSERT_ID_KEY] < expected_insert_id,
                  "Index #{index} failed. #{record[DEFAULT_INSERT_ID_KEY]}" \
                  " < #{expected_insert_id} is false."

Are you suggesting something like hashing all the insertIds and make sure we have 1000 unique ones?

README.rdoc Outdated
which sends logs to the
{Stackdriver Logging API}[https://cloud.google.com/logging/docs/api/].
fluent-plugin-google-cloud gem includes two plugins:
1. An {filter plugin for fluentd}[http://docs.fluentd.org/articles/filter-plugin-overview]
Copy link
Contributor

Choose a reason for hiding this comment

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

An -> A

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

README.rdoc Outdated
@@ -23,22 +23,31 @@ will also install and configure the gem.

== Configuration

To embed insertIds into log entries, specify <code>type add_insert_ids</code>
in a {match clause}[http://docs.fluentd.org/articles/config-file#2-ldquomatchrdquo-tell-fluentd-what-to-do]
Copy link
Contributor

@davidbtucker davidbtucker Aug 28, 2018

Choose a reason for hiding this comment

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

Should this be {filter clause}[https://docs.fluentd.org/v1.0/articles/config-file#(3)-%E2%80%9Cfilter%E2%80%9D:-event-processing-pipeline]?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

# The default field name of insertIds in the log entry.
DEFAULT_INSERT_ID_KEY = 'logging.googleapis.com/insertId'.freeze
# The character size of the insertIds. This matches the setup in the
# Stackdriver Logging backend.
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we link to any documentation about this value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I tried. I did not see it anywhere in the public sites. This size was taken from the implementation code. In fact, that's just the default size the backend will generate. It's not a "requirement".

@log.info "Started the add_insert_ids plugin with #{@insert_id_key}" \
' as the insert ID key.'
@insert_id = generate_insert_id
@log.info "Initiated the insert ID key at #{@insert_id}."
Copy link
Contributor

Choose a reason for hiding this comment

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

Initiated -> Initialized?
Also: at -> to

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.


# rubocop:disable Style/UnusedMethodArgument
def filter(tag, time, record)
# Only generate and add an insertId field If the record is a hash and
Copy link
Contributor

Choose a reason for hiding this comment

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

If -> if

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

lib/fluent/plugin/filter_add_insert_ids.rb Show resolved Hide resolved
Fluent::Test.setup
end

def test_configure_insert_id_key
Copy link
Contributor

@davidbtucker davidbtucker Aug 28, 2018

Choose a reason for hiding this comment

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

It might be clearer to inline the values and split this into 2 tests:

def test_configure_insert_id_key_with_default
  d = create_driver('')
  assert_equal DEFAULT_INSERT_ID_KEY, d.instance.insert_id_key

def test_configure_insert_id_key_with_custom
  d = create_driver('insert_id_key custom_insert_id_key')
  assert_equal 'custom_insert_id_key', d.instance.insert_id_key

Copy link
Member

Choose a reason for hiding this comment

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

+1.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The rest of our unit tests mostly follow the test data provider pattern.

https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/blob/master/test/plugin/base_test.rb#L65
https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/blob/master/test/plugin/base_test.rb#L107

It's debatable which pattern is better. Let's discuss it and reach some consensus for future unit tests before introducing a stand-alone pattern. For this PR, I'll leave it as is.

If we do decide to switch, maybe this is a nice FixIt item to improve our tests' readability.

Copy link
Member

Choose a reason for hiding this comment

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

You're right, let's defer.

gem.homepage =
'https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud'
gem.license = 'Apache-2.0'
gem.version = '0.6.23'
gem.authors = ['Ling Huang', 'Igor Peshansky']
gem.authors = ['Stackdriver Agent Team']
Copy link
Member

Choose a reason for hiding this comment

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

Stackdriver Agents Team

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

store them in Google Cloud Storage and/or BigQuery.
This is an official Google Ruby gem.
Fluentd plugins for the Stackdriver Logging API, which will make logs
viewable in the Developer Console's log viewer and can optionally store them
Copy link
Member

Choose a reason for hiding this comment

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

s/Developer Console's log viewer/Stackdriver Logs Viewer/

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

This is an official Google Ruby gem.
Fluentd plugins for the Stackdriver Logging API, which will make logs
viewable in the Developer Console's log viewer and can optionally store them
in Google Cloud Storage and/or BigQuery. This is an official Google Ruby gem.
Copy link
Member

Choose a reason for hiding this comment

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

Let's move This is an official Google Ruby gem. back to its own line.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

eos
gem.summary = 'fluentd output plugin for the Stackdriver Logging API'
gem.summary = 'fluentd plugins for the Stackdriver Logging API'
Copy link
Member

Choose a reason for hiding this comment

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

Why are we not releasing the insertId plugin as a separate gem? Expediency?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Expediency is one reason. Also the way it's used today is tied to out_google_cloud. The original proposal is to make it generic and not specific to Stackdriver (it makes more sense to create a new Github repo and go through launch process if that's the case).

There was a discussion thread in the design doc. We were debating it and ended up going with this approach.

# limitations under the License.

require 'fluent/plugin/filter'
require 'thread'
Copy link
Member

Choose a reason for hiding this comment

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

What is this needed for? It doesn't seem to be used in the code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oops. That's some residue. Originally I thought I need to implement some thread safety protection. But after digging into Fluentd's code, it's not necessary because each filter plugin in the configuration will have one instance only.

include Fluent::Plugin::AddInsertIdsFilter::ConfigConstants

CUSTOM_INSERT_ID_KEY = 'custom_insert_id_key'.freeze
APPLICATION_DEFAULT_CONFIG = ''.freeze
Copy link
Member

Choose a reason for hiding this comment

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

Do we want to keep the two configs next to each other?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

LOL I'm evil and i made them break up. Changed.

Fluent::Test.setup
end

def test_configure_insert_id_key
Copy link
Member

Choose a reason for hiding this comment

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

+1.

' include 3 elements: tag, time and record.'
record = event[2]
assert_true record.is_a?(Hash), "Index #{index} failed. Log record" \
' should be a hash.'
Copy link
Member

Choose a reason for hiding this comment

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

Do you want to include what the record actually was in the error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

expected_insert_id = nil
filtered_events.each_with_index do |event, index|
assert_equal 3, event.size, "Index #{index} failed. Log event should" \
' include 3 elements: tag, time and record.'
Copy link
Member

Choose a reason for hiding this comment

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

Do you want to include the actual size in the error?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The actual size will be included in the error already. The

"Index #{index} failed. Log event should" \
                   ' include 3 elements: tag, time and record.'

does not overwrite the original not equal message. It only adds additional information.

record = event[2]
assert_true record.is_a?(Hash), "Index #{index} failed. Log record" \
' should be a hash.'
assert_equal index, record['id'], "Index #{index} failed."
Copy link
Member

Choose a reason for hiding this comment

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

Can we reflect this in the error message?

Copy link
Contributor Author

@qingling128 qingling128 left a comment

Choose a reason for hiding this comment

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

Updated. PTAL

expected_insert_id = record[DEFAULT_INSERT_ID_KEY] if index == 0
assert_equal expected_insert_id, record[DEFAULT_INSERT_ID_KEY],
"Index #{index} failed."
expected_insert_id = expected_insert_id.next
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added a check against 1000 unique insertIds.

README.rdoc Outdated
which sends logs to the
{Stackdriver Logging API}[https://cloud.google.com/logging/docs/api/].
fluent-plugin-google-cloud gem includes two plugins:
1. An {filter plugin for fluentd}[http://docs.fluentd.org/articles/filter-plugin-overview]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

README.rdoc Outdated
@@ -23,22 +23,31 @@ will also install and configure the gem.

== Configuration

To embed insertIds into log entries, specify <code>type add_insert_ids</code>
in a {match clause}[http://docs.fluentd.org/articles/config-file#2-ldquomatchrdquo-tell-fluentd-what-to-do]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

store them in Google Cloud Storage and/or BigQuery.
This is an official Google Ruby gem.
Fluentd plugins for the Stackdriver Logging API, which will make logs
viewable in the Developer Console's log viewer and can optionally store them
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Changed.

This is an official Google Ruby gem.
Fluentd plugins for the Stackdriver Logging API, which will make logs
viewable in the Developer Console's log viewer and can optionally store them
in Google Cloud Storage and/or BigQuery. This is an official Google Ruby gem.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

include Fluent::Plugin::AddInsertIdsFilter::ConfigConstants

CUSTOM_INSERT_ID_KEY = 'custom_insert_id_key'.freeze
APPLICATION_DEFAULT_CONFIG = ''.freeze
Copy link
Contributor Author

Choose a reason for hiding this comment

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

LOL I'm evil and i made them break up. Changed.

Fluent::Test.setup
end

def test_configure_insert_id_key
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The rest of our unit tests mostly follow the test data provider pattern.

https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/blob/master/test/plugin/base_test.rb#L65
https://github.com/GoogleCloudPlatform/fluent-plugin-google-cloud/blob/master/test/plugin/base_test.rb#L107

It's debatable which pattern is better. Let's discuss it and reach some consensus for future unit tests before introducing a stand-alone pattern. For this PR, I'll leave it as is.

If we do decide to switch, maybe this is a nice FixIt item to improve our tests' readability.

expected_insert_id = nil
filtered_events.each_with_index do |event, index|
assert_equal 3, event.size, "Index #{index} failed. Log event should" \
' include 3 elements: tag, time and record.'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The actual size will be included in the error already. The

"Index #{index} failed. Log event should" \
                   ' include 3 elements: tag, time and record.'

does not overwrite the original not equal message. It only adds additional information.

' include 3 elements: tag, time and record.'
record = event[2]
assert_true record.is_a?(Hash), "Index #{index} failed. Log record" \
' should be a hash.'
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

record = event[2]
assert_true record.is_a?(Hash), "Index #{index} failed. Log record" \
' should be a hash.'
assert_equal index, record['id'], "Index #{index} failed."
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

README.rdoc Outdated
@@ -23,22 +23,31 @@ will also install and configure the gem.

== Configuration

To embed insertIds into log entries, specify <code>type add_insert_ids</code>
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: missing @ here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.


# Initialize the insertId to a random string.
def initialize_insert_id
Array.new(INSERT_ID_SIZE) { ALLOWED_CHARS.sample }.join
Copy link
Contributor

@bmoyles0117 bmoyles0117 Aug 29, 2018

Choose a reason for hiding this comment

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

If the method is named initialize_, it would make more sense to me if the actual assignment occurred here. WDYT?

@insert_id = Array.new(INSERT_ID_SIZE) { ALLOWED_CHARS.sample }.join

Copy link
Member

Choose a reason for hiding this comment

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

I was the one who proposed initialize, and it seems like it was a mistake. Maybe initial_insert_id or generate_initial_insert_id would work better. I like the fact that it's assigned in start.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed to generate_initial_insert_id instead.


# Initialize the insertId to a random string.
def initialize_insert_id
Array.new(INSERT_ID_SIZE) { ALLOWED_CHARS.sample }.join
Copy link
Member

Choose a reason for hiding this comment

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

I was the one who proposed initialize, and it seems like it was a mistake. Maybe initial_insert_id or generate_initial_insert_id would work better. I like the fact that it's assigned in start.

# Only generate and add an insertId field if the record is a hash and
# the insert ID field is not already set.
if record.is_a?(Hash) && !record.key?(@insert_id_key) \
&& record[@insert_id_key] != ''
Copy link
Member

Choose a reason for hiding this comment

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

I don't think this does what you intended... You probably meant:

        if record.is_a?(Hash) && (!record.key?(@insert_id_key) || record[@insert_id_key] == '')

Alternatively, you could use:

        if record.is_a?(Hash) && record[@insert_id_key].to_s.empty?

(I think .empty? is preferred to == '' anyway).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, unit tests failed for this. I just fixed the logic and committed the unit tests.

Fluent::Test.setup
end

def test_configure_insert_id_key
Copy link
Member

Choose a reason for hiding this comment

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

You're right, let's defer.

Copy link
Contributor Author

@qingling128 qingling128 left a comment

Choose a reason for hiding this comment

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

Feedback addressed. PTAL.

README.rdoc Outdated
@@ -23,22 +23,31 @@ will also install and configure the gem.

== Configuration

To embed insertIds into log entries, specify <code>type add_insert_ids</code>
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.


# Initialize the insertId to a random string.
def initialize_insert_id
Array.new(INSERT_ID_SIZE) { ALLOWED_CHARS.sample }.join
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed to generate_initial_insert_id instead.

# Only generate and add an insertId field if the record is a hash and
# the insert ID field is not already set.
if record.is_a?(Hash) && !record.key?(@insert_id_key) \
&& record[@insert_id_key] != ''
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, unit tests failed for this. I just fixed the logic and committed the unit tests.

end

def test_add_insert_ids
total_entry_count = 1000
Copy link
Contributor

Choose a reason for hiding this comment

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

Could this number be smaller (like 5)? Or do we need to test with a high volume?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The number was chose to be this high mainly to test against any potential race condition (there should not be).

Copy link
Member

@igorpeshansky igorpeshansky left a comment

Choose a reason for hiding this comment

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

Minor.

# rubocop:disable Style/UnusedMethodArgument
def filter(tag, time, record)
# Only generate and add an insertId field if the record is a hash and
# the insert ID field is not already set. An empty string is considered
Copy link
Member

Choose a reason for hiding this comment

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

[Optional] not already set (or set to an empty string).

" Only #{unique_insert_ids.size} found."
end

def test_not_add_insert_ids_if_present
Copy link
Member

Choose a reason for hiding this comment

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

test_insert_ids_not_added_if_present.

Copy link
Member

@igorpeshansky igorpeshansky left a comment

Choose a reason for hiding this comment

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

LGTM :shipit:

@qingling128 qingling128 merged commit 23cfc5b into master Aug 29, 2018
@qingling128 qingling128 deleted the lingshi-filter branch August 30, 2018 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants