Repository: google/turbinia

Issue:
Recipe validation fails
When trying to submit a recipe over turbiniactl, the recipe validation fails:

turbiniactl -P ./temp/recipe.yaml googleclouddisk -d disk-name

2021-11-19 09:48:04 [INFO] Turbinia version: 20211018
2021-11-19 09:48:16 [INFO] Disabling non-allowlisted jobs configured to be disabled in the config file: binaryextractorjob, bulkextractorjob, dfdeweyjob, hindsightjob, photorecjob, jenkinsanalysisjob, volatilityjob
2021-11-19 09:48:16 [INFO] Loading recipe file from ./temp/recipe.yaml
Traceback (most recent call last):
  File "/usr/local/bin/turbiniactl", line 8, in <module>
    sys.exit(main())
  File "/usr/local/lib/python3.9/site-packages/turbinia/turbiniactl.py", line 824, in main
    recipe_dict = recipe_helpers.load_recipe_from_file(
  File "/usr/local/lib/python3.9/site-packages/turbinia/lib/recipe_helpers.py", line 60, in load_recipe_from_file
    success, _ = validate_recipe(recipe_dict)
  File "/usr/local/lib/python3.9/site-packages/turbinia/lib/recipe_helpers.py", line 161, in validate_recipe
    if not task_loader.check_task_name(proposed_task):
  File "/usr/local/lib/python3.9/site-packages/turbinia/task_utils.py", line 82, in check_task_name
    for task in TASK_LIST:
NameError: name 'TASK_LIST' is not defined

Bug is also present in master branch, this should be "self.TASK_LIST":

https://github.com/google/turbinia/blob/54c2a03566422efffcc93197661d6e5da319e591/turbinia/task_utils.py#L82

Would send a PR myself, but still getting approvals to contribute :) 


Discussion:

Resolving patch:
diff --git a/turbinia/task_utils.py b/turbinia/task_utils.py
--- a/turbinia/task_utils.py
+++ b/turbinia/task_utils.py
@@ -79,7 +79,7 @@ def check_task_name(self, task_name):
     Returns:
       bool: True if task with the given name exists, else False
     """
-    for task in TASK_LIST:
+    for task in self.TASK_LIST:
       if task.lower() == task_name.lower():
         return True
     return False


Test patch:
diff --git a/turbinia/task_utils_test.py b/turbinia/task_utils_test.py
new file mode 100644
--- /dev/null
+++ b/turbinia/task_utils_test.py
@@ -0,0 +1,75 @@
+# -*- coding: utf-8 -*-
+# Copyright 2021 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Tests for Turbinia task_utils module."""
+
+from __future__ import unicode_literals
+
+import unittest
+import mock
+
+from turbinia import task_utils
+from turbinia import TurbiniaException
+from turbinia.workers.plaso import PlasoTask
+
+
+class TestTurbiniaTaskLoader(unittest.TestCase):
+  """Test Turbinia task_utils module."""
+
+  def testCheckTaskNames(self):
+    """Basic test for Turbinia get_task_names."""
+    task_loader = task_utils.TaskLoader()
+
+    # Check valid task
+    self.assertTrue(task_loader.check_task_name('PlasoTask'))
+
+    # Check invalid task
+    self.assertFalse(task_loader.check_task_name('NoSuchTask'))
+
+  def testGetTaskNames(self):
+    """Basic test for get_task_names."""
+    task_loader = task_utils.TaskLoader()
+    task_names = task_loader.get_task_names()
+    self.assertIn('PlasoTask', task_names)
+
+  def testGetTask(self):
+    """Basic test for get_task."""
+    task_loader = task_utils.TaskLoader()
+
+    # Check valid Task
+    task = task_loader.get_task('PlasoTask')
+    self.assertEqual(task.name, 'PlasoTask')
+    self.assertIsInstance(task, PlasoTask)
+
+    # Check invalid Task
+    self.assertIsNone(task_loader.get_task('NoSuchTask'))
+
+  def testTaskDeserialize(self):
+    """Basic test for task_deserialize."""
+    task = PlasoTask(request_id='testRequestID', requester='testRequester')
+    task_dict = task.serialize()
+    test_task = task_utils.task_deserialize(task_dict)
+    self.assertEqual(test_task.request_id, 'testRequestID')
+    self.assertEqual(test_task.requester, 'testRequester')
+    self.assertIsInstance(test_task, PlasoTask)
+
+  @mock.patch('turbinia.task_utils.task_deserialize')
+  def testTaskRunner(self, mock_task_deserialize):
+    """Basic test for task_runner."""
+    task = PlasoTask()
+    task.run_wrapper = lambda x: x
+    mock_task_deserialize.return_value = task
+    task_dict = task.serialize()
+    ret = task_utils.task_runner(task_dict, 'testValue')
+    self.assertEqual(ret, 'testValue')
\ No newline at end of file