Repository: dbt-labs/dbt-core

Issue:
[CT-580] Convert 013_context_var tests
Convert the context var tests to new framework.


Discussion:

Resolving patch:
diff --git a/core/dbt/main.py b/core/dbt/main.py
--- a/core/dbt/main.py
+++ b/core/dbt/main.py
@@ -537,7 +537,7 @@ def _build_parse_subparser(subparsers, base_subparser):
         "parse",
         parents=[base_subparser],
         help="""
-        Parsed the project and provides information on performance
+        Parses the project and provides information on performance
         """,
     )
     sub.set_defaults(cls=parse_task.ParseTask, which="parse", rpc_method="parse")


Test patch:
diff --git a/test/integration/013_context_var_tests/bad-generate-macros/generate_names.sql b/test/integration/013_context_var_tests/bad-generate-macros/generate_names.sql
deleted file mode 100644
--- a/test/integration/013_context_var_tests/bad-generate-macros/generate_names.sql
+++ /dev/null
@@ -1,4 +0,0 @@
-{% macro generate_schema_name(custom_schema_name, node) -%}
-    {% do var('somevar') %}
-    {% do return(dbt.generate_schema_name(custom_schema_name, node)) %}
-{%- endmacro %}
diff --git a/test/integration/013_context_var_tests/dependency-models/inside/model.sql b/test/integration/013_context_var_tests/dependency-models/inside/model.sql
deleted file mode 100644
--- a/test/integration/013_context_var_tests/dependency-models/inside/model.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-select
-	'{{ var("first_dep_override") }}' as first_dep_global,
-	'{{ var("from_root_to_root") }}' as from_root
diff --git a/test/integration/013_context_var_tests/dependency-seeds/root_model_expected.csv b/test/integration/013_context_var_tests/dependency-seeds/root_model_expected.csv
deleted file mode 100644
--- a/test/integration/013_context_var_tests/dependency-seeds/root_model_expected.csv
+++ /dev/null
@@ -1,2 +0,0 @@
-first_dep_global,from_root
-dep_never_overridden,root_root_value
diff --git a/test/integration/013_context_var_tests/emit-warning-models/warnings.sql b/test/integration/013_context_var_tests/emit-warning-models/warnings.sql
deleted file mode 100644
--- a/test/integration/013_context_var_tests/emit-warning-models/warnings.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-{% do exceptions.warn('warning: everything is terrible but not that terrible') %}
-{{ exceptions.warn("warning: everything is terrible but not that terrible") }}
-select 1 as id
diff --git a/test/integration/013_context_var_tests/first_dependency/dbt_project.yml b/test/integration/013_context_var_tests/first_dependency/dbt_project.yml
deleted file mode 100644
--- a/test/integration/013_context_var_tests/first_dependency/dbt_project.yml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-name: 'first_dep'
-version: '1.0'
-config-version: 2
-
-profile: 'default'
-
-model-paths: ["models"]
-analysis-paths: ["analyses"]
-test-paths: ["tests"]
-seed-paths: ["seeds"]
-macro-paths: ["macros"]
-
-require-dbt-version: '>=0.1.0'
-
-target-path: "target"  # directory which will store compiled SQL files
-clean-targets:         # directories to be removed by `dbt clean`
-    - "target"
-    - "dbt_packages"
-
-vars:
-  first_dep:
-    first_dep_global: 'first_dep_global_value_overridden'
-
-
-seeds:
-  quote_columns: True
diff --git a/test/integration/013_context_var_tests/first_dependency/models/nested/first_dep_model.sql b/test/integration/013_context_var_tests/first_dependency/models/nested/first_dep_model.sql
deleted file mode 100644
--- a/test/integration/013_context_var_tests/first_dependency/models/nested/first_dep_model.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-select
-    '{{ var("first_dep_global") }}' as first_dep_global,
-    '{{ var("from_root_to_first") }}' as from_root
diff --git a/test/integration/013_context_var_tests/first_dependency/seeds/first_dep_expected.csv b/test/integration/013_context_var_tests/first_dependency/seeds/first_dep_expected.csv
deleted file mode 100644
--- a/test/integration/013_context_var_tests/first_dependency/seeds/first_dep_expected.csv
+++ /dev/null
@@ -1,2 +0,0 @@
-first_dep_global,from_root
-first_dep_global_value_overridden,root_first_value
diff --git a/test/integration/013_context_var_tests/models-with-secret-bad/context.sql b/test/integration/013_context_var_tests/models-with-secret-bad/context.sql
deleted file mode 100644
--- a/test/integration/013_context_var_tests/models-with-secret-bad/context.sql
+++ /dev/null
@@ -1,12 +0,0 @@
-
-{{
-    config(
-        materialized='table'
-    )
-}}
-
-select
-
-    '{{ env_var("DBT_TEST_013_ENV_VAR") }}' as env_var,
-    '{{ env_var("DBT_ENV_SECRET_013_SECRET") }}' as env_var_secret, -- this should raise an error!
-    '{{ env_var("DBT_TEST_013_NOT_SECRET") }}' as env_var_not_secret
diff --git a/test/integration/013_context_var_tests/models/context.sql b/test/integration/013_context_var_tests/models/context.sql
deleted file mode 100644
--- a/test/integration/013_context_var_tests/models/context.sql
+++ /dev/null
@@ -1,32 +0,0 @@
-
-{{
-    config(
-        materialized='table'
-    )
-}}
-
-select
-
-    -- compile-time variables
-    '{{ this }}'        as "this",
-    '{{ this.name }}'   as "this.name",
-    '{{ this.schema }}' as "this.schema",
-    '{{ this.table }}'  as "this.table",
-
-    '{{ target.dbname }}'  as "target.dbname",
-    '{{ target.host }}'    as "target.host",
-    '{{ target.name }}'    as "target.name",
-    '{{ target.schema }}'  as "target.schema",
-    '{{ target.type }}'    as "target.type",
-    '{{ target.user }}'    as "target.user",
-    '{{ target.get("pass", "") }}'    as "target.pass", -- not actually included, here to test that it is _not_ present!
-    {{ target.port }}      as "target.port",
-    {{ target.threads }}   as "target.threads",
-
-    -- runtime variables
-    '{{ run_started_at }}' as run_started_at,
-    '{{ invocation_id }}'  as invocation_id,
-
-    '{{ env_var("DBT_TEST_013_ENV_VAR") }}' as env_var,
-    'secret_variable' as env_var_secret, -- make sure the value itself is scrubbed from the logs
-    '{{ env_var("DBT_TEST_013_NOT_SECRET") }}' as env_var_not_secret
diff --git a/test/integration/013_context_var_tests/test_context_members.py b/test/integration/013_context_var_tests/test_context_members.py
deleted file mode 100644
--- a/test/integration/013_context_var_tests/test_context_members.py
+++ /dev/null
@@ -1,22 +0,0 @@
-from test.integration.base import DBTIntegrationTest, use_profile
-
-
-class TestContextVars(DBTIntegrationTest):
-    @property
-    def schema(self):
-        return "context_members_013"
-
-    @property
-    def models(self):
-        return "context-member-models"
-
-    @property
-    def project_config(self):
-        return {
-            'config-version': 2,
-            'test-paths': ['tests'],
-        }
-
-    @use_profile('postgres')
-    def test_json_data_tests_postgres(self):
-        self.assertEqual(len(self.run_dbt(['test'])), 2)
diff --git a/test/integration/013_context_var_tests/test_context_vars.py b/test/integration/013_context_var_tests/test_context_vars.py
deleted file mode 100644
--- a/test/integration/013_context_var_tests/test_context_vars.py
+++ /dev/null
@@ -1,349 +0,0 @@
-from dbt.logger import SECRET_ENV_PREFIX
-from test.integration.base import DBTIntegrationTest, use_profile, get_manifest
-
-import os
-
-import pytest
-
-import dbt.exceptions
-
-
-class TestContextVars(DBTIntegrationTest):
-
-    def setUp(self):
-        DBTIntegrationTest.setUp(self)
-        os.environ["DBT_TEST_013_ENV_VAR"] = "1"
-
-        os.environ["DBT_TEST_013_USER"] = "root"
-        os.environ["DBT_TEST_013_PASS"] = "password"
-        os.environ[SECRET_ENV_PREFIX + "013_SECRET"] = "secret_variable"
-        os.environ["DBT_TEST_013_NOT_SECRET"] = "regular_variable"
-
-        self.fields = [
-            'this',
-            'this.name',
-            'this.schema',
-            'this.table',
-            'target.dbname',
-            'target.host',
-            'target.name',
-            'target.port',
-            'target.schema',
-            'target.threads',
-            'target.type',
-            'target.user',
-            'target.pass',
-            'run_started_at',
-            'invocation_id',
-            'env_var'
-        ]
-
-    @property
-    def schema(self):
-        return "context_vars_013"
-
-    @property
-    def models(self):
-        return "models"
-
-    @property
-    def profile_config(self):
-        return {
-            'test': {
-                'outputs': {
-                    # don't use env_var's here so the integration tests can run
-                    # seed sql statements and the like. default target is used
-                    'dev': {
-                        'type': 'postgres',
-                        'threads': 1,
-                        'host': self.database_host,
-                        'port': 5432,
-                        'user': "root",
-                        'pass': "password",
-                        'dbname': 'dbt',
-                        'schema': self.unique_schema()
-                    },
-                    'prod': {
-                        'type': 'postgres',
-                        'threads': 1,
-                        'host': self.database_host,
-                        'port': 5432,
-                        # root/password
-                        'user': "{{ env_var('DBT_TEST_013_USER') }}",
-                        'pass': "{{ env_var('DBT_TEST_013_PASS') }}",
-                        'dbname': 'dbt',
-                        'schema': self.unique_schema()
-                    }
-                },
-                'target': 'dev'
-            }
-        }
-
-    def get_ctx_vars(self):
-        field_list = ", ".join(['"{}"'.format(f) for f in self.fields])
-        query = 'select {field_list} from {schema}.context'.format(
-            field_list=field_list,
-            schema=self.unique_schema())
-
-        vals = self.run_sql(query, fetch='all')
-        ctx = dict([(k, v) for (k, v) in zip(self.fields, vals[0])])
-
-        return ctx
-
-    @use_profile('postgres')
-    def test_postgres_env_vars_dev(self):
-        results = self.run_dbt(['run'])
-        self.assertEqual(len(results), 1)
-        ctx = self.get_ctx_vars()
-
-        manifest = get_manifest()
-        expected = {'DBT_TEST_013_ENV_VAR': '1', 'DBT_TEST_013_NOT_SECRET': 'regular_variable'}
-        self.assertEqual(manifest.env_vars, expected)
-
-        this = '"{}"."{}"."context"'.format(self.default_database,
-                                            self.unique_schema())
-        self.assertEqual(ctx['this'], this)
-
-        self.assertEqual(ctx['this.name'], 'context')
-        self.assertEqual(ctx['this.schema'], self.unique_schema())
-        self.assertEqual(ctx['this.table'], 'context')
-
-        self.assertEqual(ctx['target.dbname'], 'dbt')
-        self.assertEqual(ctx['target.host'], self.database_host)
-        self.assertEqual(ctx['target.name'], 'dev')
-        self.assertEqual(ctx['target.port'], 5432)
-        self.assertEqual(ctx['target.schema'], self.unique_schema())
-        self.assertEqual(ctx['target.threads'], 1)
-        self.assertEqual(ctx['target.type'], 'postgres')
-        self.assertEqual(ctx['target.user'], 'root')
-        self.assertEqual(ctx['target.pass'], '')
-
-        self.assertEqual(ctx['env_var'], '1')
-
-    @use_profile('postgres')
-    def test_postgres_env_vars_prod(self):
-        results = self.run_dbt(['run', '--target', 'prod'])
-        self.assertEqual(len(results), 1)
-        ctx = self.get_ctx_vars()
-
-        this = '"{}"."{}"."context"'.format(self.default_database,
-                                            self.unique_schema())
-        self.assertEqual(ctx['this'], this)
-
-        self.assertEqual(ctx['this.name'], 'context')
-        self.assertEqual(ctx['this.schema'], self.unique_schema())
-        self.assertEqual(ctx['this.table'], 'context')
-
-        self.assertEqual(ctx['target.dbname'], 'dbt')
-        self.assertEqual(ctx['target.host'], self.database_host)
-        self.assertEqual(ctx['target.name'], 'prod')
-        self.assertEqual(ctx['target.port'], 5432)
-        self.assertEqual(ctx['target.schema'], self.unique_schema())
-        self.assertEqual(ctx['target.threads'], 1)
-        self.assertEqual(ctx['target.type'], 'postgres')
-        self.assertEqual(ctx['target.user'], 'root')
-        self.assertEqual(ctx['target.pass'], '')
-        self.assertEqual(ctx['env_var'], '1')
-
-    @use_profile('postgres')
-    def test_postgres_env_vars_secrets(self):
-        os.environ['DBT_DEBUG'] = 'True'
-        _, log_output = self.run_dbt_and_capture(['run', '--target', 'prod'])
-
-        self.assertFalse("secret_variable" in log_output)
-        self.assertTrue("regular_variable" in log_output)
-
-
-class TestDisallowSecretModel(DBTIntegrationTest):
-    @property
-    def schema(self):
-        return "context_vars_013"
-
-    @property
-    def models(self):
-        return "models-with-secret-bad"
-
-    @use_profile('postgres')
-    def test_postgres_disallow_secret(self):
-        with self.assertRaises(dbt.exceptions.ParsingException) as exc:
-            self.run_dbt(['compile'])
-
-        
-class TestAllowSecretProfilePackage(DBTIntegrationTest):
-
-    def setUp(self):
-        os.environ[SECRET_ENV_PREFIX + "USER"] = "root"
-        os.environ[SECRET_ENV_PREFIX + "PASS"] = "password"
-        os.environ[SECRET_ENV_PREFIX + "PACKAGE"] = "first_dependency"
-        DBTIntegrationTest.setUp(self)
-    
-    @property
-    def packages_config(self):
-        return {
-            "packages": [
-                {"local": "{{ env_var('DBT_ENV_SECRET_PACKAGE') }}"},
-            ]
-        }
-        
-    @property
-    def profile_config(self):
-        return {
-            'test': {
-                'outputs': {
-                    'default': {
-                        'type': 'postgres',
-                        'threads': 1,
-                        'host': self.database_host,
-                        'port': 5432,
-                        # root/password
-                        'user': "{{ env_var('DBT_ENV_SECRET_USER') }}",
-                        'pass': "{{ env_var('DBT_ENV_SECRET_PASS') }}",
-                        'dbname': 'dbt',
-                        'schema': self.unique_schema()
-                    },
-                'target': 'default'
-            }
-        }
-    }
-            
-    @property
-    def schema(self):
-        return "context_vars_013"
-
-    @property
-    def models(self):
-        return "models"
-
-    @use_profile('postgres')
-    def test_postgres_allow_secrets(self):
-        _, log_output = self.run_dbt_and_capture(['deps'])
-
-        self.assertFalse("first_dependency" in log_output)
-
-
-class TestCloneFailSecretScrubbed(DBTIntegrationTest):
-    
-    def setUp(self):
-        os.environ[SECRET_ENV_PREFIX + "GIT_TOKEN"] = "abc123"
-        DBTIntegrationTest.setUp(self)
-
-    @property
-    def packages_config(self):
-        return {
-            "packages": [
-                {"git": "https://fakeuser:{{ env_var('DBT_ENV_SECRET_GIT_TOKEN') }}@github.com/dbt-labs/fake-repo.git"},
-            ]
-        }
-            
-    @property
-    def schema(self):
-        return "context_vars_013"
-
-    @property
-    def models(self):
-        return "models"
-
-    @use_profile('postgres')
-    def test_postgres_fail_clone_with_scrubbing(self):
-        with self.assertRaises(dbt.exceptions.InternalException) as exc:
-            _, log_output = self.run_dbt_and_capture(['deps'])
-
-        assert "abc123" not in str(exc.exception)
-
-
-class TestEmitWarning(DBTIntegrationTest):
-    @property
-    def schema(self):
-        return "context_vars_013"
-
-    @property
-    def models(self):
-        return "emit-warning-models"
-
-    @use_profile('postgres')
-    def test_postgres_warn(self):
-        self.run_dbt(['run'], expect_pass=True)
-
-
-class TestVarDependencyInheritance(DBTIntegrationTest):
-    @property
-    def schema(self):
-        return "context_vars_013"
-
-    @property
-    def models(self):
-        return 'dependency-models'
-
-    @property
-    def packages_config(self):
-        return {
-            "packages": [
-                {'local': 'first_dependency'},
-            ]
-        }
-
-    @property
-    def project_config(self):
-        return {
-            'config-version': 2,
-            'seed-paths': ['dependency-seeds'],
-            'vars': {
-                'first_dep_override': 'dep_never_overridden',
-                'test': {
-                    'from_root_to_root': 'root_root_value',
-                },
-                'first_dep': {
-                    'from_root_to_first': 'root_first_value',
-                },
-            },
-        }
-
-    @use_profile('postgres')
-    def test_postgres_var_mutual_overrides_v1_conversion(self):
-        self.run_dbt(['deps'])
-        assert len(self.run_dbt(['seed'])) == 2
-        assert len(self.run_dbt(['run'])) == 2
-        self.assertTablesEqual('root_model_expected', 'model')
-        self.assertTablesEqual('first_dep_expected', 'first_dep_model')
-
-
-class TestMissingVarGenerateNameMacro(DBTIntegrationTest):
-    @property
-    def schema(self):
-        return "context_vars_013"
-
-    @property
-    def models(self):
-        return 'trivial-models'
-
-    @property
-    def project_config(self):
-        return {
-            'macro-paths': ['bad-generate-macros'],
-        }
-
-    @use_profile('postgres')
-    def test_postgres_generate_schema_name_var(self):
-        with self.assertRaises(dbt.exceptions.CompilationException) as exc:
-            self.run_dbt(['compile'])
-
-        assert "Required var 'somevar' not found in config" in str(exc.exception)
-
-        # globally scoped
-        self.use_default_project({
-            'vars': {
-                'somevar': 1,
-            },
-            'macro-paths': ['bad-generate-macros'],
-        })
-        self.run_dbt(['compile'])
-        # locally scoped
-        self.use_default_project({
-            'vars': {
-                'test': {
-                    'somevar': 1,
-                },
-            },
-            'macro-paths': ['bad-generate-macros'],
-        })
-        self.run_dbt(['compile'])
diff --git a/test/integration/013_context_var_tests/tests/from_yaml.sql b/test/integration/013_context_var_tests/tests/from_yaml.sql
deleted file mode 100644
--- a/test/integration/013_context_var_tests/tests/from_yaml.sql
+++ /dev/null
@@ -1,14 +0,0 @@
-{% set simplest = (fromyaml('a: 1') == {'a': 1}) %}
-{% set nested_data %}
-a:
-  b:
-   - c: 1
-     d: 2
-   - c: 3
-     d: 4
-{% endset %}
-{% set nested = (fromyaml(nested_data) == {'a': {'b': [{'c': 1, 'd': 2}, {'c': 3, 'd': 4}]}}) %}
-
-(select 'simplest' as name {% if simplest %}limit 0{% endif %})
-union all
-(select 'nested' as name {% if nested %}limit 0{% endif %})
diff --git a/test/integration/013_context_var_tests/tests/to_yaml.sql b/test/integration/013_context_var_tests/tests/to_yaml.sql
deleted file mode 100644
--- a/test/integration/013_context_var_tests/tests/to_yaml.sql
+++ /dev/null
@@ -1,17 +0,0 @@
-
-{% set simplest = (toyaml({'a': 1}) == 'a: 1\n') %}
-{% set default_sort = (toyaml({'b': 2, 'a': 1}) == 'b: 2\na: 1\n') %}
-{% set unsorted = (toyaml({'b': 2, 'a': 1}, sort_keys=False) == 'b: 2\na: 1\n') %}
-{% set sorted = (toyaml({'b': 2, 'a': 1}, sort_keys=True) == 'a: 1\nb: 2\n') %}
-{% set default_results = (toyaml({'a': adapter}, 'failed') == 'failed') %}
-
-(select 'simplest' as name {% if simplest %}limit 0{% endif %})
-union all
-(select 'default_sort' as name {% if default_sort %}limit 0{% endif %})
-union all
-(select 'unsorted' as name {% if unsorted %}limit 0{% endif %})
-union all
-(select 'sorted' as name {% if sorted %}limit 0{% endif %})
-union all
-(select 'default_results' as name {% if default_results %}limit 0{% endif %})
-
diff --git a/test/integration/013_context_var_tests/trivial-models/model.sql b/test/integration/013_context_var_tests/trivial-models/model.sql
deleted file mode 100644
--- a/test/integration/013_context_var_tests/trivial-models/model.sql
+++ /dev/null
@@ -1 +0,0 @@
-select 1 as id
diff --git a/tests/functional/context_methods/first_dependency.py b/tests/functional/context_methods/first_dependency.py
new file mode 100644
--- /dev/null
+++ b/tests/functional/context_methods/first_dependency.py
@@ -0,0 +1,58 @@
+import pytest
+
+from dbt.tests.fixtures.project import write_project_files
+
+first_dependency__dbt_project_yml = """
+name: 'first_dep'
+version: '1.0'
+config-version: 2
+
+profile: 'default'
+
+model-paths: ["models"]
+analysis-paths: ["analyses"]
+test-paths: ["tests"]
+seed-paths: ["seeds"]
+macro-paths: ["macros"]
+
+require-dbt-version: '>=0.1.0'
+
+target-path: "target"  # directory which will store compiled SQL files
+clean-targets:         # directories to be removed by `dbt clean`
+    - "target"
+    - "dbt_packages"
+
+vars:
+  first_dep:
+    first_dep_global: 'first_dep_global_value_overridden'
+
+
+seeds:
+  quote_columns: True
+
+"""
+
+first_dependency__models__nested__first_dep_model_sql = """
+select
+    '{{ var("first_dep_global") }}' as first_dep_global,
+    '{{ var("from_root_to_first") }}' as from_root
+"""
+
+first_dependency__seeds__first_dep_expected_csv = """first_dep_global,from_root
+first_dep_global_value_overridden,root_first_value
+"""
+
+
+class FirstDependencyProject:
+    @pytest.fixture(scope="class")
+    def first_dependency(self, project):
+        first_dependency_files = {
+            "dbt_project.yml": first_dependency__dbt_project_yml,
+            "models": {
+                "nested": {
+                    "first_dep_model.sql": first_dependency__models__nested__first_dep_model_sql
+                }
+            },
+            "seeds": {"first_dep_expected.csv": first_dependency__seeds__first_dep_expected_csv},
+        }
+        write_project_files(project.project_root, "first_dependency", first_dependency_files)
diff --git a/tests/functional/cli_vars/test_cli_var_override.py b/tests/functional/context_methods/test_cli_var_override.py
similarity index 100%
rename from tests/functional/cli_vars/test_cli_var_override.py
rename to tests/functional/context_methods/test_cli_var_override.py
diff --git a/tests/functional/cli_vars/test_cli_vars.py b/tests/functional/context_methods/test_cli_vars.py
similarity index 100%
rename from tests/functional/cli_vars/test_cli_vars.py
rename to tests/functional/context_methods/test_cli_vars.py
diff --git a/tests/functional/context_methods/test_env_vars.py b/tests/functional/context_methods/test_env_vars.py
new file mode 100644
--- /dev/null
+++ b/tests/functional/context_methods/test_env_vars.py
@@ -0,0 +1,182 @@
+import pytest
+import os
+
+from dbt.tests.util import run_dbt, get_manifest, run_dbt_and_capture
+from dbt.logger import SECRET_ENV_PREFIX
+
+
+context_sql = """
+
+{{
+    config(
+        materialized='table'
+    )
+}}
+
+select
+
+    -- compile-time variables
+    '{{ this }}'        as "this",
+    '{{ this.name }}'   as "this.name",
+    '{{ this.schema }}' as "this.schema",
+    '{{ this.table }}'  as "this.table",
+
+    '{{ target.dbname }}'  as "target.dbname",
+    '{{ target.host }}'    as "target.host",
+    '{{ target.name }}'    as "target.name",
+    '{{ target.schema }}'  as "target.schema",
+    '{{ target.type }}'    as "target.type",
+    '{{ target.user }}'    as "target.user",
+    '{{ target.get("pass", "") }}'    as "target.pass", -- not actually included, here to test that it is _not_ present!
+    {{ target.port }}      as "target.port",
+    {{ target.threads }}   as "target.threads",
+
+    -- runtime variables
+    '{{ run_started_at }}' as run_started_at,
+    '{{ invocation_id }}'  as invocation_id,
+
+    '{{ env_var("DBT_TEST_ENV_VAR") }}' as env_var,
+    'secret_variable' as env_var_secret, -- make sure the value itself is scrubbed from the logs
+    '{{ env_var("DBT_TEST_NOT_SECRET") }}' as env_var_not_secret
+
+"""
+
+
+class TestEnvVars:
+    @pytest.fixture(scope="class")
+    def models(self):
+        return {"context.sql": context_sql}
+
+    @pytest.fixture(scope="class", autouse=True)
+    def setup(self):
+        os.environ["DBT_TEST_ENV_VAR"] = "1"
+        os.environ["DBT_TEST_USER"] = "root"
+        os.environ["DBT_TEST_PASS"] = "password"
+        os.environ[SECRET_ENV_PREFIX + "SECRET"] = "secret_variable"
+        os.environ["DBT_TEST_NOT_SECRET"] = "regular_variable"
+        yield
+        del os.environ["DBT_TEST_ENV_VAR"]
+        del os.environ["DBT_TEST_USER"]
+        del os.environ[SECRET_ENV_PREFIX + "SECRET"]
+        del os.environ["DBT_TEST_NOT_SECRET"]
+
+    @pytest.fixture(scope="class")
+    def profiles_config_update(self, unique_schema):
+        return {
+            "test": {
+                "outputs": {
+                    # don't use env_var's here so the integration tests can run
+                    # seed sql statements and the like. default target is used
+                    "dev": {
+                        "type": "postgres",
+                        "threads": 1,
+                        "host": "localhost",
+                        "port": 5432,
+                        "user": "root",
+                        "pass": "password",
+                        "dbname": "dbt",
+                        "schema": unique_schema,
+                    },
+                    "prod": {
+                        "type": "postgres",
+                        "threads": 1,
+                        "host": "localhost",
+                        "port": 5432,
+                        # root/password
+                        "user": "{{ env_var('DBT_TEST_USER') }}",
+                        "pass": "{{ env_var('DBT_TEST_PASS') }}",
+                        "dbname": "dbt",
+                        "schema": unique_schema,
+                    },
+                },
+                "target": "dev",
+            }
+        }
+
+    def get_ctx_vars(self, project):
+        fields = [
+            "this",
+            "this.name",
+            "this.schema",
+            "this.table",
+            "target.dbname",
+            "target.host",
+            "target.name",
+            "target.port",
+            "target.schema",
+            "target.threads",
+            "target.type",
+            "target.user",
+            "target.pass",
+            "run_started_at",
+            "invocation_id",
+            "env_var",
+        ]
+        field_list = ", ".join(['"{}"'.format(f) for f in fields])
+        query = "select {field_list} from {schema}.context".format(
+            field_list=field_list, schema=project.test_schema
+        )
+        vals = project.run_sql(query, fetch="all")
+        ctx = dict([(k, v) for (k, v) in zip(fields, vals[0])])
+        return ctx
+
+    def test_env_vars_dev(
+        self,
+        project,
+    ):
+        results = run_dbt(["run"])
+        assert len(results) == 1
+        ctx = self.get_ctx_vars(project)
+
+        manifest = get_manifest(project.project_root)
+        expected = {"DBT_TEST_ENV_VAR": "1", "DBT_TEST_NOT_SECRET": "regular_variable"}
+        assert manifest.env_vars == expected
+
+        this = '"{}"."{}"."context"'.format(project.database, project.test_schema)
+        assert ctx["this"] == this
+
+        assert ctx["this.name"] == "context"
+        assert ctx["this.schema"] == project.test_schema
+        assert ctx["this.table"] == "context"
+
+        assert ctx["target.dbname"] == "dbt"
+        assert ctx["target.host"] == "localhost"
+        assert ctx["target.name"] == "dev"
+        assert ctx["target.port"] == 5432
+        assert ctx["target.schema"] == project.test_schema
+        assert ctx["target.threads"] == 1
+        assert ctx["target.type"] == "postgres"
+        assert ctx["target.user"] == "root"
+        assert ctx["target.pass"] == ""
+
+        assert ctx["env_var"] == "1"
+
+    def test_env_vars_prod(self, project):
+        results = run_dbt(["run", "--target", "prod"])
+        assert len(results) == 1
+        ctx = self.get_ctx_vars(project)
+
+        this = '"{}"."{}"."context"'.format(project.database, project.test_schema)
+        assert ctx["this"] == this
+
+        assert ctx["this.name"] == "context"
+        assert ctx["this.schema"] == project.test_schema
+        assert ctx["this.table"] == "context"
+
+        assert ctx["target.dbname"] == "dbt"
+        assert ctx["target.host"] == "localhost"
+        assert ctx["target.name"] == "prod"
+        assert ctx["target.port"] == 5432
+        assert ctx["target.schema"] == project.test_schema
+        assert ctx["target.threads"] == 1
+        assert ctx["target.type"] == "postgres"
+        assert ctx["target.user"] == "root"
+        assert ctx["target.pass"] == ""
+        assert ctx["env_var"] == "1"
+
+    def test_env_vars_secrets(self, project):
+        os.environ["DBT_DEBUG"] = "True"
+        _, log_output = run_dbt_and_capture(["run", "--target", "prod"])
+
+        assert not ("secret_variable" in log_output)
+        assert "regular_variable" in log_output
diff --git a/tests/functional/context_methods/test_secret_env_vars.py b/tests/functional/context_methods/test_secret_env_vars.py
new file mode 100644
--- /dev/null
+++ b/tests/functional/context_methods/test_secret_env_vars.py
@@ -0,0 +1,136 @@
+import pytest
+import os
+
+from dbt.tests.util import run_dbt, run_dbt_and_capture
+from dbt.exceptions import ParsingException, InternalException
+from dbt.logger import SECRET_ENV_PREFIX
+from tests.functional.context_methods.first_dependency import FirstDependencyProject
+
+
+secret_bad__context_sql = """
+
+{{
+    config(
+        materialized='table'
+    )
+}}
+
+select
+
+    '{{ env_var("DBT_TEST_ENV_VAR") }}' as env_var,
+    '{{ env_var("DBT_ENV_SECRET_SECRET") }}' as env_var_secret, -- this should raise an error!
+    '{{ env_var("DBT_TEST_NOT_SECRET") }}' as env_var_not_secret
+
+"""
+
+
+class TestDisallowSecretModel:
+    @pytest.fixture(scope="class")
+    def models(self):
+        return {"context.sql": secret_bad__context_sql}
+
+    def test_disallow_secret(self, project):
+        with pytest.raises(ParsingException):
+            run_dbt(["compile"])
+
+
+models__context_sql = """
+{{
+    config(
+        materialized='table'
+    )
+}}
+
+select
+
+    -- compile-time variables
+    '{{ this }}'        as "this",
+    '{{ this.name }}'   as "this.name",
+    '{{ this.schema }}' as "this.schema",
+    '{{ this.table }}'  as "this.table",
+
+    '{{ target.dbname }}'  as "target.dbname",
+    '{{ target.host }}'    as "target.host",
+    '{{ target.name }}'    as "target.name",
+    '{{ target.schema }}'  as "target.schema",
+    '{{ target.type }}'    as "target.type",
+    '{{ target.user }}'    as "target.user",
+    '{{ target.get("pass", "") }}'    as "target.pass", -- not actually included, here to test that it is _not_ present!
+    {{ target.port }}      as "target.port",
+    {{ target.threads }}   as "target.threads",
+
+    -- runtime variables
+    '{{ run_started_at }}' as run_started_at,
+    '{{ invocation_id }}'  as invocation_id,
+
+    '{{ env_var("DBT_TEST_ENV_VAR") }}' as env_var,
+    'secret_variable' as env_var_secret, -- make sure the value itself is scrubbed from the logs
+    '{{ env_var("DBT_TEST_NOT_SECRET") }}' as env_var_not_secret
+"""
+
+
+class TestAllowSecretProfilePackage(FirstDependencyProject):
+    @pytest.fixture(scope="class", autouse=True)
+    def setup(self):
+        os.environ[SECRET_ENV_PREFIX + "USER"] = "root"
+        os.environ[SECRET_ENV_PREFIX + "PASS"] = "password"
+        os.environ[SECRET_ENV_PREFIX + "PACKAGE"] = "first_dependency"
+        yield
+        del os.environ[SECRET_ENV_PREFIX + "USER"]
+        del os.environ[SECRET_ENV_PREFIX + "PASS"]
+        del os.environ[SECRET_ENV_PREFIX + "PACKAGE"]
+
+    @pytest.fixture(scope="class")
+    def models(self):
+        return {"context.sql": models__context_sql}
+
+    @pytest.fixture(scope="class")
+    def packages(self):
+        return {
+            "packages": [
+                {"local": "{{ env_var('DBT_ENV_SECRET_PACKAGE') }}"},
+            ]
+        }
+
+    @pytest.fixture(scope="class")
+    def profile_target(self):
+        return {
+            "type": "postgres",
+            "threads": 1,
+            "host": "localhost",
+            "port": 5432,
+            # root/password
+            "user": "{{ env_var('DBT_ENV_SECRET_USER') }}",
+            "pass": "{{ env_var('DBT_ENV_SECRET_PASS') }}",
+            "dbname": "dbt",
+        }
+
+    def test_allow_secrets(self, project, first_dependency):
+        _, log_output = run_dbt_and_capture(["deps"])
+        assert not ("first_dependency" in log_output)
+
+
+class TestCloneFailSecretScrubbed:
+    @pytest.fixture(scope="class", autouse=True)
+    def setup(self):
+        os.environ[SECRET_ENV_PREFIX + "GIT_TOKEN"] = "abc123"
+
+    @pytest.fixture(scope="class")
+    def models(self):
+        return {"context.sql": models__context_sql}
+
+    @pytest.fixture(scope="class")
+    def packages(self):
+        return {
+            "packages": [
+                {
+                    "git": "https://fakeuser:{{ env_var('DBT_ENV_SECRET_GIT_TOKEN') }}@github.com/dbt-labs/fake-repo.git"
+                },
+            ]
+        }
+
+    def test_fail_clone_with_scrubbing(self, project):
+        with pytest.raises(InternalException) as excinfo:
+            _, log_output = run_dbt_and_capture(["deps"])
+
+        assert "abc123" not in str(excinfo.value)
diff --git a/tests/functional/context_methods/test_var_dependency.py b/tests/functional/context_methods/test_var_dependency.py
new file mode 100644
--- /dev/null
+++ b/tests/functional/context_methods/test_var_dependency.py
@@ -0,0 +1,54 @@
+import pytest
+from dbt.tests.util import run_dbt, check_relations_equal
+
+from tests.functional.context_methods.first_dependency import FirstDependencyProject
+
+dependency_seeds__root_model_expected_csv = """first_dep_global,from_root
+dep_never_overridden,root_root_value
+"""
+
+dependency_models__inside__model_sql = """
+select
+    '{{ var("first_dep_override") }}' as first_dep_global,
+    '{{ var("from_root_to_root") }}' as from_root
+
+"""
+
+
+class TestVarDependencyInheritance(FirstDependencyProject):
+    @pytest.fixture(scope="class")
+    def seeds(self):
+        return {"root_model_expected.csv": dependency_seeds__root_model_expected_csv}
+
+    @pytest.fixture(scope="class")
+    def models(self):
+        return {"inside": {"model.sql": dependency_models__inside__model_sql}}
+
+    @pytest.fixture(scope="class")
+    def packages(self):
+        return {
+            "packages": [
+                {"local": "first_dependency"},
+            ]
+        }
+
+    @pytest.fixture(scope="class")
+    def project_config_update(self):
+        return {
+            "vars": {
+                "first_dep_override": "dep_never_overridden",
+                "test": {
+                    "from_root_to_root": "root_root_value",
+                },
+                "first_dep": {
+                    "from_root_to_first": "root_first_value",
+                },
+            },
+        }
+
+    def test_var_mutual_overrides_v1_conversion(self, project, first_dependency):
+        run_dbt(["deps"])
+        assert len(run_dbt(["seed"])) == 2
+        assert len(run_dbt(["run"])) == 2
+        check_relations_equal(project.adapter, ["root_model_expected", "model"])
+        check_relations_equal(project.adapter, ["first_dep_expected", "first_dep_model"])
diff --git a/tests/functional/context_methods/test_var_in_generate_name.py b/tests/functional/context_methods/test_var_in_generate_name.py
new file mode 100644
--- /dev/null
+++ b/tests/functional/context_methods/test_var_in_generate_name.py
@@ -0,0 +1,43 @@
+import pytest
+
+from dbt.tests.util import run_dbt, update_config_file
+from dbt.exceptions import CompilationException
+
+model_sql = """
+select 1 as id
+"""
+
+bad_generate_macros__generate_names_sql = """
+{% macro generate_schema_name(custom_schema_name, node) -%}
+    {% do var('somevar') %}
+    {% do return(dbt.generate_schema_name(custom_schema_name, node)) %}
+{%- endmacro %}
+
+"""
+
+
+class TestMissingVarGenerateNameMacro:
+    @pytest.fixture(scope="class")
+    def macros(self):
+        return {"generate_names.sql": bad_generate_macros__generate_names_sql}
+
+    @pytest.fixture(scope="class")
+    def models(self):
+        return {"model.sql": model_sql}
+
+    def test_generate_schema_name_var(self, project):
+        # var isn't set, so generate_name macro fails
+        with pytest.raises(CompilationException) as excinfo:
+            run_dbt(["compile"])
+
+        assert "Required var 'somevar' not found in config" in str(excinfo.value)
+
+        # globally scoped -- var is set at top-level
+        update_config_file({"vars": {"somevar": 1}}, project.project_root, "dbt_project.yml")
+        run_dbt(["compile"])
+
+        # locally scoped -- var is set in 'test' scope
+        update_config_file(
+            {"vars": {"test": {"somevar": 1}}}, project.project_root, "dbt_project.yml"
+        )
+        run_dbt(["compile"])
diff --git a/tests/functional/context_methods/test_yaml_functions.py b/tests/functional/context_methods/test_yaml_functions.py
new file mode 100644
--- /dev/null
+++ b/tests/functional/context_methods/test_yaml_functions.py
@@ -0,0 +1,50 @@
+import pytest
+
+from dbt.tests.util import run_dbt
+
+
+tests__from_yaml_sql = """
+{% set simplest = (fromyaml('a: 1') == {'a': 1}) %}
+{% set nested_data %}
+a:
+  b:
+   - c: 1
+     d: 2
+   - c: 3
+     d: 4
+{% endset %}
+{% set nested = (fromyaml(nested_data) == {'a': {'b': [{'c': 1, 'd': 2}, {'c': 3, 'd': 4}]}}) %}
+
+(select 'simplest' as name {% if simplest %}limit 0{% endif %})
+union all
+(select 'nested' as name {% if nested %}limit 0{% endif %})
+"""
+
+tests__to_yaml_sql = """
+{% set simplest = (toyaml({'a': 1}) == 'a: 1\\n') %}
+{% set default_sort = (toyaml({'b': 2, 'a': 1}) == 'b: 2\\na: 1\\n') %}
+{% set unsorted = (toyaml({'b': 2, 'a': 1}, sort_keys=False) == 'b: 2\\na: 1\\n') %}
+{% set sorted = (toyaml({'b': 2, 'a': 1}, sort_keys=True) == 'a: 1\\nb: 2\\n') %}
+{% set default_results = (toyaml({'a': adapter}, 'failed') == 'failed') %}
+
+(select 'simplest' as name {% if simplest %}limit 0{% endif %})
+union all
+(select 'default_sort' as name {% if default_sort %}limit 0{% endif %})
+union all
+(select 'unsorted' as name {% if unsorted %}limit 0{% endif %})
+union all
+(select 'sorted' as name {% if sorted %}limit 0{% endif %})
+union all
+(select 'default_results' as name {% if default_results %}limit 0{% endif %})
+"""
+
+
+class TestContextVars:
+    # This test has no actual models
+
+    @pytest.fixture(scope="class")
+    def tests(self):
+        return {"from_yaml.sql": tests__from_yaml_sql, "to_yaml.sql": tests__to_yaml_sql}
+
+    def test_json_data_tests(self, project):
+        assert len(run_dbt(["test"])) == 2
diff --git a/tests/functional/invalid_model_tests/test_model_warning.py b/tests/functional/invalid_model_tests/test_model_warning.py
new file mode 100644
--- /dev/null
+++ b/tests/functional/invalid_model_tests/test_model_warning.py
@@ -0,0 +1,18 @@
+import pytest
+
+from dbt.tests.util import run_dbt
+
+warnings_sql = """
+{% do exceptions.warn('warning: everything is terrible but not that terrible') %}
+{{ exceptions.warn("warning: everything is terrible but not that terrible") }}
+select 1 as id
+"""
+
+
+class TestEmitWarning:
+    @pytest.fixture(scope="class")
+    def models(self):
+        return {"warnings.sql": warnings_sql}
+
+    def test_warn(self, project):
+        run_dbt(["run"], expect_pass=True)