Home | History | Annotate | Download | only in tester_feedback
      1 # Copyright 2016 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 
      5 """Feedback query delegate interfaces and implementation registry."""
      6 
      7 import multiprocessing
      8 
      9 import common
     10 from autotest_lib.client.common_lib.feedback import client
     11 
     12 
     13 # Mapping of query identifiers to delegate classes.
     14 _query_delegate_registry = {}
     15 
     16 
     17 class _QueryDelegate(object):
     18     """A base class for query delegates."""
     19 
     20     _query_count = multiprocessing.Value('d', 0)
     21 
     22     def __init__(self, test, dut, multiplexer, atomic=True):
     23         """Constructs the delegate.
     24 
     25         @param test: The name of the test.
     26         @param dut: The name of the DUT.
     27         @param multiplexer: Feedback request multiplexer object.
     28         @param atomic: Whether this is an atomic query.
     29         """
     30         super(_QueryDelegate, self).__init__()
     31         self.test = test
     32         self.dut = dut
     33         self._multiplexer = multiplexer
     34         self._atomic = atomic
     35 
     36         # Assign a unique query number.
     37         with self._query_count.get_lock():
     38             self._query_num = self._query_count.value
     39             self._query_count.value += 1
     40 
     41 
     42     def _process_request(self, req):
     43         """Submits a given request to the multiplexer for processing."""
     44         return self._multiplexer.process_request(req, self._query_num,
     45                                                  self._atomic)
     46 
     47 
     48     def prepare(self, **kwargs):
     49         """Delegate for a query's prepare() method."""
     50         return self._prepare_impl(**kwargs)
     51 
     52 
     53     def _prepare_impl(self, **kwargs):
     54         """Concrete implementation of the query's prepare() call."""
     55         raise NotImplementedError
     56 
     57 
     58     def validate(self, **kwargs):
     59         """Delegate for a query's validate() method.
     60 
     61         This clears the atomic sequence with the multiplexer to make sure it
     62         isn't blocked waiting for more requests from this query.
     63         """
     64         try:
     65             return self._validate_impl(**kwargs)
     66         finally:
     67             if self._atomic:
     68                 self._multiplexer.end_atomic_seq(self._query_num)
     69 
     70 
     71     def _validate_impl(self, **kwargs):
     72         """Concrete implementation of the query's validate() call."""
     73         raise NotImplementedError
     74 
     75 
     76 class OutputQueryDelegate(_QueryDelegate):
     77     """A base class for output query delegates."""
     78 
     79 
     80 class InputQueryDelegate(_QueryDelegate):
     81     """A base class for input query delegates."""
     82 
     83     def emit(self):
     84         """Delegate for an input query's emit() method."""
     85         return self._emit_impl()
     86 
     87 
     88     def _emit_impl(self):
     89         """Concrete implementation of the query's emit() call."""
     90         raise NotImplementedError
     91 
     92 
     93 def register_delegate_cls(query_id, delegate_cls):
     94     """Registers a delegate class with a given query identifier.
     95 
     96     @param query_id: Query identifier constant.
     97     @param delegate_cls: The class implementing a delegate for this query.
     98     """
     99     _query_delegate_registry[query_id] = delegate_cls
    100 
    101 
    102 def get_delegate_cls(query_id):
    103     """Returns a query delegate class for a given query type.
    104 
    105     @param query_id: A query type identifier.
    106 
    107     @return A query delegate class.
    108 
    109     @raise ValueError: Unknown query type.
    110     @raise NotImplementedError: Query type not supported.
    111     """
    112     if query_id not in client.ALL_QUERIES:
    113         raise ValueError
    114     if query_id not in _query_delegate_registry:
    115         raise NotImplementedError
    116     return _query_delegate_registry[query_id]
    117