示例#1
0
    def test_parent_application__streams_instead_of_files(
            self, generated_rows):
        yaml_file = StringIO("""- object: Foo""")
        generate_cci_mapping_file = StringIO()
        output_file = StringIO()
        output_files = [StringIO(), StringIO()]
        continuation_file = StringIO("""
        id_manager:
           last_used_ids:
             Foo: 6
        intertable_dependencies: []
        nicknames_and_tables:
           Foo: Foo
        persistent_nicknames: {}
        persistent_objects_by_table: {}
        today: 2021-04-07""")
        generate_continuation_file = StringIO()
        decls = """[{"sf_object": Opportunity, "api": bulk}]"""
        load_declarations = [StringIO(decls), StringIO(decls)]

        generate_data(
            yaml_file=yaml_file,
            generate_cci_mapping_file=generate_cci_mapping_file,
            output_file=output_file,
            output_files=output_files,
            output_format="txt",
            continuation_file=continuation_file,
            generate_continuation_file=generate_continuation_file,
            load_declarations=load_declarations,
        )
        assert generated_rows.table_values("Foo", 0)["id"] == 7
    def test_plugin_context_vars(self, write_row):
        yaml = """
        - plugin: tests.test_custom_plugins_and_providers.PluginThatNeedsState
        - object: OBJ
          fields:
            name: OBJ1
            path: ${{PluginThatNeedsState.object_path()}}
            child:
                - object: OBJ
                  fields:
                    name: OBJ2
                    path: ${{PluginThatNeedsState.object_path()}}
        - object: OBJ
          fields:
            name: OBJ3
            path: ${{PluginThatNeedsState.object_path()}}
            child:
                - object: OBJ
                  fields:
                    name: OBJ4
                    path: ${{PluginThatNeedsState.object_path()}}
        """
        generate_data(StringIO(yaml))

        assert row_values(write_row, 0, "path") == "ROOT.OBJ1.OBJ2"
        assert row_values(write_row, 1, "path") == "ROOT.OBJ1"
        assert row_values(write_row, 2, "path") == "ROOT.OBJ3.OBJ4"
        assert row_values(write_row, 3, "path") == "ROOT.OBJ3"
示例#3
0
def snowfakery_output_for(name, primary_example, secondary_example):
    """Generate the Snowfakery output for some YAML

    Attempt to generate a two-part example, but fall back to single
    or nothing if worse comes to worst."""
    output = None
    exception = None

    for yaml_data in [primary_example, secondary_example]:
        with StringIO() as s:
            try:
                generate_data(StringIO(yaml_data),
                              output_file=s,
                              output_format="txt")
                output = s.getvalue()
                exception = None
            except Exception as e:
                exception = e

    if exception and name.lower() not in IGNORE_ERRORS:
        print(f"Cannot generate sample for {name}: {str(exception)[0:80]}")
        IGNORE_ERRORS.add(name.lower())

    if output:
        return yaml_data, output
示例#4
0
    def test_soql_dataset_in_order(self, sf, org_config, generated_rows):
        filename = Path(
            __file__).parent.parent / "examples/soql_dataset.recipe.yml"

        generate_data(filename, plugin_options={"org_name": org_config.name})
        assert len(generated_rows.mock_calls) == 10

        for mock_call in generated_rows.mock_calls:
            row_type, row_data = mock_call[1]
            assert row_type == "Contact"
            assert row_data["OwnerId"].startswith("005")
            assert row_data["LastName"]

        first_user_lastname = sf.query(
            "select LastName from User")["records"][0]["LastName"]
        assert generated_rows.mock_calls[0][1][1][
            "LastName"] == first_user_lastname

        # TODO: anon apex is better, so IDs don't end up in the VCR logs.
        sf.restful(
            "tooling/executeAnonymous",
            {
                "anonymousBody":
                "delete [SELECT Id FROM Contact WHERE Name LIKE 'TestUser%'];"
            },
        )
示例#5
0
 def test_content_version(self, generated_rows):
     content_version = "examples/salesforce/ContentVersion.recipe.yml"
     generate_data(content_version)
     b64data = generated_rows.table_values("ContentVersion",
                                           0)["VersionData"]
     rawdata = b64decode(b64data)
     assert rawdata.startswith(b"%PDF-1.3")
     assert b"Helvetica" in rawdata
示例#6
0
def snowfakery(recipe, num_records, tablename, outputfile):
    assert Path(recipe).exists(), recipe
    output = f"sqlite:///{outputfile}"
    print(output)
    generate_data(
        recipe,
        target_number=(num_records, tablename),
        dburl=output,
    )
 def test_constants(self, write_row_mock):
     yaml = """
     - plugin: snowfakery.standard_plugins.Math
     - object: OBJ
       fields:
         pi: ${{Math.pi}}
     """
     generate_data(StringIO(yaml))
     assert row_values(write_row_mock, 0, "pi") == math.pi
 def test_plugin_does_not_close(self):
     yaml = """
     - plugin: tests.test_custom_plugins_and_providers.DoesNotClosePlugin
     - object: B
       fields:
         foo:
             DoesNotClosePlugin.foo:
     """
     with pytest.warns(UserWarning, match="close"):
         generate_data(StringIO(yaml))
 def test_math_deconstructed(self, write_row_mock):
     yaml = """
     - plugin: snowfakery.standard_plugins.Math
     - object: OBJ
       fields:
         twelve:
             Math.sqrt: ${{Math.min(144, 169)}}
     """
     generate_data(StringIO(yaml))
     assert row_values(write_row_mock, 0, "twelve") == 12
 def test_missing_plugin(self):
     yaml = """
     - plugin: xyzzy.test_custom_plugins_and_providers.TestCustomPlugin
     - object: OBJ
       fields:
         service_name: saascrmlightning
     """
     with pytest.raises(DataGenImportError) as e:
         generate_data(StringIO(yaml))
     assert "xyzzy" in str(e.value)
 def test_null_attributes(self):
     yaml = """
     - plugin: tests.test_custom_plugins_and_providers.WrongTypePlugin  # 2
     - object: B                             #3
       fields:                               #4
         foo:                                #5
             WrongTypePlugin.junk: 5  #6
     """
     with pytest.raises(DataGenError) as e:
         generate_data(StringIO(yaml))
     assert 6 > e.value.line_num >= 3
示例#12
0
 def test_pretend_cci_not_available(self):
     filename = (Path(__file__).parent.parent /
                 "examples/salesforce_soql_example.recipe.yml")
     with unittest.mock.patch(
             "snowfakery.standard_plugins.Salesforce.SalesforceConnectionMixin._get_CliRuntime"
     ) as conn:
         conn.side_effect = ImportError(
             "CumulusCI Runtime cannot be loaded")
         with pytest.raises(Exception,
                            match="CumulusCI Runtime cannot be loaded"):
             generate_data(filename, plugin_options={"org_name": "None"})
 def test_bogus_plugin(self):
     yaml = """
     - plugin: tests.test_custom_plugins_and_providers.TestCustomPlugin
     - object: OBJ
       fields:
         service_name: saascrmlightning
     """
     with pytest.raises(DataGenTypeError) as e:
         generate_data(StringIO(yaml))
     assert "TestCustomPlugin" in str(e.value)
     assert ":2" in str(e.value)
 def test_custom_faker_provider(self, write_row_mock):
     yaml = """
     - plugin: faker_microservice.Provider
     - object: OBJ
       fields:
         service_name:
             fake:
                 microservice
     """
     generate_data(StringIO(yaml))
     assert row_values(write_row_mock, 0, "service_name")
 def test_simple_plugin(self, write_row_mock):
     yaml = """
     - plugin: tests.test_custom_plugins_and_providers.SimpleTestPlugin
     - object: OBJ
       fields:
         four:
             SimpleTestPlugin.double: 2
         six: ${{SimpleTestPlugin.double(3)}}
     """
     generate_data(StringIO(yaml))
     assert row_values(write_row_mock, 0, "four") == 4
     assert row_values(write_row_mock, 0, "six") == 6
 def test_profile_id(self, generated_rows, org_config):
     yaml = """
     - plugin: snowfakery.standard_plugins.Salesforce
     - object: foo
       fields:
         ProfileId:
           Salesforce.ProfileId: Identity User
     """
     generate_data(StringIO(yaml),
                   plugin_options={"org_name": org_config.name})
     assert generated_rows.table_values("foo", 0,
                                        "ProfileId").startswith("00e")
示例#17
0
 def test_find_records_returns_nothing(self, org_config):
     yaml = """
         - plugin: snowfakery.standard_plugins.Salesforce.SalesforceQuery
         - object: Contact
           fields:
             FirstName: Suzy
             LastName: Salesforce
             AccountId:
                 SalesforceQuery.find_record: Contract
     """
     with pytest.raises(DataGenError, match="No records returned"):
         generate_data(StringIO(yaml),
                       plugin_options={"org_name": org_config.name})
示例#18
0
    def test_dataset_no_from(self, org_config, sf, generated_rows):
        yaml = """
- plugin: snowfakery.standard_plugins.Salesforce.SOQLDataset
- object: Contact
  count: 10
  fields:
    __users_from_salesforce:
      SOQLDataset.shuffle:
        fields: Junk3
        """
        with pytest.raises(DataGenError, match="SOQLDataset needs a 'from'"):
            generate_data(StringIO(yaml),
                          plugin_options={"org_name": org_config.name})
示例#19
0
    def test_parent_application__echo(self):
        called = False

        class MyEmbedder(SnowfakeryApplication):
            def echo(self, *args, **kwargs):
                nonlocal called
                called = True

        meth = "snowfakery.output_streams.DebugOutputStream.close"
        with mock.patch(meth) as close:
            close.side_effect = AssertionError
            generate_data(yaml_file="examples/company.yml",
                          parent_application=MyEmbedder())
            assert called
 def test_math(self, write_row_mock):
     yaml = """
     - plugin: snowfakery.standard_plugins.Math
     - object: OBJ
       fields:
         sqrt: ${{Math.sqrt(144)}}
         max: ${{Math.max(144, 200, 100)}}
         eleven: ${{Math.round(10.7)}}
         min: ${{Math.min(144, 200, 100)}}
     """
     generate_data(StringIO(yaml))
     assert row_values(write_row_mock, 0, "sqrt") == 12
     assert row_values(write_row_mock, 0, "max") == 200
     assert row_values(write_row_mock, 0, "eleven") == 11
     assert row_values(write_row_mock, 0, "min") == 100
 def test_stringification(self, write_row):
     yaml = """
     - plugin: tests.test_custom_plugins_and_providers.EvalPlugin
     - object: OBJ
       fields:
         some_value:
             - EvalPlugin.add:
                 - 1
                 - EvalPlugin.sub:
                     - 5
                     - 3
     """
     with StringIO() as s:
         generate_data(StringIO(yaml), output_file=s, output_format="json")
         assert eval(s.getvalue())[0]["some_value"] == 3
示例#22
0
 def test_find_records_returns_multiple(self, org_config, sf,
                                        generated_rows):
     yaml = """
         - plugin: snowfakery.standard_plugins.Salesforce.SalesforceQuery
         - object: Contact
           fields:
             FirstName: Suzy
             LastName: Salesforce
             AccountId:
                 SalesforceQuery.find_record: User
     """
     generate_data(StringIO(yaml),
                   plugin_options={"org_name": org_config.name})
     first_user_id = sf.query("select Id from User")["records"][0]["Id"]
     assert generated_rows.mock_calls[0][1][1]["AccountId"] == first_user_id
示例#23
0
 def test_arguments(self):
     with TemporaryDirectory() as t:
         outfile = Path(t) / "foo.txt"
         continuation = Path(t) / "out.yml"
         generate_data(
             yaml_file="examples/company.yml",
             user_options={"A": "B"},
             target_number=(20, "Employee"),
             debug_internals=True,
             output_format="json",
             output_file=outfile,
             generate_continuation_file=continuation,
         )
         assert outfile.exists()
         assert continuation.exists()
         with continuation.open() as f:
             assert yaml.safe_load(f)
    def test_lazy_with_context(self, write_row):
        yaml = """
        - plugin: tests.test_custom_plugins_and_providers.DoubleVisionPlugin
        - plugin: tests.test_custom_plugins_and_providers.PluginThatNeedsState
        - object: OBJ
          fields:
            some_value:
                - DoubleVisionPlugin.do_it_twice:
                    - abc
            some_value_2:
                - DoubleVisionPlugin.do_it_twice:
                    - ${{PluginThatNeedsState.count()}}
        """
        generate_data(StringIO(yaml))

        assert row_values(write_row, 0, "some_value") == "abc : abc"
        assert row_values(write_row, 0, "some_value_2") == "1 : 2"
示例#25
0
 def test_arguments(self):
     with TemporaryDirectory() as t:
         outfile = Path(t) / "foo.txt"
         continuation = Path(t) / "out.yml"
         generate_data(
             yaml_file="tests/BDI_generator.yml",
             user_options={"num_accounts": "15"},
             target_number=(20, "Account"),
             debug_internals=True,
             output_format="json",
             output_file=outfile,
             generate_continuation_file=continuation,
         )
         assert outfile.exists()
         assert continuation.exists()
         with continuation.open() as f:
             assert yaml.safe_load(f)
示例#26
0
    def test_parent_application__early_finish(self, generated_rows):
        class MyEmbedder(SnowfakeryApplication):
            count = 0

            def check_if_finished(self, idmanager):
                assert isinstance(idmanager, IdManager)
                self.__class__.count += 1
                assert self.__class__.count < 100, "Runaway recipe!"
                return idmanager["Employee"] >= 10

        meth = "snowfakery.output_streams.DebugOutputStream.close"
        with mock.patch(meth) as close:
            close.side_effect = AssertionError
            generate_data(yaml_file="examples/company.yml",
                          parent_application=MyEmbedder())
            # called 5 times, after generating 2 employees each
            assert MyEmbedder.count == 5
示例#27
0
 def doit(recipe_data, *args, **kwargs):
     db = tmpdir / "testdb.db"
     dburl = f"sqlite:///{db}"
     recipe = tmpdir / "recipe.yml"
     mapping_file = tmpdir / "mapping.yml"
     recipe.write_text(recipe_data)
     generate_data(
         recipe,
         *args,
         generate_cci_mapping_file=mapping_file,
         dburl=dburl,
         should_create_cci_record_type_tables=True,
         **kwargs,
     )
     mapping = yaml.safe_load(mapping_file.read_text())
     e = create_engine(dburl)
     with e.connect() as connection:
         yield mapping, connection
示例#28
0
    def test_soql_dataset_bulk(self, sf, org_config, generated_rows):
        filename = (Path(__file__).parent.parent /
                    "examples/soql_dataset_where.recipe.yml")

        # pretend there are 5000 records in org
        pretend_5000 = patch(
            "simple_salesforce.api.Salesforce.restful",
            lambda *args, **kwargs:
            {"sObjects": [{
                "name": "User",
                "count": 5000
            }]},
        )
        csv_data = """"Id","FirstName","LastName"
"0051F00000nc59NQAQ","Automated","Process" """

        @contextmanager
        def download_file(*args, **kwargs):
            yield StringIO(csv_data)

        do_not_really_download = patch(
            "cumulusci.tasks.bulkdata.step.download_file",
            download_file,
        )
        with pretend_5000, do_not_really_download:
            generate_data(filename,
                          plugin_options={"org_name": org_config.name})

        assert len(generated_rows.mock_calls) == 10

        for mock_call in generated_rows.mock_calls:
            row_type, row_data = mock_call[1]
            assert row_type == "Contact"
            assert row_data["OwnerId"].startswith("005")
            assert row_data["FirstName"].startswith("A")

        # anon apex is better, so IDs don't end up in the VCR logs.
        sf.restful(
            "tooling/executeAnonymous",
            {
                "anonymousBody":
                "delete [SELECT Id FROM Contact WHERE Name LIKE 'TestUser%'];"
            },
        )
示例#29
0
 def test_continuation_as_open_file(self):
     with TemporaryDirectory() as t:
         outfile = Path(t) / "foo.json"
         continuation = Path(t) / "cont.yml"
         mapping_file = Path(t) / "mapping.yml"
         with open(continuation, "w") as cont, open(mapping_file, "w") as mapf:
             generate_data(
                 yaml_file="examples/company.yml",
                 target_number=(20, "Employee"),
                 debug_internals=False,
                 output_file=outfile,
                 generate_continuation_file=cont,
                 generate_cci_mapping_file=mapf,
             )
         assert outfile.exists()
         assert continuation.exists()
         with continuation.open() as f:
             assert yaml.safe_load(f)
         assert mapping_file.exists()
         with mapping_file.open() as f:
             assert yaml.safe_load(f)
示例#30
0
    def test_soql_dataset_where(self, sf, org_config, generated_rows):
        filename = (Path(__file__).parent.parent /
                    "examples/soql_dataset_where.recipe.yml")

        generate_data(filename, plugin_options={"org_name": org_config.name})
        assert len(generated_rows.mock_calls) == 10

        for mock_call in generated_rows.mock_calls:
            row_type, row_data = mock_call[1]
            assert row_type == "Contact"
            assert row_data["OwnerId"].startswith("005")
            assert row_data["FirstName"].startswith("A")

        # TODO: anon apex is better, so IDs don't end up in the VCR logs.
        sf.restful(
            "tooling/executeAnonymous",
            {
                "anonymousBody":
                "delete [SELECT Id FROM Contact WHERE Name LIKE 'TestUser%'];"
            },
        )