-
Notifications
You must be signed in to change notification settings - Fork 8.1k
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
[ILM] Policy form should not throw away data #83077
Merged
Merged
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
267ffd1
fix ilm policy deserialization
jloleysens 0991acb
reorder expected jest object to match actual
jloleysens c40e650
fix removal of wait for snapshot if it is not on the form
jloleysens e141966
add client integration test for policy serialization of unknown fields
jloleysens 57b7196
save on a few chars
jloleysens adf967d
added unit test for deserializer and serializer
jloleysens 79c1536
Implement feedback
jloleysens 65ea753
Updated serialization unit test coverage
jloleysens 8c53017
Merge branch 'master' into ilm/fix-serializer
kibanamachine c33e2b9
Merge branch 'master' into ilm/fix-serializer
kibanamachine 263023a
Merge branch 'master' into ilm/fix-serializer
kibanamachine 3e45301
fixed minor issue in how serialization tests are being set up
jloleysens File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
201 changes: 201 additions & 0 deletions
201
...nagement/public/application/sections/edit_policy/form/deserializer_and_serializer.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,201 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License; | ||
* you may not use this file except in compliance with the Elastic License. | ||
*/ | ||
|
||
import { setAutoFreeze } from 'immer'; | ||
import { cloneDeep } from 'lodash'; | ||
import { SerializedPolicy } from '../../../../../common/types'; | ||
import { deserializer } from './deserializer'; | ||
import { createSerializer } from './serializer'; | ||
import { FormInternal } from '../types'; | ||
|
||
const isObject = (v: unknown): v is { [key: string]: any } => | ||
Object.prototype.toString.call(v) === '[object Object]'; | ||
|
||
const unknownValue = { some: 'value' }; | ||
|
||
const populateWithUnknownEntries = (v: unknown) => { | ||
if (isObject(v)) { | ||
for (const key of Object.keys(v)) { | ||
if (['require', 'include', 'exclude'].includes(key)) continue; // this will generate an invalid policy | ||
populateWithUnknownEntries(v[key]); | ||
} | ||
v.unknown = unknownValue; | ||
return; | ||
} | ||
if (Array.isArray(v)) { | ||
v.forEach(populateWithUnknownEntries); | ||
} | ||
}; | ||
|
||
const originalPolicy: SerializedPolicy = { | ||
name: 'test', | ||
phases: { | ||
hot: { | ||
actions: { | ||
rollover: { | ||
max_age: '1d', | ||
max_size: '10gb', | ||
max_docs: 1000, | ||
}, | ||
forcemerge: { | ||
index_codec: 'best_compression', | ||
max_num_segments: 22, | ||
}, | ||
set_priority: { | ||
priority: 1, | ||
}, | ||
}, | ||
min_age: '12ms', | ||
}, | ||
warm: { | ||
min_age: '12ms', | ||
actions: { | ||
shrink: { number_of_shards: 12 }, | ||
allocate: { | ||
number_of_replicas: 3, | ||
}, | ||
set_priority: { | ||
priority: 10, | ||
}, | ||
migrate: { enabled: false }, | ||
}, | ||
}, | ||
cold: { | ||
min_age: '30ms', | ||
actions: { | ||
allocate: { | ||
number_of_replicas: 12, | ||
require: { test: 'my_value' }, | ||
include: { test: 'my_value' }, | ||
exclude: { test: 'my_value' }, | ||
}, | ||
freeze: {}, | ||
set_priority: { | ||
priority: 12, | ||
}, | ||
}, | ||
}, | ||
delete: { | ||
min_age: '33ms', | ||
actions: { | ||
delete: { | ||
delete_searchable_snapshot: true, | ||
}, | ||
wait_for_snapshot: { | ||
policy: 'test', | ||
}, | ||
}, | ||
}, | ||
}, | ||
}; | ||
|
||
describe('deserializer and serializer', () => { | ||
let policy: SerializedPolicy; | ||
let serializer: ReturnType<typeof createSerializer>; | ||
let formInternal: FormInternal; | ||
|
||
// So that we can modify produced form objects | ||
beforeAll(() => setAutoFreeze(false)); | ||
// This is the default in dev, so change back to true (https://github.com/immerjs/immer/blob/master/docs/freezing.md) | ||
afterAll(() => setAutoFreeze(true)); | ||
|
||
beforeEach(() => { | ||
policy = cloneDeep(originalPolicy); | ||
formInternal = deserializer(policy); | ||
// Because the policy object is not deepCloned by the form lib we | ||
// clone here so that we can mutate the policy and preserve the | ||
// original reference in the createSerializer | ||
serializer = createSerializer(cloneDeep(policy)); | ||
}); | ||
|
||
it('preserves any unknown policy settings', () => { | ||
const thisTestPolicy = cloneDeep(originalPolicy); | ||
// We populate all levels of the policy with entries our UI does not know about | ||
populateWithUnknownEntries(thisTestPolicy); | ||
serializer = createSerializer(thisTestPolicy); | ||
|
||
const copyOfThisTestPolicy = cloneDeep(thisTestPolicy); | ||
|
||
expect(serializer(deserializer(thisTestPolicy))).toEqual(thisTestPolicy); | ||
|
||
// Assert that the policy we passed in is unaltered after deserialization and serialization | ||
expect(thisTestPolicy).not.toBe(copyOfThisTestPolicy); | ||
expect(thisTestPolicy).toEqual(copyOfThisTestPolicy); | ||
}); | ||
|
||
it('removes all phases if they were disabled in the form', () => { | ||
formInternal._meta.warm.enabled = false; | ||
formInternal._meta.cold.enabled = false; | ||
formInternal._meta.delete.enabled = false; | ||
|
||
expect(serializer(formInternal)).toEqual({ | ||
name: 'test', | ||
phases: { | ||
hot: policy.phases.hot, // We expect to see only the hot phase | ||
}, | ||
}); | ||
}); | ||
|
||
it('removes the forcemerge action if it is disabled in the form', () => { | ||
delete formInternal.phases.hot!.actions.forcemerge; | ||
delete formInternal.phases.warm!.actions.forcemerge; | ||
|
||
const result = serializer(formInternal); | ||
|
||
expect(result.phases.hot!.actions.forcemerge).toBeUndefined(); | ||
expect(result.phases.warm!.actions.forcemerge).toBeUndefined(); | ||
}); | ||
|
||
it('removes set priority if it is disabled in the form', () => { | ||
delete formInternal.phases.hot!.actions.set_priority; | ||
delete formInternal.phases.warm!.actions.set_priority; | ||
delete formInternal.phases.cold!.actions.set_priority; | ||
|
||
const result = serializer(formInternal); | ||
|
||
expect(result.phases.hot!.actions.set_priority).toBeUndefined(); | ||
expect(result.phases.warm!.actions.set_priority).toBeUndefined(); | ||
expect(result.phases.cold!.actions.set_priority).toBeUndefined(); | ||
}); | ||
|
||
it('removes freeze setting in the cold phase if it is disabled in the form', () => { | ||
formInternal._meta.cold.freezeEnabled = false; | ||
|
||
const result = serializer(formInternal); | ||
|
||
expect(result.phases.cold!.actions.freeze).toBeUndefined(); | ||
}); | ||
|
||
it('removes node attribute allocation when it is not selected in the form', () => { | ||
// Change from 'node_attrs' to 'node_roles' | ||
formInternal._meta.cold.dataTierAllocationType = 'node_roles'; | ||
|
||
const result = serializer(formInternal); | ||
|
||
expect(result.phases.cold!.actions.allocate!.number_of_replicas).toBe(12); | ||
expect(result.phases.cold!.actions.allocate!.require).toBeUndefined(); | ||
expect(result.phases.cold!.actions.allocate!.include).toBeUndefined(); | ||
expect(result.phases.cold!.actions.allocate!.exclude).toBeUndefined(); | ||
}); | ||
|
||
it('removes forcemerge and rollover config when rollover is disabled in hot phase', () => { | ||
formInternal._meta.hot.useRollover = false; | ||
|
||
const result = serializer(formInternal); | ||
|
||
expect(result.phases.hot!.actions.rollover).toBeUndefined(); | ||
expect(result.phases.hot!.actions.forcemerge).toBeUndefined(); | ||
}); | ||
|
||
it('removes min_age from warm when rollover is enabled', () => { | ||
formInternal._meta.hot.useRollover = true; | ||
formInternal._meta.warm.warmPhaseOnRollover = true; | ||
|
||
const result = serializer(formInternal); | ||
|
||
expect(result.phases.warm!.min_age).toBeUndefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't we use the
lodash.clonedeep
package?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think not after #78156 was merged. We should be importing the entire lodash library now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could. Thanks, good to know 👍