Home | History | Annotate | Download | only in bestflags
      1 # Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 """Unittest for the pipeline_worker functions in the build/test stage.
      5 
      6 Part of the Chrome build flags optimization.
      7 
      8 This module tests the helper method and the worker method.
      9 """
     10 
     11 __author__ = 'yuhenglong (at] google.com (Yuheng Long)'
     12 
     13 import multiprocessing
     14 import random
     15 import sys
     16 import unittest
     17 
     18 from mock_task import MockTask
     19 import pipeline_process
     20 import pipeline_worker
     21 
     22 # Pick an integer at random.
     23 TEST_STAGE = -3
     24 
     25 
     26 def MockTaskCostGenerator():
     27   """Calls a random number generator and returns a negative number."""
     28   return random.randint(-sys.maxint - 1, -1)
     29 
     30 
     31 class PipelineWorkerTest(unittest.TestCase):
     32   """This class tests the pipeline_worker functions.
     33 
     34   Given the same identifier, the cost should result the same from the
     35   pipeline_worker functions.
     36   """
     37 
     38   def testHelper(self):
     39     """"Test the helper.
     40 
     41     Call the helper method twice, and test the results. The results should be
     42     the same, i.e., the cost should be the same.
     43     """
     44 
     45     # Set up the input, helper and output queue for the helper method.
     46     manager = multiprocessing.Manager()
     47     helper_queue = manager.Queue()
     48     result_queue = manager.Queue()
     49     completed_queue = manager.Queue()
     50 
     51     # Set up the helper process that holds the helper method.
     52     helper_process = multiprocessing.Process(
     53         target=pipeline_worker.Helper,
     54         args=(TEST_STAGE, {}, helper_queue, completed_queue, result_queue))
     55     helper_process.start()
     56 
     57     # A dictionary defines the mock result to the helper.
     58     mock_result = {1: 1995, 2: 59, 9: 1027}
     59 
     60     # Test if there is a task that is done before, whether the duplicate task
     61     # will have the same result. Here, two different scenarios are tested. That
     62     # is the mock results are added to the completed_queue before and after the
     63     # corresponding mock tasks being added to the input queue.
     64     completed_queue.put((9, mock_result[9]))
     65 
     66     # The output of the helper should contain all the following tasks.
     67     results = [1, 1, 2, 9]
     68 
     69     # Testing the correctness of having tasks having the same identifier, here
     70     # 1.
     71     for result in results:
     72       helper_queue.put(MockTask(TEST_STAGE, result, MockTaskCostGenerator()))
     73 
     74     completed_queue.put((2, mock_result[2]))
     75     completed_queue.put((1, mock_result[1]))
     76 
     77     # Signal there is no more duplicate task.
     78     helper_queue.put(pipeline_process.POISONPILL)
     79     helper_process.join()
     80 
     81     while results:
     82       task = result_queue.get()
     83       identifier = task.GetIdentifier(TEST_STAGE)
     84       self.assertTrue(identifier in results)
     85       if identifier in mock_result:
     86         self.assertTrue(task.GetResult(TEST_STAGE), mock_result[identifier])
     87       results.remove(identifier)
     88 
     89   def testWorker(self):
     90     """"Test the worker method.
     91 
     92     The worker should process all the input tasks and output the tasks to the
     93     helper and result queue.
     94     """
     95 
     96     manager = multiprocessing.Manager()
     97     result_queue = manager.Queue()
     98     completed_queue = manager.Queue()
     99 
    100     # A dictionary defines the mock tasks and their corresponding results.
    101     mock_work_tasks = {1: 86, 2: 788}
    102 
    103     mock_tasks = []
    104 
    105     for flag, cost in mock_work_tasks.iteritems():
    106       mock_tasks.append(MockTask(TEST_STAGE, flag, cost))
    107 
    108     # Submit the mock tasks to the worker.
    109     for mock_task in mock_tasks:
    110       pipeline_worker.Worker(TEST_STAGE, mock_task, completed_queue,
    111                              result_queue)
    112 
    113     # The tasks, from the output queue, should be the same as the input and
    114     # should be performed.
    115     for task in mock_tasks:
    116       output = result_queue.get()
    117       self.assertEqual(output, task)
    118       self.assertTrue(output.Done(TEST_STAGE))
    119 
    120     # The tasks, from the completed_queue, should be defined in the
    121     # mock_work_tasks dictionary.
    122     for flag, cost in mock_work_tasks.iteritems():
    123       helper_input = completed_queue.get()
    124       self.assertEqual(helper_input, (flag, cost))
    125 
    126 
    127 if __name__ == '__main__':
    128   unittest.main()
    129