diff --git a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG index 90ceb32fc..5f8e810f 100644 --- a/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG +++ b/third_party/WebKit/LayoutTests/FlagExpectations/enable-blink-features=LayoutNG
@@ -2418,7 +2418,7 @@ crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-018.html [ Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-019.html [ Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-020.html [ Failure ] -crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-021.html [ Failure ] +crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-021.html [ Crash Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-022.html [ Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-023.html [ Failure ] crbug.com/591099 external/wpt/css/css-shapes/shape-outside/shape-image/shape-image-025.html [ Failure ] @@ -2496,7 +2496,7 @@ crbug.com/591099 external/wpt/css/css-shapes/spec-examples/shape-outside-019.html [ Failure ] crbug.com/591099 external/wpt/css/css-tables/height-distribution/percentage-sizing-of-table-cell-children.html [ Failure ] crbug.com/591099 external/wpt/css/css-tables/html5-table-formatting-fixed-layout-1.html [ Crash Pass ] -crbug.com/591099 external/wpt/css/css-tables/table-model-fixup-2.html [ Failure ] +crbug.com/591099 external/wpt/css/css-tables/table-model-fixup-2.html [ Failure Pass ] crbug.com/591099 external/wpt/css/css-tables/visibility-collapse-rowcol-001.html [ Crash Pass ] crbug.com/591099 external/wpt/css/css-tables/visibility-collapse-rowspan-crash.html [ Crash Pass ] crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-color-001.xht [ Crash ] @@ -2651,7 +2651,7 @@ crbug.com/591099 external/wpt/editing/run/formatblock.html [ Timeout ] crbug.com/591099 external/wpt/editing/run/forwarddelete.html [ Timeout ] crbug.com/591099 external/wpt/editing/run/hilitecolor.html [ Timeout ] -crbug.com/591099 external/wpt/editing/run/indent.html [ Timeout ] +crbug.com/591099 external/wpt/editing/run/indent.html [ Pass Timeout ] crbug.com/591099 external/wpt/editing/run/inserthorizontalrule.html [ Crash Pass Timeout ] crbug.com/591099 external/wpt/editing/run/inserthtml.html [ Timeout ] crbug.com/591099 external/wpt/editing/run/insertlinebreak.html [ Timeout ] @@ -5005,6 +5005,7 @@ crbug.com/714962 compositing/images/direct-image-clip-path.html [ Failure ] crbug.com/714962 compositing/images/direct-image-dynamic-clip-path.html [ Failure ] crbug.com/714962 compositing/overflow/absolute-element-in-isolated-composited-ancestor.html [ Failure ] +crbug.com/591099 compositing/overflow/border-radius-above-composited-subframe.html [ Failure ] crbug.com/591099 compositing/overflow/border-radius-composited-subframe.html [ Failure ] crbug.com/591099 compositing/overflow/border-radius-on-squashed-layers.html [ Failure Pass ] crbug.com/591099 compositing/overflow/composited-scroll-with-fractional-translation.html [ Pass ] @@ -5176,9 +5177,9 @@ crbug.com/714962 external/wpt/css/CSS2/text/text-indent-overflow-004.xht [ Failure ] crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-color-5.html [ Failure ] crbug.com/714962 external/wpt/css/css-backgrounds/background-attachment-local/attachment-local-clipping-image-5.html [ Failure ] -crbug.com/714962 external/wpt/css/css-backgrounds/background-image-003.html [ Failure ] +crbug.com/714962 external/wpt/css/css-backgrounds/background-image-003.html [ Failure Pass ] crbug.com/714962 external/wpt/css/css-backgrounds/background-image-004.html [ Failure ] -crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure ] +crbug.com/714962 external/wpt/css/css-backgrounds/background-image-005.html [ Failure Pass ] crbug.com/714962 external/wpt/css/css-backgrounds/background-image-006.html [ Failure Pass ] crbug.com/714962 external/wpt/css/css-backgrounds/background-size/background-size-cover.xht [ Failure ] crbug.com/714962 external/wpt/css/css-backgrounds/css3-background-clip.html [ Failure ] @@ -5331,6 +5332,7 @@ crbug.com/591099 external/wpt/css/css-multicol/multicol-width-001.xht [ Failure ] crbug.com/591099 external/wpt/css/css-multicol/multicol-width-002.xht [ Failure ] crbug.com/591099 external/wpt/css/css-multicol/multicol-width-003.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-multicol/multicol-width-ch-001.xht [ Failure ] crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-001.xht [ Failure ] crbug.com/591099 external/wpt/css/css-multicol/multicol-width-count-002.xht [ Failure ] crbug.com/714962 external/wpt/css/css-multicol/multicol-width-large-001.xht [ Failure ] @@ -5353,6 +5355,8 @@ crbug.com/714962 external/wpt/css/css-position/position-sticky-top.html [ Failure Pass ] crbug.com/714962 external/wpt/css/css-scroll-anchoring/start-edge-in-block-layout-direction.html [ Failure ] crbug.com/714962 external/wpt/css/css-scroll-anchoring/wrapped-text.html [ Failure ] +crbug.com/591099 external/wpt/css/css-style-attr/style-attr-urls-001.xht [ Failure ] +crbug.com/591099 external/wpt/css/css-style-attr/style-attr-urls-002.xht [ Failure ] crbug.com/714962 external/wpt/css/css-tables/visibility-collapse-colspan-003.html [ Failure ] crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-above-left-001.xht [ Crash ] crbug.com/591099 external/wpt/css/css-text-decor/text-emphasis-position-above-right-001.xht [ Crash ] @@ -5392,7 +5396,7 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-003.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-005.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-007.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-009.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-009.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-011.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-013.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-015.xht [ Failure ] @@ -5419,7 +5423,7 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-057.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-059.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-061.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-063.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-063.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-065.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-067.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-069.xht [ Failure ] @@ -5439,7 +5443,7 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-097.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-103.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-105.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-107.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-107.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-109.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-111.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-113.xht [ Failure Pass ] @@ -5471,11 +5475,11 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-165.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-167.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-169.xht [ Failure Pass ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-171.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-171.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-173.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-175.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-177.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-179.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-177.xht [ Failure Pass ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-179.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-181.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-183.xht [ Failure Pass ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vlr-185.xht [ Failure Pass ] @@ -5596,7 +5600,7 @@ crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-190.xht [ Failure ] crbug.com/591099 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-192.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-194.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-196.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-196.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-198.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-200.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/abs-pos-non-replaced-vrl-202.xht [ Failure ] @@ -5683,14 +5687,14 @@ crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-011.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-013.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-015.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-017.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-017.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vlr-019.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-002.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-004.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-006.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-008.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-010.xht [ Failure ] -crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure ] +crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-012.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-014.xht [ Failure Pass ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-016.xht [ Failure ] crbug.com/714962 external/wpt/css/css-writing-modes/text-align-vrl-018.xht [ Failure ] @@ -5801,6 +5805,8 @@ crbug.com/591099 external/wpt/html/semantics/selectors/pseudo-classes/readwrite-readonly.html [ Crash ] crbug.com/714962 external/wpt/intersection-observer/root-margin.html [ Failure ] crbug.com/591099 external/wpt/mediacapture-streams/MediaStreamTrack-getSettings.https.html [ Pass ] +crbug.com/591099 external/wpt/mimesniff/mime-types/parsing.any.html [ Timeout ] +crbug.com/591099 external/wpt/mimesniff/mime-types/parsing.any.worker.html [ Timeout ] crbug.com/591099 external/wpt/offscreen-canvas/the-offscreen-canvas/offscreencanvas.getcontext.worker.html [ Pass ] crbug.com/714962 external/wpt/pointerevents/pointerevent_capture_mouse-manual.html [ Timeout ] crbug.com/714962 external/wpt/pointerevents/pointerevent_capture_suppressing_mouse-manual.html [ Timeout ] @@ -5899,7 +5905,7 @@ crbug.com/714962 fast/borders/border-radius-inline-flow.html [ Failure ] crbug.com/714962 fast/borders/border-radius-percent.html [ Failure ] crbug.com/714962 fast/borders/border-radius-split-inline.html [ Failure ] -crbug.com/714962 fast/borders/border-radius-with-composited-child.html [ Failure ] +crbug.com/714962 fast/borders/border-radius-with-composited-child.html [ Failure Pass ] crbug.com/714962 fast/borders/border-styles-split.html [ Failure ] crbug.com/714962 fast/borders/borderRadiusArcs01.html [ Failure ] crbug.com/714962 fast/borders/borderRadiusDouble01.html [ Failure ] @@ -6094,7 +6100,7 @@ crbug.com/714962 fast/events/input-element-display-none-in-dragleave-crash.html [ Failure ] crbug.com/714962 fast/events/inputevents/inputevent-drag-drop.html [ Failure ] crbug.com/714962 fast/events/middleClickAutoscroll-click-hyperlink.html [ Timeout ] -crbug.com/714962 fast/events/middleClickAutoscroll-latching.html [ Timeout ] +crbug.com/714962 fast/events/middleClickAutoscroll-latching.html [ Pass Timeout ] crbug.com/714962 fast/events/mouse-down-on-pseudo-element-remove-crash.html [ Failure ] crbug.com/714962 fast/events/mouse-events-on-textarea-resize.html [ Failure ] crbug.com/591099 fast/events/mouse-relative-position.html [ Failure ] @@ -6625,7 +6631,7 @@ crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-iframe-inset-negative-width-crash.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-iframe-inset-rectangle-negative-width-crash.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-image-001.html [ Failure ] -crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-image-002.html [ Failure ] +crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-image-002.html [ Crash Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-image-margin-001.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-image-margin-002.html [ Failure ] crbug.com/591099 fast/shapes/shape-outside-floats/shape-outside-floats-image-threshold-001.html [ Failure ] @@ -6786,6 +6792,7 @@ crbug.com/591099 fast/table/change-row-border-width-floating-container.html [ Failure ] crbug.com/591099 fast/table/change-table-border-width.html [ Failure ] crbug.com/591099 fast/table/change-tbody-border-width.html [ Failure ] +crbug.com/591099 fast/table/collapsed-border-overflow-hidden.html [ Failure ] crbug.com/591099 fast/table/column-in-inline.html [ Failure ] crbug.com/591099 fast/table/convert-inline-to-table-cell.html [ Failure Pass ] crbug.com/591099 fast/table/dynamic-descendant-percentage-height.html [ Failure ] @@ -7492,7 +7499,7 @@ crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-jquery2.js [ Crash Failure ] crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar-remove.js [ Crash Pass ] crbug.com/591099 http/tests/devtools/elements/event-listener-sidebar.js [ Crash Failure ] -crbug.com/714962 http/tests/devtools/elements/hide-shortcut.js [ Crash ] +crbug.com/714962 http/tests/devtools/elements/hide-shortcut.js [ Crash Pass ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside-scroll.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-css-shapes-outside.js [ Failure ] crbug.com/714962 http/tests/devtools/elements/highlight/highlight-dom-updates.js [ Crash ] @@ -7500,7 +7507,7 @@ crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scaled.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node-scroll.js [ Failure ] crbug.com/591099 http/tests/devtools/elements/highlight/highlight-node.js [ Failure ] -crbug.com/714962 http/tests/devtools/elements/iframe-load-event.js [ Crash ] +crbug.com/714962 http/tests/devtools/elements/iframe-load-event.js [ Crash Pass ] crbug.com/714962 http/tests/devtools/elements/insert-node.js [ Crash ] crbug.com/714962 http/tests/devtools/elements/inspect-pseudo-element.js [ Timeout ] crbug.com/714962 http/tests/devtools/elements/modify-chardata.js [ Crash ] @@ -7512,7 +7519,7 @@ crbug.com/714962 http/tests/devtools/elements/styles-1/add-new-rule-with-style-after-body.js [ Crash Pass ] crbug.com/714962 http/tests/devtools/elements/styles-1/edit-value-url-with-color.js [ Crash ] crbug.com/714962 http/tests/devtools/elements/styles-2/force-pseudo-state.js [ Crash ] -crbug.com/714962 http/tests/devtools/elements/styles-2/paste-property.js [ Crash ] +crbug.com/714962 http/tests/devtools/elements/styles-2/paste-property.js [ Crash Pass ] crbug.com/714962 http/tests/devtools/elements/styles-2/pseudo-elements.js [ Crash ] crbug.com/591099 http/tests/devtools/elements/styles-3/style-rule-from-imported-stylesheet.js [ Crash Pass ] crbug.com/714962 http/tests/devtools/elements/styles-3/styles-add-blank-property.js [ Crash ] @@ -7537,6 +7544,7 @@ crbug.com/591099 http/tests/devtools/extensions/extensions-sidebar.js [ Crash Failure ] crbug.com/591099 http/tests/devtools/extensions/extensions-timeline-api.js [ Failure Pass ] crbug.com/591099 http/tests/devtools/indexeddb/resources-panel.js [ Failure Timeout ] +crbug.com/591099 http/tests/devtools/inspect-element.js [ Crash Pass ] crbug.com/714962 http/tests/devtools/jump-to-previous-editing-location.js [ Failure ] crbug.com/714962 http/tests/devtools/layers/layer-canvas-log.js [ Failure ] crbug.com/591099 http/tests/devtools/network/network-columns-visible.js [ Failure Timeout ] @@ -7554,7 +7562,7 @@ crbug.com/591099 http/tests/devtools/sources/debugger/live-edit-no-reveal.js [ Failure Pass ] crbug.com/591099 http/tests/devtools/sources/debugger/properties-special.js [ Failure ] crbug.com/591099 http/tests/devtools/startup/console/console-format-startup.html [ Failure ] -crbug.com/591099 http/tests/devtools/startup/reattach-after-editing-styles.html [ Crash ] +crbug.com/591099 http/tests/devtools/startup/reattach-after-editing-styles.html [ Crash Pass ] crbug.com/591099 http/tests/devtools/text-autosizing-override.js [ Failure ] crbug.com/714962 http/tests/devtools/tracing/scroll-invalidations.js [ Failure ] crbug.com/591099 http/tests/devtools/tracing/timeline-misc/timeline-bound-function.js [ Crash Failure ] @@ -9240,7 +9248,7 @@ crbug.com/714962 svg/clip-path/nested-clip-in-mask-image-based-clipping.svg [ Failure ] crbug.com/714962 svg/clip-path/nested-clip-in-mask-path-and-image-based-clipping.svg [ Crash Failure ] crbug.com/714962 svg/clip-path/nested-clip-in-mask-path-based-clipping.svg [ Failure ] -crbug.com/714962 svg/clip-path/nested-empty-clip.html [ Failure ] +crbug.com/714962 svg/clip-path/nested-empty-clip.html [ Crash Failure ] crbug.com/714962 svg/clip-path/opacity-assertion.svg [ Failure ] crbug.com/714962 svg/clip-path/transformed-clip.svg [ Failure ] crbug.com/714962 svg/clip-path/visible-clip-path-as-hidden-use-element.html [ Failure ] @@ -10263,6 +10271,8 @@ crbug.com/591099 virtual/spv175/compositing/columns/composited-in-paginated.html [ Failure ] crbug.com/714962 virtual/spv175/compositing/composited-descendant-grandparent-border-radius-mask.html [ Pass ] crbug.com/714962 virtual/spv175/compositing/composited-descendant-requiring-border-radius-mask.html [ Pass ] +crbug.com/591099 virtual/spv175/compositing/composited-scaled-child-with-border-radius-parent-clip.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/composited-translated-child-with-border-radius-parent-clip.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/compositing-visible-descendant.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/contents-opaque/background-clip.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/contents-opaque/background-color.html [ Failure ] @@ -10461,15 +10471,24 @@ crbug.com/591099 virtual/spv175/compositing/masks/multiple-masks.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/masks/simple-composited-mask.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/nested-border-radius-composited-child.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/opacity-with-mask.html [ Failure ] crbug.com/714962 virtual/spv175/compositing/overflow/absolute-element-in-isolated-composited-ancestor.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/accelerated-overflow-scroll-should-not-affect-perspective.html [ Failure ] crbug.com/714962 virtual/spv175/compositing/overflow/accelerated-scrolling-with-clip-reference.html [ Pass ] crbug.com/591099 virtual/spv175/compositing/overflow/ancestor-overflow.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/border-radius-above-composited-subframe.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/border-radius-composited-subframe.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/border-radius-on-grandparent-composited-grandchild.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/border-radius-on-parent-composited-grandchild.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/border-radius-on-squashed-layers.html [ Failure Pass ] +crbug.com/591099 virtual/spv175/compositing/overflow/border-radius-on-two-ancestors-composited-grandchild.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/border-radius-outside-bounds-of-compositing-ancestor.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/border-radius-styles-with-composited-child.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/clear-scroll-parent.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/clip-descendents.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/clip-parent-reset.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/clipping-ancestor-with-accelerated-scrolling-ancestor.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/composited-layer-under-border-radius-under-composited-layer.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/composited-nested-sticky-left.html [ Failure Pass ] crbug.com/591099 virtual/spv175/compositing/overflow/composited-scrolling-paint-phases.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/content-gains-scrollbars.html [ Failure ] @@ -10479,6 +10498,8 @@ crbug.com/591099 virtual/spv175/compositing/overflow/fixed-position-ancestor-clip.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/fractional-sized-scrolling-layer.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/get-transform-from-non-box-container.html [ Crash ] +crbug.com/591099 virtual/spv175/compositing/overflow/grandchild-composited-with-border-radius-ancestor.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/grandchild-with-border-radius-ancestor.html [ Failure ] crbug.com/714962 virtual/spv175/compositing/overflow/image-load-overflow-scrollbars.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/mask-with-filter.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/mask-with-small-content-rect.html [ Failure ] @@ -10510,8 +10531,12 @@ crbug.com/591099 virtual/spv175/compositing/overflow/scrollbar-layer-placement.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/scrollbar-painting.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/scrolling-content-clip-to-viewport.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/siblings-composited-with-border-radius-ancestor-one-clipped.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/siblings-composited-with-border-radius-ancestor.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/siblings-with-border-radius-ancestor.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/textarea-scroll-touch.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/theme-affects-visual-overflow.html [ Failure ] +crbug.com/591099 virtual/spv175/compositing/overflow/tiled-mask.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/universal-accelerated-overflow-scroll.html [ Failure Timeout ] crbug.com/591099 virtual/spv175/compositing/overflow/update-widget-positions-on-nested-frames-and-scrollers.html [ Failure ] crbug.com/591099 virtual/spv175/compositing/overflow/zero-size-overflow.html [ Failure ]
diff --git a/third_party/WebKit/Source/core/css/CSSSelector.cpp b/third_party/WebKit/Source/core/css/CSSSelector.cpp index 307da292..f170482 100644 --- a/third_party/WebKit/Source/core/css/CSSSelector.cpp +++ b/third_party/WebKit/Source/core/css/CSSSelector.cpp
@@ -541,14 +541,8 @@ pseudo_type_ = kPseudoUnknown; break; case kPseudoShadow: - if (RuntimeEnabledFeatures:: - ShadowPseudoElementInCSSDynamicProfileEnabled()) { - if (match_ != kPseudoElement) - pseudo_type_ = kPseudoUnknown; - } else { - if (match_ != kPseudoElement || context.IsDynamicProfile()) - pseudo_type_ = kPseudoUnknown; - } + if (match_ != kPseudoElement || context.IsDynamicProfile()) + pseudo_type_ = kPseudoUnknown; break; case kPseudoBlinkInternalElement: if (match_ != kPseudoElement || mode != kUASheetMode)
diff --git a/third_party/WebKit/Source/core/css/SelectorChecker.cpp b/third_party/WebKit/Source/core/css/SelectorChecker.cpp index 7cd5a7d..80e92b5e 100644 --- a/third_party/WebKit/Source/core/css/SelectorChecker.cpp +++ b/third_party/WebKit/Source/core/css/SelectorChecker.cpp
@@ -333,8 +333,6 @@ switch (relation) { case CSSSelector::kShadowDeepAsDescendant: - DCHECK( - !RuntimeEnabledFeatures::DeepCombinatorInCSSDynamicProfileEnabled()); Deprecation::CountDeprecation(context.element->GetDocument(), WebFeature::kCSSDeepCombinator); // fall through @@ -416,15 +414,10 @@ case CSSSelector::kShadowPseudo: { if (!is_ua_rule_ && - context.selector->GetPseudoType() == CSSSelector::kPseudoShadow) { - if (mode_ == kQueryingRules) { - UseCounter::Count(context.element->GetDocument(), - WebFeature::kPseudoShadowInStaticProfile); - } else if (RuntimeEnabledFeatures:: - ShadowPseudoElementInCSSDynamicProfileEnabled()) { - Deprecation::CountDeprecation(context.element->GetDocument(), - WebFeature::kCSSSelectorPseudoShadow); - } + context.selector->GetPseudoType() == CSSSelector::kPseudoShadow && + mode_ == kQueryingRules) { + UseCounter::Count(context.element->GetDocument(), + WebFeature::kPseudoShadowInStaticProfile); } // If we're in the same tree-scope as the scoping element, then following // a shadow descendant combinator would escape that and thus the scope.
diff --git a/third_party/WebKit/Source/core/css/StyleEngineTest.cpp b/third_party/WebKit/Source/core/css/StyleEngineTest.cpp index b67108f..d13d1d8 100644 --- a/third_party/WebKit/Source/core/css/StyleEngineTest.cpp +++ b/third_party/WebKit/Source/core/css/StyleEngineTest.cpp
@@ -689,14 +689,6 @@ EXPECT_EQ(ScheduleInvalidationsForRules( *shadow_root, ".a ::content span { background: green}"), kRuleSetInvalidationFullRecalc); - if (RuntimeEnabledFeatures::DeepCombinatorInCSSDynamicProfileEnabled()) { - EXPECT_EQ(ScheduleInvalidationsForRules( - *shadow_root, ".a /deep/ span { background: green}"), - kRuleSetInvalidationFullRecalc); - EXPECT_EQ(ScheduleInvalidationsForRules( - *shadow_root, ".a::shadow span { background: green}"), - kRuleSetInvalidationFullRecalc); - } } TEST_F(StyleEngineTest, HasViewportDependentMediaQueries) {
diff --git a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp index 962f5802a..53a807a 100644 --- a/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp +++ b/third_party/WebKit/Source/core/css/parser/CSSSelectorParser.cpp
@@ -1,3 +1,4 @@ + // Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -644,9 +645,6 @@ const CSSParserToken& slash = range.ConsumeIncludingWhitespace(); if (slash.GetType() != kDelimiterToken || slash.Delimiter() != '/') failed_parsing_ = true; - if (RuntimeEnabledFeatures::DeepCombinatorInCSSDynamicProfileEnabled()) { - return CSSSelector::kShadowDeep; - } return context_->IsDynamicProfile() ? CSSSelector::kShadowDeepAsDescendant : CSSSelector::kShadowDeep; }
diff --git a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 b/third_party/WebKit/Source/platform/runtime_enabled_features.json5 index 6859246..0106752 100644 --- a/third_party/WebKit/Source/platform/runtime_enabled_features.json5 +++ b/third_party/WebKit/Source/platform/runtime_enabled_features.json5
@@ -315,11 +315,6 @@ name: "DecodeToYUV", status: "experimental", }, - // Remove this flag once we can remove /deep/ at M63. - { - name: "DeepCombinatorInCSSDynamicProfile", - status: "test", - }, { name: "DeprecationReporting", status: "experimental", @@ -956,11 +951,6 @@ name: "ShadowPiercingDescendantCombinator", status: "experimental", }, - // Remove this flag once we can remove ::shadow at M63. - { - name: "ShadowPseudoElementInCSSDynamicProfile", - status: "test", - }, { name: "ShapeDetection", status: "experimental",
diff --git a/third_party/WebKit/Source/platform/wtf/Functional.h b/third_party/WebKit/Source/platform/wtf/Functional.h index e70c89c3..b42729e 100644 --- a/third_party/WebKit/Source/platform/wtf/Functional.h +++ b/third_party/WebKit/Source/platform/wtf/Functional.h
@@ -49,44 +49,24 @@ // arguments together into a function object that can be stored, copied and // invoked, similar to boost::bind and std::bind in C++11. -// *************************************************************************** -// ** NOTICE: same-thread WTF::Function is being migrated to base::Callback ** -// *************************************************************************** +// To create a same-thread callback, use WTF::Bind() or WTF::BindRepeating(). +// Use the former to create a callback that's called only once, and use the +// latter for a callback that may be called multiple times. // -// We are in the process of replace same-thread WTF::Function with -// base::{Once,Repeating}Callback (crbug.com/771087). -// -// One of the most important implications of this is that we'll need to -// distinguish a callback function that's only used once from one that may be -// called multiple times. -// -// Use the following guide to determine the correct usage for your use case -// (note this guideline may change as the migration effort progresses): -// -// 1. To create a callback that may be used or destructed in another thread -// -// Use CrossThreadBind() (defined in platform/CrossThreadFunctional.h), and -// receive the returned callback as WTF::CrossThreadFunction. There is no -// distinction of Once and Repeating for cross-thread usage for now. -// -// 2. To create a same-thread callback that's called only once -// -// Use WTF::Bind(), and receive the returned callback as base::OnceCallback -// or base::OnceClosure. Read //docs/callback.md for how to use them. -// -// 3. To create a same-thread callback that may be called multiple times -// -// Use WTF::BindRepeating(), and receive the returned callback as -// base::RepeatingCallback or base::RepeatingClosure (WTF::RepeatingFunction -// is gone). +// WTF::Bind() and WTF::BindRepeating() returns base::OnceCallback and +// base::RepeatingCallback respectively. See //docs/callback.md for how to use +// those types. // Thread Safety: // -// WTF::Bind() and WTF::Closure should be used for same-thread closures -// only, i.e. the closures must be created, executed and destructed on -// the same thread. +// WTF::Bind(), WTF::BindRepeating and base::{Once,Repeating}Callback should +// be used for same-thread closures only, i.e. the closures must be created, +// executed and destructed on the same thread. // Use crossThreadBind() and CrossThreadClosure if the function/task is called // or destructed on a (potentially) different thread from the current thread. +// +// Currently, WTF::CrossThreadClosure does not distinguish Once and Repeating +// usage. // WTF::Bind() / WTF::BindRepeating() and move semantics // ===================================================== @@ -96,12 +76,13 @@ // 1) Pass by rvalue reference. // // void YourFunction(Argument&& argument) { ... } -// Function<void(Argument&&)> functor = Bind(&YourFunction); +// base::OnceCallback<void(Argument&&)> functor = +// Bind(&YourFunction); // // 2) Pass by value. // // void YourFunction(Argument argument) { ... } -// Function<void(Argument)> functor = Bind(&YourFunction); +// base::OnceCallback<void(Argument)> functor = Bind(&YourFunction); // // Note that with the latter there will be *two* move constructions happening, // because there needs to be at least one intermediary function call taking an @@ -124,7 +105,7 @@ // } // // ... -// Function<void()> functor = Bind(&YourFunction, WTF::Passed(Argument())); +// base::OnceClosure functor = Bind(&YourFunction, WTF::Passed(Argument())); // ... // std::move(functor).Run(); // @@ -313,9 +294,6 @@ #endif template <typename Signature> -using Function = base::OnceCallback<Signature>; - -template <typename Signature> class CrossThreadFunction; template <typename R, typename... Args> @@ -358,9 +336,8 @@ // Note: now there is WTF::Bind()and WTF::BindRepeating(). See the comment block // above for the correct usage of those. template <typename FunctionType, typename... BoundParameters> -Function<base::MakeUnboundRunType<FunctionType, BoundParameters...>> Bind( - FunctionType function, - BoundParameters&&... bound_parameters) { +base::OnceCallback<base::MakeUnboundRunType<FunctionType, BoundParameters...>> +Bind(FunctionType function, BoundParameters&&... bound_parameters) { static_assert(internal::CheckGCedTypeRestrictions< std::index_sequence_for<BoundParameters...>, std::decay_t<BoundParameters>...>::ok, @@ -399,9 +376,6 @@ return cb; } -// TODO(yutak): Replace WTF::Function with base::OnceCallback. -using Closure = Function<void()>; - template <typename T> using CrossThreadRepeatingFunction = CrossThreadFunction<T>; using CrossThreadRepeatingClosure = CrossThreadFunction<void()>; @@ -443,7 +417,6 @@ using WTF::CrossThreadUnretained; -using WTF::Function; using WTF::CrossThreadFunction; using WTF::CrossThreadClosure;
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index ce795c0e..a1240c7 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml
@@ -42269,6 +42269,7 @@ <int value="26372521" label="sync_attachment_downloader"/> <int value="27071967" label="chrome_cleaner"/> <int value="27915688" label="oauth2_access_token_fetcher"/> + <int value="28406789" label="undefined-656607"/> <int value="29865866" label="headless_url_request"/> <int value="30913825" label="family_info"/> <int value="32030464" label="persist_blob_to_indexed_db"/>
diff --git a/tools/traffic_annotation/auditor/BUILD.gn b/tools/traffic_annotation/auditor/BUILD.gn index fe86490..f4b33ba 100644 --- a/tools/traffic_annotation/auditor/BUILD.gn +++ b/tools/traffic_annotation/auditor/BUILD.gn
@@ -56,6 +56,8 @@ "traffic_annotation_exporter.h", "traffic_annotation_file_filter.cc", "traffic_annotation_file_filter.h", + "traffic_annotation_id_checker.cc", + "traffic_annotation_id_checker.h", ] data = [ "safe_list.txt",
diff --git a/tools/traffic_annotation/auditor/auditor_result.cc b/tools/traffic_annotation/auditor/auditor_result.cc index e59bab7..e09f10c2 100644 --- a/tools/traffic_annotation/auditor/auditor_result.cc +++ b/tools/traffic_annotation/auditor/auditor_result.cc
@@ -19,14 +19,15 @@ type == AuditorResult::Type::RESULT_OK || type == AuditorResult::Type::RESULT_IGNORE || type == AuditorResult::Type::ERROR_FATAL || - type == AuditorResult::Type::ERROR_DUPLICATE_UNIQUE_ID_HASH_CODE || + type == AuditorResult::Type::ERROR_HASH_CODE_COLLISION || + type == AuditorResult::Type::ERROR_REPEATED_ID || type == AuditorResult::Type::ERROR_MERGE_FAILED || type == AuditorResult::Type::ERROR_ANNOTATIONS_XML_UPDATE); DCHECK(!message.empty() || type == AuditorResult::Type::RESULT_OK || type == AuditorResult::Type::RESULT_IGNORE || type == AuditorResult::Type::ERROR_MISSING_TAG_USED || type == AuditorResult::Type::ERROR_NO_ANNOTATION || - type == AuditorResult::Type::ERROR_MISSING_EXTRA_ID || + type == AuditorResult::Type::ERROR_MISSING_SECOND_ID || type == AuditorResult::Type::ERROR_INCOMPLETED_ANNOTATION || type == AuditorResult::Type::ERROR_DIRECT_ASSIGNMENT); if (!message.empty()) @@ -77,31 +78,38 @@ flat_message.c_str()); } - case AuditorResult::Type::ERROR_RESERVED_UNIQUE_ID_HASH_CODE: + case AuditorResult::Type::ERROR_RESERVED_ID_HASH_CODE: DCHECK(details_.size()); return base::StringPrintf( - "Unique id '%s' in '%s:%i' has a hash code similar to a reserved " - "word and should be changed.", + "Id '%s' in '%s:%i' has a hash code equal to a reserved word and " + "should be changed.", details_[0].c_str(), file_path_.c_str(), line_); - case AuditorResult::Type::ERROR_DEPRECATED_UNIQUE_ID_HASH_CODE: + case AuditorResult::Type::ERROR_DEPRECATED_ID_HASH_CODE: DCHECK(details_.size()); return base::StringPrintf( - "Unique id '%s' in '%s:%i' has a hash code similar to a deprecated " - "unique id and should be changed.", + "Id '%s' in '%s:%i' has a hash code equal to a deprecated id and " + "should be changed.", details_[0].c_str(), file_path_.c_str(), line_); - case AuditorResult::Type::ERROR_DUPLICATE_UNIQUE_ID_HASH_CODE: + case AuditorResult::Type::ERROR_HASH_CODE_COLLISION: DCHECK_EQ(details_.size(), 2u); return base::StringPrintf( - "The following annotations have similar unique id " - "hash codes and should be updated: %s, %s.", + "The following annotations have colliding hash codes and should be " + "updated: %s, %s.", details_[0].c_str(), details_[1].c_str()); - case AuditorResult::Type::ERROR_UNIQUE_ID_INVALID_CHARACTER: + case AuditorResult::Type::ERROR_REPEATED_ID: + DCHECK_EQ(details_.size(), 2u); + return base::StringPrintf( + "The following annotations have equal ids and should be updated: " + "%s, %s.", + details_[0].c_str(), details_[1].c_str()); + + case AuditorResult::Type::ERROR_ID_INVALID_CHARACTER: DCHECK(details_.size()); return base::StringPrintf( - "Unique id '%s' in '%s:%i' contains an invalid character.", + "Id '%s' in '%s:%i' contains an invalid character.", details_[0].c_str(), file_path_.c_str(), line_); case AuditorResult::Type::ERROR_MISSING_ANNOTATION: @@ -115,7 +123,7 @@ "Annotation at '%s:%i' has the following missing fields: %s", file_path_.c_str(), line_, details_[0].c_str()); - case AuditorResult::Type::ERROR_MISSING_EXTRA_ID: + case AuditorResult::Type::ERROR_MISSING_SECOND_ID: return base::StringPrintf( "Second id of annotation at '%s:%i' should be updated as it has the " "same hash code as the first one.",
diff --git a/tools/traffic_annotation/auditor/auditor_result.h b/tools/traffic_annotation/auditor/auditor_result.h index e63aef1a..996921c 100644 --- a/tools/traffic_annotation/auditor/auditor_result.h +++ b/tools/traffic_annotation/auditor/auditor_result.h
@@ -18,18 +18,21 @@ // MISSING_TRAFFIC_ANNOTATION tag. ERROR_NO_ANNOTATION, // A function is called with NO_ANNOTATION tag. ERROR_SYNTAX, // Annotation syntax is not right. - ERROR_RESERVED_UNIQUE_ID_HASH_CODE, // A unique id has a hash code similar - // to a reserved word. - ERROR_DEPRECATED_UNIQUE_ID_HASH_CODE, // A unique id has a hash code - // equal to a deprecated one. - ERROR_DUPLICATE_UNIQUE_ID_HASH_CODE, // Two unique ids have equal hash - // codes. - ERROR_UNIQUE_ID_INVALID_CHARACTER, // A unique id contanins a characer - // which is not alphanumeric or - // underline. + ERROR_RESERVED_ID_HASH_CODE, // An id has a hash code equal to a reserved + // word. + ERROR_DEPRECATED_ID_HASH_CODE, // An id has a hash code equal to a + // deprecated one. + ERROR_HASH_CODE_COLLISION, // Two ids have equal hash codes. + ERROR_REPEATED_ID, // An id is used in two places without proper + // matching conditions. Proper conditions + // include cases that two annotations are + // completing each other or are different + // branches of one completing annotation. + ERROR_ID_INVALID_CHARACTER, // An id contanins a characer which is not + // alphanumeric or underline. ERROR_MISSING_ANNOTATION, // A function that requires annotation is not // annotated. - ERROR_MISSING_EXTRA_ID, // Annotation does not have a valid extra id. + ERROR_MISSING_SECOND_ID, // Annotation does not have a valid second id. ERROR_INCOMPLETE_ANNOTATION, // Annotation has some missing fields. ERROR_INCONSISTENT_ANNOTATION, // Annotation has some inconsistent fields. ERROR_MERGE_FAILED, // Two annotations that are supposed to merge
diff --git a/tools/traffic_annotation/auditor/instance.cc b/tools/traffic_annotation/auditor/instance.cc index ba7699b..1478ebb 100644 --- a/tools/traffic_annotation/auditor/instance.cc +++ b/tools/traffic_annotation/auditor/instance.cc
@@ -70,9 +70,9 @@ AnnotationInstance::AnnotationInstance(const AnnotationInstance& other) : proto(other.proto), type(other.type), - extra_id(other.extra_id), + second_id(other.second_id), unique_id_hash_code(other.unique_id_hash_code), - extra_id_hash_code(other.extra_id_hash_code){}; + second_id_hash_code(other.second_id_hash_code){}; AuditorResult AnnotationInstance::Deserialize( const std::vector<std::string>& serialized_lines, @@ -90,7 +90,7 @@ base::StringToInt(serialized_lines[start_line++], &line_number); std::string function_type = serialized_lines[start_line++]; const std::string& unique_id = serialized_lines[start_line++]; - extra_id = serialized_lines[start_line++]; + second_id = serialized_lines[start_line++]; // Decode function type. if (function_type == "Definition") { @@ -158,7 +158,7 @@ src->set_function(function_context); src->set_line(line_number); proto.set_unique_id(unique_id); - extra_id_hash_code = TrafficAnnotationAuditor::ComputeHashValue(extra_id); + second_id_hash_code = TrafficAnnotationAuditor::ComputeHashValue(second_id); return AuditorResult(AuditorResult::Type::RESULT_OK); } @@ -247,13 +247,13 @@ bool AnnotationInstance::IsCompletableWith( const AnnotationInstance& other) const { - if (type != AnnotationInstance::Type::ANNOTATION_PARTIAL || extra_id.empty()) + if (type != AnnotationInstance::Type::ANNOTATION_PARTIAL || second_id.empty()) return false; if (other.type == AnnotationInstance::Type::ANNOTATION_COMPLETING) { - return extra_id_hash_code == other.unique_id_hash_code; + return second_id_hash_code == other.unique_id_hash_code; } else if (other.type == AnnotationInstance::Type::ANNOTATION_BRANCHED_COMPLETING) { - return extra_id_hash_code == other.extra_id_hash_code; + return second_id_hash_code == other.second_id_hash_code; } else { return false; } @@ -279,8 +279,8 @@ } combination->type = AnnotationInstance::Type::ANNOTATION_COMPLETE; - combination->extra_id.clear(); - combination->extra_id_hash_code = 0; + combination->second_id.clear(); + combination->second_id_hash_code = 0; combination->comments = base::StringPrintf( "This annotation is a merge of the following two annotations:\n" "'%s' in '%s:%i' and '%s' in '%s:%i'.",
diff --git a/tools/traffic_annotation/auditor/instance.h b/tools/traffic_annotation/auditor/instance.h index 8a04494..c7b45c9 100644 --- a/tools/traffic_annotation/auditor/instance.h +++ b/tools/traffic_annotation/auditor/instance.h
@@ -63,6 +63,14 @@ // type. bool IsCompletableWith(const AnnotationInstance& other) const; + // Tells if annotation requires two ids. All annotations have the unique id, + // but partial annotations also require the completing id, and branched + // completing annotations require the group id. + bool NeedsTwoIDs() const { + return type == Type::ANNOTATION_PARTIAL || + type == Type::ANNOTATION_BRANCHED_COMPLETING; + } + // Combines |*this| partial annotation with a completing/branched_completing // annotation and returns the combined complete annotation. AuditorResult CreateCompleteAnnotation( @@ -75,12 +83,13 @@ // Type of the annotation. Type type; - // Extra id of the annotation (if available). - std::string extra_id; + // Extra id of the annotation (if available). This can be the completing id + // for partial annotations, or group id for branched completing annotations. + std::string second_id; // Hash codes of unique id and extra id (if available). int unique_id_hash_code; - int extra_id_hash_code; + int second_id_hash_code; std::string comments; };
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc index 65ea72a3..fa30c2d 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.cc
@@ -20,6 +20,7 @@ #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "tools/traffic_annotation/auditor/traffic_annotation_exporter.h" #include "tools/traffic_annotation/auditor/traffic_annotation_file_filter.h" +#include "tools/traffic_annotation/auditor/traffic_annotation_id_checker.h" namespace { @@ -114,7 +115,7 @@ if (!safe_list_loaded_ && !LoadSafeList()) return false; - // Create a file to pass options to clang scripts. + // Create a file to pass options to the clang tool running script. base::FilePath options_filepath; if (!base::CreateTemporaryFile(&options_filepath)) { LOG(ERROR) << "Could not create temporary options file."; @@ -152,10 +153,26 @@ if (path_filters.size()) { for (const auto& path_filter : path_filters) { - filter.GetRelevantFiles( - source_path_, - safe_list_[static_cast<int>(AuditorException::ExceptionType::ALL)], - path_filter, &file_paths); +// If path filter is a directory, search and add its contents. +// Otherwise add it if it is a relevant file which is not safe listed. +#if defined(OS_WIN) + base::FilePath current_path = base::FilePath( + base::FilePath::StringPieceType((base::UTF8ToWide(path_filter)))); +#else + base::FilePath current_path = base::FilePath(path_filter); +#endif + if (base::DirectoryExists(current_path)) { + filter.GetRelevantFiles(source_path_, + safe_list_[static_cast<int>( + AuditorException::ExceptionType::ALL)], + path_filter, &file_paths); + } else { + if (!TrafficAnnotationAuditor::IsSafeListed( + path_filter, AuditorException::ExceptionType::ALL) && + filter.IsFileRelevant(path_filter)) { + file_paths.push_back(path_filter); + } + } } } else { filter.GetRelevantFiles( @@ -380,10 +397,18 @@ // static const std::map<int, std::string>& -TrafficAnnotationAuditor::GetReservedUniqueIDs() { +TrafficAnnotationAuditor::GetReservedIDsMap() { return kReservedAnnotations; } +// static +std::set<int> TrafficAnnotationAuditor::GetReservedIDsSet() { + std::set<int> reserved_ids; + for (const auto& item : kReservedAnnotations) + reserved_ids.insert(item.first); + return reserved_ids; +} + void TrafficAnnotationAuditor::PurgeAnnotations( const std::set<int>& hash_codes) { extracted_annotations_.erase( @@ -396,150 +421,6 @@ extracted_annotations_.end()); } -bool TrafficAnnotationAuditor::CheckDuplicateHashes() { - const std::map<int, std::string> reserved_ids = GetReservedUniqueIDs(); - - std::map<int, std::vector<AnnotationID>> collisions; - std::set<int> to_be_purged; - std::set<int> deprecated_ids; - - // Load deprecated Hashcodes. - if (!TrafficAnnotationExporter(source_path_) - .GetDeprecatedHashCodes(&deprecated_ids)) { - return false; - } - - for (AnnotationInstance& instance : extracted_annotations_) { - // Check if partial and branched completing annotation have an extra id - // which is different from their unique id. - if ((instance.type == AnnotationInstance::Type::ANNOTATION_PARTIAL || - instance.type == - AnnotationInstance::Type::ANNOTATION_BRANCHED_COMPLETING) && - (instance.unique_id_hash_code == instance.extra_id_hash_code)) { - errors_.push_back(AuditorResult( - AuditorResult::Type::ERROR_MISSING_EXTRA_ID, std::string(), - instance.proto.source().file(), instance.proto.source().line())); - continue; - } - - AnnotationID current; - current.instance = &instance; - // Iterate over unique id and extra id. - for (int id = 0; id < 2; id++) { - if (id) { - // If it's an empty extra id, no further check is required. - if (instance.extra_id.empty()) { - continue; - } else { - current.text = instance.extra_id; - current.hash = instance.extra_id_hash_code; - if (instance.type == AnnotationInstance::Type::ANNOTATION_PARTIAL) { - current.type = AnnotationID::Type::kPatrialExtra; - } else if (instance.type == - AnnotationInstance::Type::ANNOTATION_BRANCHED_COMPLETING) { - current.type = AnnotationID::Type::kBranchedExtra; - } else { - current.type = AnnotationID::Type::kOther; - } - } - } else { - current.text = instance.proto.unique_id(); - current.hash = instance.unique_id_hash_code; - current.type = - instance.type == AnnotationInstance::Type::ANNOTATION_COMPLETING - ? AnnotationID::Type::kCompletingMain - : AnnotationID::Type::kOther; - } - - // If the id's hash code is the same as a reserved id, add an error. - if (base::ContainsKey(reserved_ids, current.hash)) { - errors_.push_back(AuditorResult( - AuditorResult::Type::ERROR_RESERVED_UNIQUE_ID_HASH_CODE, - current.text, instance.proto.source().file(), - instance.proto.source().line())); - continue; - } - - // If the id's hash code was formerly used by a deprecated annotation, - // add an error. - if (base::ContainsKey(deprecated_ids, current.hash)) { - errors_.push_back(AuditorResult( - AuditorResult::Type::ERROR_DEPRECATED_UNIQUE_ID_HASH_CODE, - current.text, instance.proto.source().file(), - instance.proto.source().line())); - continue; - } - - // Check for collisions. - if (!base::ContainsKey(collisions, current.hash)) { - collisions[current.hash] = std::vector<AnnotationID>(); - } else { - // Add error for ids with the same hash codes. If the texts are really - // different, there is a hash collision and should be corrected in any - // case. Otherwise, it's an error if it doesn't match the criteria that - // are previously spcified in definition of AnnotationID struct. - for (const auto& other : collisions[current.hash]) { - if (current.text == other.text && - ((current.type == AnnotationID::Type::kPatrialExtra && - (other.type == AnnotationID::Type::kPatrialExtra || - other.type == AnnotationID::Type::kCompletingMain || - other.type == AnnotationID::Type::kBranchedExtra)) || - (other.type == AnnotationID::Type::kPatrialExtra && - (current.type == AnnotationID::Type::kCompletingMain || - current.type == AnnotationID::Type::kBranchedExtra)) || - (current.type == AnnotationID::Type::kBranchedExtra && - other.type == AnnotationID::Type::kBranchedExtra))) { - continue; - } - - AuditorResult error( - AuditorResult::Type::ERROR_DUPLICATE_UNIQUE_ID_HASH_CODE, - base::StringPrintf( - "%s in '%s:%i'", current.text.c_str(), - current.instance->proto.source().file().c_str(), - current.instance->proto.source().line())); - error.AddDetail( - base::StringPrintf("%s in '%s:%i'", other.text.c_str(), - other.instance->proto.source().file().c_str(), - other.instance->proto.source().line())); - - errors_.push_back(error); - to_be_purged.insert(current.hash); - to_be_purged.insert(other.hash); - } - } - collisions[current.hash].push_back(current); - } - } - - PurgeAnnotations(to_be_purged); - return true; -} - -void TrafficAnnotationAuditor::CheckUniqueIDsFormat() { - std::set<int> to_be_purged; - for (const AnnotationInstance& instance : extracted_annotations_) { - if (!base::ContainsOnlyChars(base::ToLowerASCII(instance.proto.unique_id()), - "0123456789_abcdefghijklmnopqrstuvwxyz")) { - errors_.push_back(AuditorResult( - AuditorResult::Type::ERROR_UNIQUE_ID_INVALID_CHARACTER, - instance.proto.unique_id(), instance.proto.source().file(), - instance.proto.source().line())); - to_be_purged.insert(instance.unique_id_hash_code); - } - if (!instance.extra_id.empty() && - !base::ContainsOnlyChars(base::ToLowerASCII(instance.extra_id), - "0123456789_abcdefghijklmnopqrstuvwxyz")) { - errors_.push_back( - AuditorResult(AuditorResult::Type::ERROR_UNIQUE_ID_INVALID_CHARACTER, - instance.extra_id, instance.proto.source().file(), - instance.proto.source().line())); - to_be_purged.insert(instance.unique_id_hash_code); - } - } - PurgeAnnotations(to_be_purged); -} - void TrafficAnnotationAuditor::CheckAllRequiredFunctionsAreAnnotated() { for (const CallInstance& call : extracted_calls_) { if (!call.is_annotated && !CheckIfCallCanBeUnannotated(call)) { @@ -698,10 +579,20 @@ } bool TrafficAnnotationAuditor::RunAllChecks() { - if (!CheckDuplicateHashes()) + std::set<int> deprecated_ids; + if (!TrafficAnnotationExporter(source_path_) + .GetDeprecatedHashCodes(&deprecated_ids)) { return false; - CheckUniqueIDsFormat(); - CheckAnnotationsContents(); + } + TrafficAnnotationIDChecker id_checker(GetReservedIDsSet(), deprecated_ids); + id_checker.Load(extracted_annotations_); + id_checker.CheckIDs(&errors_); + + // Only check annotation contents if IDs are all OK, because if there are + // id errors, there might be some mismatching annotations and irrelevant + // content errors. + if (errors_.empty()) + CheckAnnotationsContents(); CheckAllRequiredFunctionsAreAnnotated(); return true;
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h index 940afe9..c12c2a5 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor.h +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor.h
@@ -75,17 +75,6 @@ bool IsSafeListed(const std::string& file_path, AuditorException::ExceptionType exception_type); - // Checks to see if any unique id or extra id or their hash code are - // duplicated, either in currently existing annotations, or in deprecated - // ones. Adds errors to |errors_| and purges annotations with duplicate ids. - // Returns false if any errors happen while checking. - bool CheckDuplicateHashes(); - - // Checks to see if unique ids only include alphanumeric characters and - // underline. Adds errors to |errors_| and purges annotations with - // incorrect ids. - void CheckUniqueIDsFormat(); - // Checks to see if annotation contents are valid. Complete annotations should // have all required fields and be consistent, and incomplete annotations // should be completed with each other. Merges all matching incomplete @@ -106,7 +95,13 @@ // texts. This list includes all unique ids that are defined in // net/traffic_annotation/network_traffic_annotation.h and // net/traffic_annotation/network_traffic_annotation_test_helper.h - static const std::map<int, std::string>& GetReservedUniqueIDs(); + static const std::map<int, std::string>& GetReservedIDsMap(); + + // Returns a set of reserved unique ids' hash codes. This set includes all + // unique ids that are defined in + // net/traffic_annotation/network_traffic_annotation.h and + // net/traffic_annotation/network_traffic_annotation_test_helper.h + static std::set<int> GetReservedIDsSet(); // Removes annotations whose unique id hash code are given. void PurgeAnnotations(const std::set<int>& hash_codes);
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc index a5564ff5..b82e9cf 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor_ui.cc
@@ -415,7 +415,7 @@ TrafficAnnotationExporter exporter(source_path); if (!exporter.UpdateAnnotations( auditor.extracted_annotations(), - TrafficAnnotationAuditor::GetReservedUniqueIDs())) { + TrafficAnnotationAuditor::GetReservedIDsMap())) { return 1; } if (exporter.modified()) {
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc index 63ab3969..7b7720c 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_auditor_unittest.cc
@@ -19,6 +19,7 @@ #include "testing/gtest/include/gtest/gtest.h" #include "tools/traffic_annotation/auditor/traffic_annotation_exporter.h" #include "tools/traffic_annotation/auditor/traffic_annotation_file_filter.h" +#include "tools/traffic_annotation/auditor/traffic_annotation_id_checker.h" namespace { @@ -52,6 +53,7 @@ .Append(FILE_PATH_LITERAL("scripts")) .Append(FILE_PATH_LITERAL("annotations_xml_downstream_caller.py")); +const std::set<int> kDummyDeprecatedIDs = {100, 101, 102}; } // namespace using namespace testing; @@ -86,11 +88,16 @@ source_path_.Append(FILE_PATH_LITERAL("out")) .Append(FILE_PATH_LITERAL("Default")), clang_tool_path); + + id_checker_ = std::make_unique<TrafficAnnotationIDChecker>( + TrafficAnnotationAuditor::GetReservedIDsSet(), kDummyDeprecatedIDs); } const base::FilePath source_path() const { return source_path_; } const base::FilePath tests_folder() const { return tests_folder_; }; TrafficAnnotationAuditor& auditor() { return *auditor_; } + TrafficAnnotationIDChecker& id_checker() { return *id_checker_; } + std::vector<AuditorResult>* errors() { return &errors_; } protected: // Deserializes an annotation or a call instance from a sample file similar to @@ -100,6 +107,13 @@ // Creates a complete annotation instance using sample files. AnnotationInstance CreateAnnotationInstanceSample(); + AnnotationInstance CreateAnnotationInstanceSample( + AnnotationInstance::Type type, + int unique_id); + AnnotationInstance CreateAnnotationInstanceSample( + AnnotationInstance::Type type, + int unique_id, + int second_id); void SetAnnotationForTesting(const AnnotationInstance& instance) { std::vector<AnnotationInstance> annotations; @@ -108,10 +122,20 @@ auditor_->ClearErrorsForTesting(); } + void RunIDChecker(const AnnotationInstance& instance) { + std::vector<AnnotationInstance> annotations; + annotations.push_back(instance); + errors_.clear(); + id_checker_->Load(annotations); + id_checker_->CheckIDs(&errors_); + } + private: base::FilePath source_path_; base::FilePath tests_folder_; std::unique_ptr<TrafficAnnotationAuditor> auditor_; + std::unique_ptr<TrafficAnnotationIDChecker> id_checker_; + std::vector<AuditorResult> errors_; }; AuditorResult::Type TrafficAnnotationAuditorTest::Deserialize( @@ -138,6 +162,30 @@ return instance; } +AnnotationInstance TrafficAnnotationAuditorTest::CreateAnnotationInstanceSample( + AnnotationInstance::Type type, + int unique_id) { + return CreateAnnotationInstanceSample(type, unique_id, 0); +} + +AnnotationInstance TrafficAnnotationAuditorTest::CreateAnnotationInstanceSample( + AnnotationInstance::Type type, + int unique_id, + int second_id) { + AnnotationInstance instance = CreateAnnotationInstanceSample(); + instance.type = type; + instance.unique_id_hash_code = unique_id; + instance.proto.set_unique_id(base::StringPrintf("S%i", unique_id)); + if (second_id) { + instance.second_id = base::StringPrintf("S%i", second_id); + instance.second_id_hash_code = second_id; + } else { + instance.second_id.clear(); + instance.second_id_hash_code = 0; + } + return instance; +} + // Tests if the two hash computation functions have the same result. TEST_F(TrafficAnnotationAuditorTest, HashFunctionCheck) { TEST_HASH_CODE("test"); @@ -342,9 +390,9 @@ } } -// Tests if TrafficAnnotationAuditor::GetReservedUniqueIDs has all known ids and +// Tests if TrafficAnnotationAuditor::GetReservedIDsMap has all known ids and // they have correct text. -TEST_F(TrafficAnnotationAuditorTest, GetReservedUniqueIDs) { +TEST_F(TrafficAnnotationAuditorTest, GetReservedIDsCoverage) { int expected_ids[] = { TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code, PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS.unique_id_hash_code, @@ -354,7 +402,7 @@ NO_TRAFFIC_ANNOTATION_BUG_656607.unique_id_hash_code}; std::map<int, std::string> reserved_words = - TrafficAnnotationAuditor::GetReservedUniqueIDs(); + TrafficAnnotationAuditor::GetReservedIDsMap(); for (int id : expected_ids) { EXPECT_TRUE(base::ContainsKey(reserved_words, id)); @@ -363,157 +411,171 @@ } } -// Tests if TrafficAnnotationAuditor::CheckDuplicateHashes works as expected. -TEST_F(TrafficAnnotationAuditorTest, CheckDuplicateHashes) { - // Load a valid annotation. - AnnotationInstance instance = CreateAnnotationInstanceSample(); +// Tests if use of reserved ids are detected. +TEST_F(TrafficAnnotationAuditorTest, CheckReservedIDsUsageDetection) { + for (const auto& reserved_id : auditor().GetReservedIDsSet()) { + RunIDChecker(CreateAnnotationInstanceSample( + AnnotationInstance::Type::ANNOTATION_COMPLETE, reserved_id)); + EXPECT_EQ(1u, errors()->size()); + EXPECT_EQ(AuditorResult::Type::ERROR_RESERVED_ID_HASH_CODE, + (*errors())[0].type()); - const std::map<int, std::string>& reserved_words = - TrafficAnnotationAuditor::GetReservedUniqueIDs(); + RunIDChecker(CreateAnnotationInstanceSample( + AnnotationInstance::Type::ANNOTATION_PARTIAL, 1, reserved_id)); + EXPECT_EQ(1u, errors()->size()); + EXPECT_EQ(AuditorResult::Type::ERROR_RESERVED_ID_HASH_CODE, + (*errors())[0].type()); + } +} +// Tests if use of deprecated ids are detected. +TEST_F(TrafficAnnotationAuditorTest, CheckDeprecatedIDsUsageDetection) { + for (const auto& deprecated_id : kDummyDeprecatedIDs) { + RunIDChecker(CreateAnnotationInstanceSample( + AnnotationInstance::Type::ANNOTATION_COMPLETE, deprecated_id)); + EXPECT_EQ(1u, errors()->size()); + EXPECT_EQ(AuditorResult::Type::ERROR_DEPRECATED_ID_HASH_CODE, + (*errors())[0].type()); + + RunIDChecker(CreateAnnotationInstanceSample( + AnnotationInstance::Type::ANNOTATION_PARTIAL, 1, deprecated_id)); + EXPECT_EQ(1u, errors()->size()); + EXPECT_EQ(AuditorResult::Type::ERROR_DEPRECATED_ID_HASH_CODE, + (*errors())[0].type()); + } +} + +// Tests if use of repeated ids are detected. +TEST_F(TrafficAnnotationAuditorTest, CheckRepeatedIDsDetection) { std::vector<AnnotationInstance> annotations; - // Check for reserved words hash code duplication errors. - int next_id = 0; - for (const auto& reserved_word : reserved_words) { - EXPECT_FALSE(base::ContainsKey(reserved_words, next_id)); - instance.unique_id_hash_code = next_id; - instance.extra_id_hash_code = reserved_word.first; - instance.extra_id = "SomeID"; - annotations.push_back(instance); - next_id++; - - EXPECT_FALSE(base::ContainsKey(reserved_words, next_id)); - instance.unique_id_hash_code = reserved_word.first; - instance.extra_id_hash_code = next_id; - instance.extra_id.clear(); - annotations.push_back(instance); - next_id++; - } - - auditor().SetExtractedAnnotationsForTesting(annotations); - auditor().ClearErrorsForTesting(); - auditor().CheckDuplicateHashes(); - EXPECT_EQ(auditor().errors().size(), annotations.size()); - for (const auto& error : auditor().errors()) { - EXPECT_EQ(error.type(), - AuditorResult::Type::ERROR_RESERVED_UNIQUE_ID_HASH_CODE); - } - // Check if several different hash codes result in no error. - annotations.clear(); - instance.extra_id_hash_code = 0; - instance.extra_id.clear(); for (int i = 0; i < 10; i++) { - // Ensure that the test id is not a reserved hash code. - EXPECT_FALSE(base::ContainsKey(reserved_words, i)); - instance.unique_id_hash_code = i; - annotations.push_back(instance); + annotations.push_back(CreateAnnotationInstanceSample( + AnnotationInstance::Type::ANNOTATION_COMPLETE, i)); } - auditor().SetExtractedAnnotationsForTesting(annotations); - auditor().ClearErrorsForTesting(); - auditor().CheckDuplicateHashes(); - EXPECT_EQ(auditor().errors().size(), 0u); + id_checker().Load(annotations); + errors()->clear(); + id_checker().CheckIDs(errors()); + EXPECT_EQ(0u, errors()->size()); // Check if repeating the same hash codes results in errors. annotations.clear(); for (int i = 0; i < 10; i++) { - instance.unique_id_hash_code = i; - annotations.push_back(instance); - annotations.push_back(instance); + annotations.push_back(CreateAnnotationInstanceSample( + AnnotationInstance::Type::ANNOTATION_COMPLETE, i)); + annotations.push_back(annotations.back()); } - auditor().SetExtractedAnnotationsForTesting(annotations); - auditor().ClearErrorsForTesting(); - auditor().CheckDuplicateHashes(); - EXPECT_EQ(auditor().errors().size(), 10u); - for (const auto& error : auditor().errors()) { - EXPECT_EQ(error.type(), - AuditorResult::Type::ERROR_DUPLICATE_UNIQUE_ID_HASH_CODE); + id_checker().Load(annotations); + errors()->clear(); + id_checker().CheckIDs(errors()); + EXPECT_EQ(10u, errors()->size()); + for (const auto& error : *errors()) { + EXPECT_EQ(error.type(), AuditorResult::Type::ERROR_REPEATED_ID); } +} - // Check if the same value for unique id and extra id only results in error in - // types with valid extra id. - instance.unique_id_hash_code = 1; - instance.extra_id_hash_code = 1; +// Tests if having the same unique id and second id is detected. +TEST_F(TrafficAnnotationAuditorTest, CheckSimilarUniqueAndSecondIDsDetection) { const int last_type = static_cast<int>(AnnotationInstance::Type::ANNOTATION_INSTANCE_TYPE_LAST); for (int type = 0; type <= last_type; type++) { - instance.type = static_cast<AnnotationInstance::Type>(type); - SetAnnotationForTesting(instance); - auditor().CheckDuplicateHashes(); - SCOPED_TRACE(type); - if (instance.type == AnnotationInstance::Type::ANNOTATION_COMPLETE || - instance.type == AnnotationInstance::Type::ANNOTATION_COMPLETING) { - // Extra id of these two types is not used. - EXPECT_EQ(auditor().errors().size(), 0u); - } else { - EXPECT_EQ(auditor().errors().size(), 1u); - } + AnnotationInstance instance = CreateAnnotationInstanceSample( + static_cast<AnnotationInstance::Type>(type), 1, 1); + RunIDChecker(instance); + EXPECT_EQ(instance.NeedsTwoIDs() ? 1u : 0u, errors()->size()) << type; } +} - // Check for unique id / extra id collision cases. - AnnotationInstance other = instance; +// Tests Unique id and Second id collision cases. +TEST_F(TrafficAnnotationAuditorTest, CheckDuplicateIDsDetection) { + const int last_type = + static_cast<int>(AnnotationInstance::Type::ANNOTATION_INSTANCE_TYPE_LAST); + for (int type1 = 0; type1 < last_type; type1++) { for (int type2 = type1; type2 <= last_type; type2++) { - // Iterate different possiblities of common id. - for (int common1 = 0; common1 < 2; common1++) { - for (int common2 = 0; common2 < 2; common2++) { - instance.type = static_cast<AnnotationInstance::Type>(type1); - other.type = static_cast<AnnotationInstance::Type>(type2); - instance.unique_id_hash_code = common1 ? 1 : 2; - instance.extra_id_hash_code = common1 ? 2 : 1; - other.unique_id_hash_code = common2 ? 2 : 3; - other.extra_id_hash_code = common2 ? 3 : 2; + for (int id1 = 1; id1 < 5; id1++) { + for (int id2 = 1; id2 < 5; id2++) { + for (int id3 = 1; id3 < 5; id3++) { + for (int id4 = 1; id4 < 5; id4++) { + SCOPED_TRACE( + base::StringPrintf("Testing (%i, %i, %i, %i, %i, %i).", type1, + type2, id1, id2, id3, id4)); - annotations.clear(); - annotations.push_back(instance); - annotations.push_back(other); - auditor().SetExtractedAnnotationsForTesting(annotations); - auditor().ClearErrorsForTesting(); - auditor().CheckDuplicateHashes(); + AnnotationInstance instance1 = CreateAnnotationInstanceSample( + static_cast<AnnotationInstance::Type>(type1), id1, id2); + AnnotationInstance instance2 = CreateAnnotationInstanceSample( + static_cast<AnnotationInstance::Type>(type2), id3, id4); + std::vector<AnnotationInstance> annotations; + annotations.push_back(instance1); + annotations.push_back(instance2); + id_checker().Load(annotations); + errors()->clear(); + id_checker().CheckIDs(errors()); - bool acceptable = false; - switch (instance.type) { - case AnnotationInstance::Type::ANNOTATION_COMPLETE: - // The unique id of a complete annotation must not be reused. - acceptable = - (instance.unique_id_hash_code != other.unique_id_hash_code && - instance.unique_id_hash_code != other.extra_id_hash_code); - break; + std::set<int> unique_ids; + bool first_needs_two = instance1.NeedsTwoIDs(); + bool second_needs_two = instance2.NeedsTwoIDs(); + unique_ids.insert(id1); + if (first_needs_two) + unique_ids.insert(id2); + unique_ids.insert(id3); + if (second_needs_two) + unique_ids.insert(id4); - case AnnotationInstance::Type::ANNOTATION_PARTIAL: - // The unique id of a partial annotation should be unique. - // It's extra id can be used as unique id of a completing - // annotation or extra id of a branched completing one. - if (instance.unique_id_hash_code != other.unique_id_hash_code && - instance.unique_id_hash_code != other.extra_id_hash_code) { - if (instance.extra_id_hash_code == other.unique_id_hash_code) { - acceptable = - (other.type == - AnnotationInstance::Type::ANNOTATION_COMPLETING); - } else if (instance.extra_id_hash_code == - other.extra_id_hash_code) { - acceptable = - (other.type == AnnotationInstance::Type:: - ANNOTATION_BRANCHED_COMPLETING); + if (first_needs_two && second_needs_two) { + // If both need two ids, either the 4 ids should be different, + // or the second ids should be equal and both annotations should + // be of types partial or branched completing. + if (unique_ids.size() == 4) { + EXPECT_TRUE(errors()->empty()); + } else if (unique_ids.size() == 3) { + bool acceptable = + (id2 == id4) && + (type1 == + static_cast<int>( + AnnotationInstance::Type::ANNOTATION_PARTIAL) || + type1 == static_cast<int>( + AnnotationInstance::Type:: + ANNOTATION_BRANCHED_COMPLETING)) && + (type2 == + static_cast<int>( + AnnotationInstance::Type::ANNOTATION_PARTIAL) || + type2 == static_cast<int>( + AnnotationInstance::Type:: + ANNOTATION_BRANCHED_COMPLETING)); + + EXPECT_EQ(acceptable, errors()->empty()); } else { - acceptable = true; + EXPECT_FALSE(errors()->empty()); + } + } else if (first_needs_two && !second_needs_two) { + // If just the first one needs two ids, then either the 3 ids + // should be different or the first annotation would be partial + // and the second completing, with one common id. + if (unique_ids.size() == 3) { + EXPECT_TRUE(errors()->empty()); + } else if (unique_ids.size() == 2) { + bool acceptable = + (id2 == id3) && + (type1 == + static_cast<int>( + AnnotationInstance::Type::ANNOTATION_PARTIAL) && + type2 == static_cast<int>(AnnotationInstance::Type:: + ANNOTATION_COMPLETING)); + EXPECT_EQ(errors()->empty(), acceptable); + } else { + EXPECT_FALSE(errors()->empty()); + } + } else if (!first_needs_two && second_needs_two) { + // Can only be valid if all 3 are different. + EXPECT_EQ(unique_ids.size() == 3, errors()->empty()); + } else { + // If none requires two ids, it can only be valid if ids are + // different. + EXPECT_EQ(unique_ids.size() == 2, errors()->empty()); } } - break; - - case AnnotationInstance::Type::ANNOTATION_COMPLETING: - case AnnotationInstance::Type::ANNOTATION_INSTANCE_TYPE_LAST: - // Considering the other annotation has a higher type number, - // unique id of a completing or branched completing annotation - // should not be used as unique or extra id of another one. - acceptable = - (instance.unique_id_hash_code != other.unique_id_hash_code && - instance.unique_id_hash_code != other.extra_id_hash_code); - break; - - default: - NOTREACHED(); } } } @@ -521,46 +583,49 @@ } } -// Tests if TrafficAnnotationAuditor::CheckUniqueIDsFormat results are as -// expected. -TEST_F(TrafficAnnotationAuditorTest, CheckUniqueIDsFormat) { +// Tests if IDs format is correctly checked. +TEST_F(TrafficAnnotationAuditorTest, CheckIDsFormat) { std::map<std::string, bool> test_cases = { {"ID1", true}, {"id2", true}, {"Id_3", true}, {"ID?4", false}, {"ID:5", false}, {"ID>>6", false}, }; - std::vector<AnnotationInstance> annotations; AnnotationInstance instance = CreateAnnotationInstanceSample(); - unsigned int false_samples_count = 0; - - // Test cases one by one. for (const auto& test_case : test_cases) { + // Set type to complete to require just unique id. instance.type = AnnotationInstance::Type::ANNOTATION_COMPLETE; instance.proto.set_unique_id(test_case.first); - instance.extra_id.clear(); - SetAnnotationForTesting(instance); - annotations.push_back(instance); - auditor().CheckUniqueIDsFormat(); - EXPECT_EQ(auditor().errors().size(), test_case.second ? 0u : 1u); - if (!test_case.second) - false_samples_count++; + instance.unique_id_hash_code = 1; + RunIDChecker(instance); + EXPECT_EQ(test_case.second ? 0u : 1u, errors()->size()) << test_case.first; - instance.type = AnnotationInstance::Type::ANNOTATION_COMPLETING; + // Set type to partial to require both ids. + instance.type = AnnotationInstance::Type::ANNOTATION_PARTIAL; instance.proto.set_unique_id("Something_Good"); - instance.extra_id = test_case.first; - SetAnnotationForTesting(instance); - annotations.push_back(instance); - auditor().CheckUniqueIDsFormat(); - EXPECT_EQ(auditor().errors().size(), test_case.second ? 0u : 1u); - if (!test_case.second) - false_samples_count++; + instance.second_id = test_case.first; + instance.unique_id_hash_code = 1; + instance.second_id_hash_code = 2; + RunIDChecker(instance); + EXPECT_EQ(test_case.second ? 0u : 1u, errors()->size()) << test_case.first; } // Test all cases together. - auditor().SetExtractedAnnotationsForTesting(annotations); - auditor().ClearErrorsForTesting(); - auditor().CheckUniqueIDsFormat(); - EXPECT_EQ(auditor().errors().size(), false_samples_count); + std::vector<AnnotationInstance> annotations; + instance.type = AnnotationInstance::Type::ANNOTATION_COMPLETE; + instance.unique_id_hash_code = 1; + + unsigned int false_samples_count = 0; + for (const auto& test_case : test_cases) { + instance.proto.set_unique_id(test_case.first); + instance.unique_id_hash_code++; + annotations.push_back(instance); + if (!test_case.second) + false_samples_count++; + } + id_checker().Load(annotations); + errors()->clear(); + id_checker().CheckIDs(errors()); + EXPECT_EQ(false_samples_count, errors()->size()); } // Tests if TrafficAnnotationAuditor::CheckAllRequiredFunctionsAreAnnotated @@ -770,40 +835,35 @@ // Tests if AnnotationInstance::IsCompletableWith works as expected. TEST_F(TrafficAnnotationAuditorTest, IsCompletableWith) { - AnnotationInstance instance = CreateAnnotationInstanceSample(); - AnnotationInstance other = instance; - const int last_type = static_cast<int>(AnnotationInstance::Type::ANNOTATION_INSTANCE_TYPE_LAST); for (int type1 = 0; type1 < last_type; type1++) { for (int type2 = 0; type2 <= last_type; type2++) { // Iterate all combination of common/specified ids. for (int ids = 0; ids < 256; ids++) { - instance.type = static_cast<AnnotationInstance::Type>(type1); - other.type = static_cast<AnnotationInstance::Type>(type2); - instance.unique_id_hash_code = ids % 4; - instance.extra_id_hash_code = (ids >> 2) % 4; - other.unique_id_hash_code = (ids >> 4) % 4; - other.extra_id_hash_code = (ids >> 6); - instance.extra_id = - instance.extra_id_hash_code ? "SomeID" : std::string(); - other.extra_id = other.extra_id_hash_code ? "SomeID" : std::string(); + AnnotationInstance instance1 = CreateAnnotationInstanceSample( + static_cast<AnnotationInstance::Type>(type1), ids % 4, + (ids >> 2) % 4); + AnnotationInstance instance2 = CreateAnnotationInstanceSample( + static_cast<AnnotationInstance::Type>(type2), (ids >> 4) % 4, + (ids >> 6)); bool expectation = false; - // It's compatible only if the first one is partial and has extra_id, + // It's compatible only if the first one is partial and has second_id, // and the second one is either completing with matching unique id, or - // branched completing with matching extra id. - if (instance.type == AnnotationInstance::Type::ANNOTATION_PARTIAL && - !instance.extra_id.empty()) { + // branched completing with matching second id. + if (instance1.type == AnnotationInstance::Type::ANNOTATION_PARTIAL && + !instance1.second_id.empty()) { expectation |= - (other.type == AnnotationInstance::Type::ANNOTATION_COMPLETING && - instance.extra_id_hash_code == other.unique_id_hash_code); + (instance2.type == + AnnotationInstance::Type::ANNOTATION_COMPLETING && + instance1.second_id_hash_code == instance2.unique_id_hash_code); expectation |= - (other.type == + (instance2.type == AnnotationInstance::Type::ANNOTATION_BRANCHED_COMPLETING && - instance.extra_id_hash_code == other.extra_id_hash_code); + instance1.second_id_hash_code == instance2.second_id_hash_code); } - EXPECT_EQ(instance.IsCompletableWith(other), expectation); + EXPECT_EQ(instance1.IsCompletableWith(instance2), expectation); } } } @@ -823,8 +883,8 @@ // Partial and Completing. instance.type = AnnotationInstance::Type::ANNOTATION_PARTIAL; other.type = AnnotationInstance::Type::ANNOTATION_COMPLETING; - instance.extra_id_hash_code = 1; - instance.extra_id = "SomeID"; + instance.second_id_hash_code = 1; + instance.second_id = "SomeID"; other.unique_id_hash_code = 1; EXPECT_EQ(instance.CreateCompleteAnnotation(other, &combination).type(), AuditorResult::Type::RESULT_OK); @@ -832,9 +892,9 @@ // Partial and Branched Completing. other.type = AnnotationInstance::Type::ANNOTATION_BRANCHED_COMPLETING; - instance.extra_id_hash_code = 1; - other.extra_id_hash_code = 1; - other.extra_id = "SomeID"; + instance.second_id_hash_code = 1; + other.second_id_hash_code = 1; + other.second_id = "SomeID"; EXPECT_EQ(instance.CreateCompleteAnnotation(other, &combination).type(), AuditorResult::Type::RESULT_OK); EXPECT_EQ(combination.unique_id_hash_code, other.unique_id_hash_code); @@ -842,9 +902,9 @@ // Inconsistent field. other = instance; other.type = AnnotationInstance::Type::ANNOTATION_BRANCHED_COMPLETING; - instance.extra_id_hash_code = 1; - other.extra_id_hash_code = 1; - other.extra_id = "SomeID"; + instance.second_id_hash_code = 1; + other.second_id_hash_code = 1; + other.second_id = "SomeID"; instance.proto.mutable_semantics()->set_destination( traffic_annotation:: NetworkTrafficAnnotation_TrafficSemantics_Destination_WEBSITE);
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc b/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc index 09a051ae..20460ca 100644 --- a/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc +++ b/tools/traffic_annotation/auditor/traffic_annotation_file_filter.cc
@@ -36,15 +36,9 @@ "MISSING_TRAFFIC_ANNOTATION", "TRAFFIC_ANNOTATION_FOR_TESTS", "PARTIAL_TRAFFIC_ANNOTATION_FOR_TESTS", - "SSLClientSocket", // SSLClientSocket:: - "TCPClientSocket", // TCPClientSocket:: - "UDPClientSocket", // UDPClientSocket:: "URLFetcher::Create", // This one is used with class as it's too generic. - "CreateDatagramClientSocket", // ClientSocketFactory:: - "CreateSSLClientSocket", // ClientSocketFactory:: - "CreateTransportClientSocket", // ClientSocketFactory:: - "CreateRequest", // URLRequestContext:: - nullptr // End Marker + "CreateRequest", // URLRequestContext:: + nullptr // End Marker }; } // namespace @@ -101,6 +95,14 @@ return false; } + // Ignore unittest files to speed up the tests. They would be only tested when + // filters are disabled. + pos = file_path.length() - 12; + if (pos >= 0 && (!strcmp("_unittest.cc", file_path.c_str() + pos) || + !strcmp("_unittest.mm", file_path.c_str() + pos))) { + return false; + } + base::FilePath converted_file_path = #if defined(OS_WIN) base::FilePath(
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_id_checker.cc b/tools/traffic_annotation/auditor/traffic_annotation_id_checker.cc new file mode 100644 index 0000000..f5abd0e --- /dev/null +++ b/tools/traffic_annotation/auditor/traffic_annotation_id_checker.cc
@@ -0,0 +1,182 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "tools/traffic_annotation/auditor/traffic_annotation_id_checker.h" + +#include "base/stl_util.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" + +TrafficAnnotationIDChecker::TrafficAnnotationIDChecker( + const std::set<int>& reserved_ids, + const std::set<int>& deprecated_ids) + : deprecated_ids_(deprecated_ids), reserved_ids_(reserved_ids) {} + +TrafficAnnotationIDChecker::~TrafficAnnotationIDChecker() = default; + +void TrafficAnnotationIDChecker::Load( + const std::vector<AnnotationInstance>& extracted_annotations) { + annotations_.clear(); + for (const AnnotationInstance& instance : extracted_annotations) { + AnnotationItem item; + item.type = instance.type; + item.ids[0].hash_code = instance.unique_id_hash_code; + item.ids[0].text = instance.proto.unique_id(); + if (instance.NeedsTwoIDs()) { + item.ids_count = 2; + item.ids[1].hash_code = instance.second_id_hash_code; + item.ids[1].text = instance.second_id; + } else { + item.ids_count = 1; + } + item.file_path = instance.proto.source().file(); + item.line_number = instance.proto.source().line(); + annotations_.push_back(item); + } +} + +void TrafficAnnotationIDChecker::CheckIDs(std::vector<AuditorResult>* errors) { + CheckIDsFormat(errors); + CheckForSecondIDs(errors); + CheckForInvalidValues( + reserved_ids_, AuditorResult::Type::ERROR_RESERVED_ID_HASH_CODE, errors); + CheckForInvalidValues(deprecated_ids_, + AuditorResult::Type::ERROR_DEPRECATED_ID_HASH_CODE, + errors); + CheckForHashCollisions(errors); + CheckForInvalidRepeatedIDs(errors); +} + +void TrafficAnnotationIDChecker::CheckForInvalidValues( + const std::set<int>& invalid_set, + AuditorResult::Type error_type, + std::vector<AuditorResult>* errors) { + for (AnnotationItem& item : annotations_) { + for (int i = 0; i < item.ids_count; i++) { + if (base::ContainsKey(invalid_set, item.ids[i].hash_code)) { + errors->push_back(AuditorResult(error_type, item.ids[i].text, + item.file_path, item.line_number)); + } + } + } +} + +void TrafficAnnotationIDChecker::CheckForSecondIDs( + std::vector<AuditorResult>* errors) { + for (AnnotationItem& item : annotations_) { + if (item.ids_count == 2 && + (item.ids[1].text.empty() || + item.ids[0].hash_code == item.ids[1].hash_code)) { + errors->push_back( + AuditorResult(AuditorResult::Type::ERROR_MISSING_SECOND_ID, + std::string(), item.file_path, item.line_number)); + // Remove this id from next tests. + item.ids_count = 0; + } + } +} + +void TrafficAnnotationIDChecker::CheckForHashCollisions( + std::vector<AuditorResult>* errors) { + std::map<int, std::string> collisions; + for (AnnotationItem& item : annotations_) { + for (int i = 0; i < item.ids_count; i++) { + if (!base::ContainsKey(collisions, item.ids[i].hash_code)) { + collisions.insert( + std::make_pair(item.ids[i].hash_code, item.ids[i].text)); + } else { + if (item.ids[i].text != collisions[item.ids[i].hash_code]) { + AuditorResult error(AuditorResult::Type::ERROR_HASH_CODE_COLLISION, + item.ids[i].text); + error.AddDetail(collisions[item.ids[i].hash_code]); + errors->push_back(error); + } + } + } + } +} + +void TrafficAnnotationIDChecker::CheckForInvalidRepeatedIDs( + std::vector<AuditorResult>* errors) { + std::map<int, AnnotationItem*> first_ids; + std::map<int, AnnotationItem*> second_ids; + + // Check if first ids are unique. + for (AnnotationItem& item : annotations_) { + if (!base::ContainsKey(first_ids, item.ids[0].hash_code)) { + first_ids[item.ids[0].hash_code] = &item; + } else { + errors->push_back(CreateRepeatedIDError( + item.ids[0].text, item, *first_ids[item.ids[0].hash_code])); + } + } + + // If a second id is equal to a first id, owner of the second id should be of + // type PARTIAL and owner of the first id should be of type COMPLETING. + for (AnnotationItem& item : annotations_) { + if (item.ids_count == 2 && + base::ContainsKey(first_ids, item.ids[1].hash_code)) { + if (item.type != AnnotationInstance::Type::ANNOTATION_PARTIAL || + first_ids[item.ids[1].hash_code]->type != + AnnotationInstance::Type::ANNOTATION_COMPLETING) { + errors->push_back(CreateRepeatedIDError( + item.ids[1].text, item, *first_ids[item.ids[1].hash_code])); + } + } + } + + // If two second ids are equal, they should be either PARTIAL or + // BRANCHED_COMPLETING. + for (AnnotationItem& item : annotations_) { + if (item.ids_count != 2) + continue; + if (!base::ContainsKey(second_ids, item.ids[1].hash_code)) { + second_ids[item.ids[1].hash_code] = &item; + } else { + AnnotationInstance::Type other_type = + second_ids[item.ids[1].hash_code]->type; + if ((item.type != AnnotationInstance::Type::ANNOTATION_PARTIAL && + item.type != + AnnotationInstance::Type::ANNOTATION_BRANCHED_COMPLETING) || + (other_type != AnnotationInstance::Type::ANNOTATION_PARTIAL && + other_type != + AnnotationInstance::Type::ANNOTATION_BRANCHED_COMPLETING)) { + errors->push_back(CreateRepeatedIDError( + item.ids[1].text, item, *second_ids[item.ids[1].hash_code])); + } + } + } +} + +void TrafficAnnotationIDChecker::CheckIDsFormat( + std::vector<AuditorResult>* errors) { + for (AnnotationItem& item : annotations_) { + bool any_failed = false; + for (int i = 0; i < item.ids_count; i++) { + if (!base::ContainsOnlyChars(base::ToLowerASCII(item.ids[i].text), + "0123456789_abcdefghijklmnopqrstuvwxyz")) { + errors->push_back( + AuditorResult(AuditorResult::Type::ERROR_ID_INVALID_CHARACTER, + item.ids[i].text, item.file_path, item.line_number)); + any_failed = true; + } + } + // Remove this id from next tests. + if (any_failed) + item.ids_count = 0; + } +} + +AuditorResult TrafficAnnotationIDChecker::CreateRepeatedIDError( + const std::string& common_id, + const AnnotationItem& item1, + const AnnotationItem& item2) { + AuditorResult error( + AuditorResult::Type::ERROR_REPEATED_ID, + base::StringPrintf("%s in '%s:%i'", common_id.c_str(), + item1.file_path.c_str(), item1.line_number)); + error.AddDetail(base::StringPrintf("'%s:%i'", item2.file_path.c_str(), + item2.line_number)); + return error; +}
diff --git a/tools/traffic_annotation/auditor/traffic_annotation_id_checker.h b/tools/traffic_annotation/auditor/traffic_annotation_id_checker.h new file mode 100644 index 0000000..efca132 --- /dev/null +++ b/tools/traffic_annotation/auditor/traffic_annotation_id_checker.h
@@ -0,0 +1,68 @@ +// Copyright 2017 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef TRAFFIC_ANNOTATION_ID_CHECKER_H_ +#define TRAFFIC_ANNOTATION_ID_CHECKER_H_ + +#include <set> +#include <vector> + +#include "tools/traffic_annotation/auditor/instance.h" + +// Performs all tests that are required to ensure that annotations have correct +// ids. +class TrafficAnnotationIDChecker { + public: + TrafficAnnotationIDChecker(const std::set<int>& reserved_ids, + const std::set<int>& deprecated_ids); + ~TrafficAnnotationIDChecker(); + + // Loads |extracted_annotations| into |annotations_|; + void Load(const std::vector<AnnotationInstance>& extracted_annotations); + + // Checks loaded |annotations_| for all sort of ID related errors and writes + // errors to |errors|. + void CheckIDs(std::vector<AuditorResult>* errors); + + private: + struct AnnotationItem { + struct { + std::string text; + int hash_code; + } ids[2]; + int ids_count; // Number of existing ids (1 or 2). + AnnotationInstance::Type type; + std::string file_path; + int line_number; + }; + + // Checks if the ids in |invalid_set| are not used in annotations. If found, + // creates an error with |error_type| and writes it to |errors|. + void CheckForInvalidValues(const std::set<int>& invalid_set, + AuditorResult::Type error_type, + std::vector<AuditorResult>* errors); + + // Check if annotations that need two ids, have two and the second one is + // different from their unique id. + void CheckForSecondIDs(std::vector<AuditorResult>* errors); + + // Checks if there are ids with colliding hash values. + void CheckForHashCollisions(std::vector<AuditorResult>* errors); + + // Checks if there are invalid repeated ids. + void CheckForInvalidRepeatedIDs(std::vector<AuditorResult>* errors); + + // Checks if ids only include alphanumeric characters and underline. + void CheckIDsFormat(std::vector<AuditorResult>* errors); + + AuditorResult CreateRepeatedIDError(const std::string& common_id, + const AnnotationItem& item1, + const AnnotationItem& item2); + + std::vector<AnnotationItem> annotations_; + std::set<int> deprecated_ids_; + std::set<int> reserved_ids_; +}; + +#endif // TRAFFIC_ANNOTATION_ID_CHECKER_H_ \ No newline at end of file
diff --git a/tools/traffic_annotation/summary/annotations.xml b/tools/traffic_annotation/summary/annotations.xml index 128d4e2..9565b0f4 100644 --- a/tools/traffic_annotation/summary/annotations.xml +++ b/tools/traffic_annotation/summary/annotations.xml
@@ -199,6 +199,7 @@ <item id="thumbnail_source" hash_code="135251783" content_hash_code="31086298" os_list="linux,windows"/> <item id="translate_url_fetcher" hash_code="137116619" content_hash_code="1127120" os_list="linux,windows"/> <item id="undefined" hash_code="45578882" reserved="1" os_list="linux,windows"/> + <item id="undefined-656607" hash_code="28406789" reserved="1" os_list="linux,windows"/> <item id="url_fetcher_downloader" hash_code="113231892" content_hash_code="61085066" os_list="linux,windows"/> <item id="url_prevision_fetcher" hash_code="118389509" content_hash_code="66145513" os_list="linux,windows"/> <item id="user_info_fetcher" hash_code="22265491" content_hash_code="72016232" os_list="linux,windows"/>