• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3#   Copyright 2019 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17import functools
18import inspect
19
20from mobly import asserts
21
22from blueberry.tests.gd.cert.test_decorators import test_info
23
24
25def _fail_decorator(msg):
26
27    def fail_decorator(func):
28
29        @functools.wraps(func)
30        def fail(*args, **kwargs):
31            asserts.fail(msg)
32
33        return fail
34
35    return fail_decorator
36
37
38def metadata(_do_not_use=None, pts_test_id=None, pts_test_name=None):
39    """
40    Record a piece of test metadata in the Extra section of the test Record in
41    the test summary file. The metadata will come with a timestamp, but there
42    is no guarantee on the order of when the metadata will be written
43
44    Note:
45    - Metadata is recorded per test case as key-value pairs.
46    - Metadata is only guaranteed to be written when the test result is PASS,
47      FAIL or SKIPPED. When there are test infrastructural errors, metadata
48      might not be written successfully
49    :param _do_not_use: a positional argument with default value. This argument
50                        is to ensure that @metadata(key=value) is used in a
51                        functional form instead of @metadata or @metadata(a)
52    :param pts_test_id: A fully qualified PTS test ID such as
53                        L2CAP/COS/IEX/BV-01-C
54    :param pts_test_name: A human readable test name such as
55                          "Request Connection" for the above example
56    :return: decorated test case function object
57    """
58    if _do_not_use is not None:
59
60        def fail(*args, **kwargs):
61            asserts.fail("@metadata must be used in functional form such " "as @metadta(key=value)")
62
63        return fail
64
65    # Create a dictionary of optional parameters
66    values = locals()
67    args = {arg: values[arg] for arg in inspect.getfullargspec(metadata).args}
68    del args["_do_not_use"]
69
70    # Check if at least one optional parameter is valid
71    if not any(args.values()):
72        return _fail_decorator("at least one optional argument should be valid")
73
74    # Validate pts_test_id and pts_test_name
75    if any((pts_test_id, pts_test_name)) and \
76            not all((pts_test_id, pts_test_name)):
77        return _fail_decorator("pts_test_id and pts_test_name must both " "be valid if one of them is valid")
78
79    return test_info(**args)
80