Repository: great-expectations/great_expectations

Issue:
Use cleaner solution for non-truncating division in python 2
Prefer `from __future__ import division` to `1.*x/y`


Discussion:
Done inline during improve_partitions push.

Resolving patch:
diff --git a/great_expectations/core/usage_statistics/schemas.py b/great_expectations/core/usage_statistics/schemas.py
--- a/great_expectations/core/usage_statistics/schemas.py
+++ b/great_expectations/core/usage_statistics/schemas.py
@@ -707,6 +707,49 @@
     ],
 }
 
+anonymized_legacy_profiler_build_suite_payload_schema = {
+    "$schema": "http://json-schema.org/draft-04/schema#",
+    "title": "anonymized-legacy-profiler-build-suite-payload",
+    "type": "object",
+    "properties": {
+        "profile_dataset_type": {"type": "string", "maxLength": 256},
+        "excluded_expectations_specified": {
+            "type": ["boolean"],
+        },
+        "ignored_columns_specified": {
+            "type": ["boolean"],
+        },
+        "not_null_only": {
+            "type": ["boolean"],
+        },
+        "primary_or_compound_key_specified": {
+            "type": ["boolean"],
+        },
+        "semantic_types_dict_specified": {
+            "type": ["boolean"],
+        },
+        "table_expectations_only": {
+            "type": ["boolean"],
+        },
+        "value_set_threshold_specified": {
+            "type": ["boolean"],
+        },
+        "api_version": {"type": "string", "maxLength": 256},
+    },
+    "required": [
+        "profile_dataset_type",
+        "excluded_expectations_specified",
+        "ignored_columns_specified",
+        "not_null_only",
+        "primary_or_compound_key_specified",
+        "semantic_types_dict_specified",
+        "table_expectations_only",
+        "value_set_threshold_specified",
+        "api_version",
+    ],
+    "additionalProperties": False,
+}
+
 anonymized_usage_statistics_record_schema = {
     "$schema": "http://json-schema.org/draft-04/schema#",
     "title": "anonymized-usage-statistics-record",
@@ -737,6 +780,7 @@
         "anonymized_validation": anonymized_validation_schema,
         "anonymized_validations": anonymized_validations_list_schema,
         "anonymized_checkpoint_run": anonymized_checkpoint_run_schema,
+        "anonymized_legacy_profiler_build_suite_payload": anonymized_legacy_profiler_build_suite_payload_schema,
     },
     "type": "object",
     "properties": {
@@ -877,6 +921,17 @@
                 "event_payload": {"$ref": "#/definitions/anonymized_checkpoint_run"},
             },
         },
+        {
+            "type": "object",
+            "properties": {
+                "event": {
+                    "enum": ["legacy_profiler.build_suite"],
+                },
+                "event_payload": {
+                    "$ref": "#/definitions/anonymized_legacy_profiler_build_suite_payload"
+                },
+            },
+        },
         {
             "type": "object",
             "properties": {
diff --git a/great_expectations/core/usage_statistics/usage_statistics.py b/great_expectations/core/usage_statistics/usage_statistics.py
--- a/great_expectations/core/usage_statistics/usage_statistics.py
+++ b/great_expectations/core/usage_statistics/usage_statistics.py
@@ -536,7 +536,7 @@ def get_checkpoint_run_usage_statistics(checkpoint, *args, **kwargs):
 
 
 def send_usage_message(
-    data_context,
+    data_context: "DataContext",  # noqa: F821
     event: str,
     event_payload: Optional[dict] = None,
     success: Optional[bool] = None,
diff --git a/great_expectations/profile/user_configurable_profiler.py b/great_expectations/profile/user_configurable_profiler.py
--- a/great_expectations/profile/user_configurable_profiler.py
+++ b/great_expectations/profile/user_configurable_profiler.py
@@ -8,6 +8,7 @@
 from great_expectations.core import ExpectationSuite
 from great_expectations.core.batch import Batch
 from great_expectations.core.expectation_configuration import ExpectationConfiguration
+from great_expectations.core.usage_statistics.util import send_usage_message
 from great_expectations.dataset import Dataset, PandasDataset
 from great_expectations.exceptions import ProfilerError
 from great_expectations.execution_engine import (
@@ -106,7 +107,7 @@ def __init__(
         """
         self.column_info = {}
         self.profile_dataset = profile_dataset
-        assert isinstance(self.profile_dataset, (Dataset, Validator, Batch))
+        assert isinstance(self.profile_dataset, (Batch, Dataset, Validator))
 
         if isinstance(self.profile_dataset, Batch):
             self.profile_dataset = Validator(
@@ -203,6 +204,7 @@ def build_suite(self) -> ExpectationSuite:
             An expectation suite built either with or without a semantic_types dict
 
         """
+        expectation_suite: ExpectationSuite
         if len(self.profile_dataset.get_expectation_suite().expectations) > 0:
             # noinspection PyProtectedMember
             suite_name: str = (
@@ -211,9 +213,56 @@ def build_suite(self) -> ExpectationSuite:
             self.profile_dataset._expectation_suite = ExpectationSuite(suite_name)
 
         if self.semantic_types_dict:
-            return self._build_expectation_suite_from_semantic_types_dict()
+            expectation_suite = self._build_expectation_suite_from_semantic_types_dict()
+        else:
+            expectation_suite = self._profile_and_build_expectation_suite()
+
+        self._send_usage_stats_message()
+
+        return expectation_suite
 
-        return self._profile_and_build_expectation_suite()
+    def _send_usage_stats_message(self):
+        profile_dataset_type: str = str(type(self.profile_dataset))
+        if "Dataset" in profile_dataset_type:
+            profile_dataset_type = "Dataset"
+        elif "Batch" in profile_dataset_type:
+            profile_dataset_type = "Batch"
+        elif "Validator" in profile_dataset_type:
+            profile_dataset_type = "Validator"
+        else:
+            raise ValueError(
+                f"""The "profile_dataset_type" property must be one of "Dataset", "Batch", or "Validator" objects. The \
+type detected is "{str(type(self.profile_dataset))}", which is illegal.
+"""
+            )
+
+        event_payload: dict = {
+            "profile_dataset_type": profile_dataset_type,
+            "excluded_expectations_specified": self.excluded_expectations is not None
+            and isinstance(self.excluded_expectations, list)
+            and len(self.excluded_expectations) > 0,
+            "ignored_columns_specified": self.ignored_columns is not None
+            and isinstance(self.ignored_columns, list)
+            and len(self.ignored_columns) > 0,
+            "not_null_only": self.not_null_only,
+            "primary_or_compound_key_specified": self.primary_or_compound_key
+            is not None
+            and isinstance(self.primary_or_compound_key, list)
+            and len(self.primary_or_compound_key) > 0,
+            "semantic_types_dict_specified": self.semantic_types_dict is not None
+            and isinstance(self.semantic_types_dict, dict)
+            and len(self.semantic_types_dict.keys()) > 0,
+            "table_expectations_only": self.table_expectations_only,
+            "value_set_threshold_specified": self.value_set_threshold is not None
+            and isinstance(self.value_set_threshold, str)
+            and len(self.value_set_threshold) > 0,
+        }
+        send_usage_message(
+            event="legacy_profiler.build_suite",
+            event_payload=event_payload,
+            api_version="v2",
+            success=True,
+        )
 
     def _build_expectation_suite_from_semantic_types_dict(self):
         """


Test patch:
diff --git a/tests/core/usage_statistics/test_usage_stats_schema.py b/tests/core/usage_statistics/test_usage_stats_schema.py
--- a/tests/core/usage_statistics/test_usage_stats_schema.py
+++ b/tests/core/usage_statistics/test_usage_stats_schema.py
@@ -9,6 +9,7 @@
     anonymized_datasource_schema,
     anonymized_datasource_sqlalchemy_connect_payload_schema,
     anonymized_init_payload_schema,
+    anonymized_legacy_profiler_build_suite_payload_schema,
     anonymized_save_or_edit_expectation_suite_payload_schema,
     anonymized_test_yaml_config_payload_schema,
     anonymized_usage_statistics_record_schema,
@@ -64,6 +65,7 @@ def test_comprehensive_list_of_messages():
         "data_context.test_yaml_config",
         "datasource.sqlalchemy.connect",
         "checkpoint.run",
+        "legacy_profiler.build_suite",
     }
 
 
@@ -155,6 +157,23 @@ def test_checkpoint_run_message():
             )
 
 
+def test_legacy_profiler_build_suite_message():
+    usage_stats_records_messages = [
+        "legacy_profiler.build_suite",
+    ]
+    for message_type in usage_stats_records_messages:
+        for message in valid_usage_statistics_messages[message_type]:
+            # record itself
+            jsonschema.validate(
+                message,
+                anonymized_usage_statistics_record_schema,
+            )
+            jsonschema.validate(
+                message["event_payload"],
+                anonymized_legacy_profiler_build_suite_payload_schema,
+            )
+
+
 def test_data_context_save_expectation_suite_message():
     usage_stats_records_messages = [
         "data_context.save_expectation_suite",
@@ -190,7 +209,6 @@ def test_datasource_sqlalchemy_connect_message():
 
 
 def test_cli_data_asset_validate():
-
     usage_stats_records_messages = [
         "data_asset.validate",
     ]
diff --git a/tests/integration/usage_statistics/test_usage_statistics_messages.py b/tests/integration/usage_statistics/test_usage_statistics_messages.py
--- a/tests/integration/usage_statistics/test_usage_statistics_messages.py
+++ b/tests/integration/usage_statistics/test_usage_statistics_messages.py
@@ -1100,12 +1100,190 @@ def test_generate_messages_with_defaults():
             "x-forwarded-for": "00.000.00.000, 00.000.000.000",
         },
     ],
+    "legacy_profiler.build_suite": [
+        {
+            "event": "legacy_profiler.build_suite",
+            "event_payload": {
+                "profile_dataset_type": "Dataset",
+                "excluded_expectations_specified": False,
+                "ignored_columns_specified": True,
+                "not_null_only": False,
+                "primary_or_compound_key_specified": True,
+                "semantic_types_dict_specified": False,
+                "table_expectations_only": False,
+                "value_set_threshold_specified": True,
+                "api_version": "v2",
+            },
+            "success": True,
+            "version": "1.0.0",
+            "event_time": "2020-06-25T16:08:28.070Z",
+            "event_duration": 123,
+            "data_context_id": "00000000-0000-0000-0000-000000000002",
+            "data_context_instance_id": "10000000-0000-0000-0000-000000000002",
+            "ge_version": "0.13.45.manual_testing",
+            "x-forwarded-for": "00.000.00.000, 00.000.000.000",
+        },
+        {
+            "event": "legacy_profiler.build_suite",
+            "event_payload": {
+                "profile_dataset_type": "Batch",
+                "excluded_expectations_specified": True,
+                "ignored_columns_specified": False,
+                "not_null_only": False,
+                "primary_or_compound_key_specified": False,
+                "semantic_types_dict_specified": False,
+                "table_expectations_only": True,
+                "value_set_threshold_specified": True,
+                "api_version": "v2",
+            },
+            "success": True,
+            "version": "1.0.0",
+            "event_time": "2020-06-25T16:08:23.570Z",
+            "event_duration": 123,
+            "data_context_id": "00000000-0000-0000-0000-000000000002",
+            "data_context_instance_id": "10000000-0000-0000-0000-000000000002",
+            "ge_version": "0.13.45.manual_testing",
+            "x-forwarded-for": "00.000.00.000, 00.000.000.000",
+        },
+        {
+            "event": "legacy_profiler.build_suite",
+            "event_payload": {
+                "profile_dataset_type": "Validator",
+                "excluded_expectations_specified": False,
+                "ignored_columns_specified": True,
+                "not_null_only": True,
+                "primary_or_compound_key_specified": False,
+                "semantic_types_dict_specified": True,
+                "table_expectations_only": False,
+                "value_set_threshold_specified": False,
+                "api_version": "v2",
+            },
+            "success": True,
+            "version": "1.0.0",
+            "event_time": "2020-06-25T16:08:23.570Z",
+            "event_duration": 123,
+            "data_context_id": "00000000-0000-0000-0000-000000000002",
+            "data_context_instance_id": "10000000-0000-0000-0000-000000000002",
+            "ge_version": "0.13.45.manual_testing",
+            "x-forwarded-for": "00.000.00.000, 00.000.000.000",
+        },
+        {
+            "event": "legacy_profiler.build_suite",
+            "event_payload": {
+                "profile_dataset_type": "Validator",
+                "excluded_expectations_specified": False,
+                "ignored_columns_specified": False,
+                "not_null_only": False,
+                "primary_or_compound_key_specified": False,
+                "semantic_types_dict_specified": False,
+                "table_expectations_only": False,
+                "value_set_threshold_specified": True,
+                "api_version": "v2",
+            },
+            "success": True,
+            "version": "1.0.0",
+            "event_time": "2020-06-25T16:08:23.570Z",
+            "event_duration": 123,
+            "data_context_id": "00000000-0000-0000-0000-000000000002",
+            "data_context_instance_id": "10000000-0000-0000-0000-000000000002",
+            "ge_version": "0.13.45.manual_testing",
+            "x-forwarded-for": "00.000.00.000, 00.000.000.000",
+        },
+        {
+            "event": "legacy_profiler.build_suite",
+            "event_payload": {
+                "profile_dataset_type": "Validator",
+                "excluded_expectations_specified": True,
+                "ignored_columns_specified": True,
+                "not_null_only": False,
+                "primary_or_compound_key_specified": True,
+                "semantic_types_dict_specified": False,
+                "table_expectations_only": False,
+                "value_set_threshold_specified": True,
+                "api_version": "v2",
+            },
+            "success": True,
+            "version": "1.0.0",
+            "event_time": "2020-06-25T16:08:23.570Z",
+            "event_duration": 123,
+            "data_context_id": "00000000-0000-0000-0000-000000000002",
+            "data_context_instance_id": "10000000-0000-0000-0000-000000000002",
+            "ge_version": "0.13.45.manual_testing",
+            "x-forwarded-for": "00.000.00.000, 00.000.000.000",
+        },
+        {
+            "event": "legacy_profiler.build_suite",
+            "event_payload": {
+                "profile_dataset_type": "Validator",
+                "excluded_expectations_specified": True,
+                "ignored_columns_specified": True,
+                "not_null_only": False,
+                "primary_or_compound_key_specified": True,
+                "semantic_types_dict_specified": True,
+                "table_expectations_only": False,
+                "value_set_threshold_specified": True,
+                "api_version": "v2",
+            },
+            "success": True,
+            "version": "1.0.0",
+            "event_time": "2020-06-25T16:08:23.570Z",
+            "event_duration": 123,
+            "data_context_id": "00000000-0000-0000-0000-000000000002",
+            "data_context_instance_id": "10000000-0000-0000-0000-000000000002",
+            "ge_version": "0.13.45.manual_testing",
+            "x-forwarded-for": "00.000.00.000, 00.000.000.000",
+        },
+        {
+            "event": "legacy_profiler.build_suite",
+            "event_payload": {
+                "profile_dataset_type": "Validator",
+                "excluded_expectations_specified": True,
+                "ignored_columns_specified": True,
+                "not_null_only": False,
+                "primary_or_compound_key_specified": False,
+                "semantic_types_dict_specified": False,
+                "table_expectations_only": True,
+                "value_set_threshold_specified": True,
+                "api_version": "v2",
+            },
+            "success": True,
+            "version": "1.0.0",
+            "event_time": "2020-06-25T16:08:23.570Z",
+            "event_duration": 123,
+            "data_context_id": "00000000-0000-0000-0000-000000000002",
+            "data_context_instance_id": "10000000-0000-0000-0000-000000000002",
+            "ge_version": "0.13.45.manual_testing",
+            "x-forwarded-for": "00.000.00.000, 00.000.000.000",
+        },
+        {
+            "event": "legacy_profiler.build_suite",
+            "event_payload": {
+                "profile_dataset_type": "Validator",
+                "excluded_expectations_specified": True,
+                "ignored_columns_specified": True,
+                "not_null_only": False,
+                "primary_or_compound_key_specified": False,
+                "semantic_types_dict_specified": False,
+                "table_expectations_only": True,
+                "value_set_threshold_specified": True,
+                "api_version": "v2",
+            },
+            "success": True,
+            "version": "1.0.0",
+            "event_time": "2020-06-25T16:08:23.570Z",
+            "event_duration": 123,
+            "data_context_id": "00000000-0000-0000-0000-000000000002",
+            "data_context_instance_id": "10000000-0000-0000-0000-000000000002",
+            "ge_version": "0.13.45.manual_testing",
+            "x-forwarded-for": "00.000.00.000, 00.000.000.000",
+        },
+    ],
     "data_context.save_expectation_suite": [
         {
+            "event": "data_context.save_expectation_suite",
             "event_payload": {
                 "anonymized_expectation_suite_name": "4b6bf73298fcc2db6da929a8f18173f7"
             },
-            "event": "data_context.save_expectation_suite",
             "success": True,
             "version": "1.0.0",
             "event_time": "2020-06-25T16:08:23.570Z",
@@ -2005,17 +2183,17 @@ def test_generate_messages_with_defaults():
             {
                 "event": "cli.checkpoint.run",
                 "event_payload": {},
-                "ge_version": "0.11.9.manual_testing",
+                "ge_version": "0.13.18.manual_testing",
             },
             {
                 "event": "cli.checkpoint.run",
                 "event_payload": {"api_version": "v2"},
-                "ge_version": "0.13.0.manual_testing",
+                "ge_version": "0.13.18.manual_testing",
             },
             {
                 "event": "cli.checkpoint.run",
                 "event_payload": {"api_version": "v3"},
-                "ge_version": "0.13.0.manual_testing",
+                "ge_version": "0.13.18.manual_testing",
             },
             {
                 "event": "cli.checkpoint.run.begin",
diff --git a/tests/profile/fixtures/great_expectations_titanic_0.13.yml b/tests/profile/fixtures/great_expectations_titanic_0.13.yml
--- a/tests/profile/fixtures/great_expectations_titanic_0.13.yml
+++ b/tests/profile/fixtures/great_expectations_titanic_0.13.yml
@@ -117,5 +117,5 @@ data_docs_sites:
       class_name: DefaultSiteIndexBuilder
 
 anonymous_usage_statistics:
-  enabled: false
+  enabled: true
 notebooks:
diff --git a/tests/profile/test_user_configurable_profiler_v3_batch_request.py b/tests/profile/test_user_configurable_profiler_v3_batch_request.py
--- a/tests/profile/test_user_configurable_profiler_v3_batch_request.py
+++ b/tests/profile/test_user_configurable_profiler_v3_batch_request.py
@@ -2,6 +2,8 @@
 import os
 import random
 import string
+import unittest
+from unittest import mock
 
 import pandas as pd
 import pytest
@@ -365,11 +367,6 @@ def test_init_with_semantic_types(cardinality_validator):
 
     assert "col_one" not in profiler.column_info
 
-    # assert profiler.column_info.get("col_none") == {
-    #     "cardinality": "NONE",
-    #     "type": "NUMERIC",
-    #     "semantic_types": [],
-    # }
     assert profiler.column_info.get("col_two") == {
         "cardinality": "TWO",
         "type": "INT",
@@ -460,7 +457,14 @@ def test__validate_semantic_types_dict(cardinality_validator):
     )
 
 
-def test_build_suite_no_config(titanic_validator, possible_expectations_set):
+@mock.patch(
+    "great_expectations.core.usage_statistics.usage_statistics.UsageStatisticsHandler.emit"
+)
+def test_build_suite_no_config(
+    mock_emit,
+    titanic_validator,
+    possible_expectations_set,
+):
     """
     What does this test do and why?
     Tests that the build_suite function works as expected with no config
@@ -472,6 +476,35 @@ def test_build_suite_no_config(titanic_validator, possible_expectations_set):
     assert expectations_from_suite.issubset(possible_expectations_set)
     assert len(suite.expectations) == 48
 
+    assert mock_emit.call_count == 1
+
+    # noinspection PyUnresolvedReferences
+    expected_events: List[unittest.mock._Call]
+    # noinspection PyUnresolvedReferences
+    actual_events: List[unittest.mock._Call]
+
+    expected_events = [
+        mock.call(
+            {
+                "event": "legacy_profiler.build_suite",
+                "event_payload": {
+                    "profile_dataset_type": "Validator",
+                    "excluded_expectations_specified": False,
+                    "ignored_columns_specified": False,
+                    "not_null_only": False,
+                    "primary_or_compound_key_specified": False,
+                    "semantic_types_dict_specified": False,
+                    "table_expectations_only": False,
+                    "value_set_threshold_specified": True,
+                    "api_version": "v2",
+                },
+                "success": True,
+            }
+        ),
+    ]
+    actual_events = mock_emit.call_args_list
+    assert actual_events == expected_events
+
 
 def test_all_table_columns_populates(taxi_validator_pandas):
     taxi_profiler = UserConfigurableProfiler(taxi_validator_pandas)
@@ -517,8 +550,13 @@ def test_profiler_works_with_batch_object(cardinality_validator):
     ]
 
 
+@mock.patch(
+    "great_expectations.core.usage_statistics.usage_statistics.UsageStatisticsHandler.emit"
+)
 def test_build_suite_with_config_and_no_semantic_types_dict(
-    titanic_validator, possible_expectations_set
+    mock_emit,
+    titanic_validator,
+    possible_expectations_set,
 ):
     """
     What does this test do and why?
@@ -544,8 +582,41 @@ def test_build_suite_with_config_and_no_semantic_types_dict(
     assert "expect_column_mean_to_be_between" not in expectations_from_suite
     assert len(suite.expectations) == 29
 
+    assert mock_emit.call_count == 1
+
+    # noinspection PyUnresolvedReferences
+    expected_events: List[unittest.mock._Call]
+    # noinspection PyUnresolvedReferences
+    actual_events: List[unittest.mock._Call]
+
+    expected_events = [
+        mock.call(
+            {
+                "event": "legacy_profiler.build_suite",
+                "event_payload": {
+                    "profile_dataset_type": "Validator",
+                    "excluded_expectations_specified": True,
+                    "ignored_columns_specified": True,
+                    "not_null_only": False,
+                    "primary_or_compound_key_specified": True,
+                    "semantic_types_dict_specified": False,
+                    "table_expectations_only": False,
+                    "value_set_threshold_specified": True,
+                    "api_version": "v2",
+                },
+                "success": True,
+            }
+        ),
+    ]
+    actual_events = mock_emit.call_args_list
+    assert actual_events == expected_events
+
 
+@mock.patch(
+    "great_expectations.core.usage_statistics.usage_statistics.UsageStatisticsHandler.emit"
+)
 def test_build_suite_with_semantic_types_dict(
+    mock_emit,
     cardinality_validator,
     possible_expectations_set,
 ):
@@ -589,8 +660,43 @@ def test_build_suite_with_semantic_types_dict(
     assert len(value_set_columns) == 2
     assert value_set_columns == {"col_two", "col_very_few"}
 
+    assert mock_emit.call_count == 1
 
-def test_build_suite_when_suite_already_exists(cardinality_validator):
+    # noinspection PyUnresolvedReferences
+    expected_events: List[unittest.mock._Call]
+    # noinspection PyUnresolvedReferences
+    actual_events: List[unittest.mock._Call]
+
+    expected_events = [
+        mock.call(
+            {
+                "event": "legacy_profiler.build_suite",
+                "event_payload": {
+                    "profile_dataset_type": "Validator",
+                    "excluded_expectations_specified": True,
+                    "ignored_columns_specified": True,
+                    "not_null_only": False,
+                    "primary_or_compound_key_specified": True,
+                    "semantic_types_dict_specified": True,
+                    "table_expectations_only": False,
+                    "value_set_threshold_specified": True,
+                    "api_version": "v2",
+                },
+                "success": True,
+            }
+        ),
+    ]
+    actual_events = mock_emit.call_args_list
+    assert actual_events == expected_events
+
+
+@mock.patch(
+    "great_expectations.core.usage_statistics.usage_statistics.UsageStatisticsHandler.emit"
+)
+def test_build_suite_when_suite_already_exists(
+    mock_emit,
+    cardinality_validator,
+):
     """
     What does this test do and why?
     Confirms that creating a new suite on an existing profiler wipes the previous suite
@@ -612,6 +718,52 @@ def test_build_suite_when_suite_already_exists(cardinality_validator):
     assert len(suite.expectations) == 1
     assert "expect_table_row_count_to_be_between" in expectations
 
+    assert mock_emit.call_count == 2
+
+    # noinspection PyUnresolvedReferences
+    expected_events: List[unittest.mock._Call]
+    # noinspection PyUnresolvedReferences
+    actual_events: List[unittest.mock._Call]
+
+    expected_events = [
+        mock.call(
+            {
+                "event": "legacy_profiler.build_suite",
+                "event_payload": {
+                    "profile_dataset_type": "Validator",
+                    "excluded_expectations_specified": True,
+                    "ignored_columns_specified": True,
+                    "not_null_only": False,
+                    "primary_or_compound_key_specified": False,
+                    "semantic_types_dict_specified": False,
+                    "table_expectations_only": True,
+                    "value_set_threshold_specified": True,
+                    "api_version": "v2",
+                },
+                "success": True,
+            }
+        ),
+        mock.call(
+            {
+                "event": "legacy_profiler.build_suite",
+                "event_payload": {
+                    "profile_dataset_type": "Validator",
+                    "excluded_expectations_specified": True,
+                    "ignored_columns_specified": True,
+                    "not_null_only": False,
+                    "primary_or_compound_key_specified": False,
+                    "semantic_types_dict_specified": False,
+                    "table_expectations_only": True,
+                    "value_set_threshold_specified": True,
+                    "api_version": "v2",
+                },
+                "success": True,
+            }
+        ),
+    ]
+    actual_events = mock_emit.call_args_list
+    assert actual_events == expected_events
+
 
 def test_primary_or_compound_key_not_found_in_columns(cardinality_validator):
     """