Repository: dbt-labs/dbt-core

Issue:
[0.14.1 Regression] `dbt source snapshot-freshness` can hang
The `dbt source snapshot-freshness` command will hang if a project contains ephemeral models. This is related to the 0.14.1 change which returned ephemeral models indiscriminately from the node selector, a performance improvement. These ephemeral models find their way into the job queue, but are not processed in the codepath of `dbt source snapshot-freshness`, leading to a hang.

Separately, ctrl+c'ing the hanged process results in an error in the KeyboardInterrupt handler.


Discussion:

Resolving patch:
diff --git a/core/dbt/contracts/results.py b/core/dbt/contracts/results.py
--- a/core/dbt/contracts/results.py
+++ b/core/dbt/contracts/results.py
@@ -286,6 +286,10 @@ def __init__(self, node, max_loaded_at, snapshotted_at,
     def failed(self):
         return self.status == 'error'
 
+    @property
+    def warned(self):
+        return self.status == 'warn'
+
     @property
     def skipped(self):
         return False
diff --git a/core/dbt/task/freshness.py b/core/dbt/task/freshness.py
--- a/core/dbt/task/freshness.py
+++ b/core/dbt/task/freshness.py
@@ -28,6 +28,7 @@ def build_query(self):
             "resource_types": [NodeType.Source],
             "tags": [],
             "required": ['has_freshness'],
+            "addin_ephemeral_nodes": False,
         }
 
     def get_runner_type(self):
diff --git a/core/dbt/ui/printer.py b/core/dbt/ui/printer.py
--- a/core/dbt/ui/printer.py
+++ b/core/dbt/ui/printer.py
@@ -297,8 +297,14 @@ def print_run_result_error(result, newline=True, is_warning=False):
             result.node.get('resource_type'),
             result.node.get('name'),
             result.node.get('original_file_path')))
-        status = dbt.utils.pluralize(result.status, 'result')
-        logger.info("  Got {}, expected 0.".format(status))
+
+        try:
+            int(result.status)
+        except ValueError:
+            logger.info("  Status: {}".format(result.status))
+        else:
+            status = dbt.utils.pluralize(result.status, 'result')
+            logger.info("  Got {}, expected 0.".format(status))
 
         if result.node.get('build_path') is not None:
             logger.info("")


Test patch:
diff --git a/test/integration/042_sources_test/models/view_model.sql b/test/integration/042_sources_test/models/view_model.sql
new file mode 100644
--- /dev/null
+++ b/test/integration/042_sources_test/models/view_model.sql
@@ -0,0 +1,4 @@
+
+-- See here: https://github.com/fishtown-analytics/dbt/pull/1729
+
+select * from {{ ref('ephemeral_model') }}
diff --git a/test/integration/042_sources_test/test_sources.py b/test/integration/042_sources_test/test_sources.py
--- a/test/integration/042_sources_test/test_sources.py
+++ b/test/integration/042_sources_test/test_sources.py
@@ -87,7 +87,7 @@ def run_dbt_with_vars(self, cmd, *args, **kwargs):
     @use_profile('postgres')
     def test_postgres_basic_source_def(self):
         results = self.run_dbt_with_vars(['run'])
-        self.assertEqual(len(results), 3)
+        self.assertEqual(len(results), 4)
         self.assertManyTablesEqual(
             ['source', 'descendant_model', 'nonsource_descendant'],
             ['expected_multi_source', 'multi_source_model'])