1# Copyright (C) 2016 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may not
4# use this file except in compliance with the License. You may obtain a copy of
5# the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations under
13# the License.
14import unittest
15import logging
16import os
17import sys
18import tempfile
19import shutil
20from importlib import import_module
21
22from google.protobuf import text_format
23
24from acts.libs.proto.proto_utils import compile_proto
25from acts.libs.proto.proto_utils import compile_import_proto
26
27TEST_PROTO_NAME = "acts_proto_utils_test.proto"
28TEST_PROTO_GENERATED_NAME = "acts_proto_utils_test_pb2"
29TEST_PROTO_DATA_NAME = "acts_proto_utils_test_data.txt"
30TEST_NAME = "test_name"
31TEST_ID = 42
32
33
34class BtMetricsUtilsTest(unittest.TestCase):
35    """This test class has unit tests for the implementation of everything
36    under acts.controllers.android_device.
37    """
38
39    def setUp(self):
40        # Set log_path to logging since acts logger setup is not called.
41        if not hasattr(logging, "log_path"):
42            setattr(logging, "log_path", "/tmp/logs")
43        # Creates a temp dir to be used by tests in this test class.
44        self.tmp_dir = tempfile.mkdtemp()
45
46    def tearDown(self):
47        """Removes the temp dir.
48        """
49        shutil.rmtree(self.tmp_dir)
50
51    def getResource(self, relative_path_to_test):
52        return os.path.join(
53            os.path.dirname(os.path.realpath(__file__)), relative_path_to_test)
54
55    def compare_test_entry(self, entry, name, id, nested):
56        self.assertEqual(entry.name, name)
57        self.assertEqual(entry.id, id)
58        self.assertEqual(len(entry.nested), len(nested))
59        for i in range(len(entry.nested)):
60            self.assertEqual(entry.nested[i].name, nested[i][0])
61            self.assertEqual(entry.nested[i].type, nested[i][1])
62
63    def test_compile_proto(self):
64        proto_path = self.getResource(TEST_PROTO_NAME)
65        output_module_name = compile_proto(proto_path, self.tmp_dir)
66        self.assertIsNotNone(output_module_name)
67        self.assertEqual(output_module_name, TEST_PROTO_GENERATED_NAME)
68        self.assertTrue(
69            os.path.exists(
70                os.path.join(self.tmp_dir, output_module_name) + ".py"))
71        sys.path.append(self.tmp_dir)
72        bt_metrics_utils_test_pb2 = None
73        try:
74            bt_metrics_utils_test_pb2 = import_module(output_module_name)
75        except ImportError:
76            self.fail("Cannot import generated py-proto %s" %
77                      (output_module_name))
78        test_proto = bt_metrics_utils_test_pb2.TestProto()
79        test_proto_entry = test_proto.entries.add()
80        test_proto_entry.id = TEST_ID
81        test_proto_entry.name = TEST_NAME
82        self.assertEqual(test_proto.entries[0].id, TEST_ID)
83        self.assertEqual(test_proto.entries[0].name, TEST_NAME)
84
85    def test_parse_proto(self):
86        proto_path = self.getResource(TEST_PROTO_NAME)
87        output_module = compile_import_proto(self.tmp_dir, proto_path)
88        self.assertIsNotNone(output_module)
89        AAA = output_module.TestProtoEntry.NestedType.AAA
90        BBB = output_module.TestProtoEntry.NestedType.BBB
91        test_proto = output_module.TestProto()
92        proto_data_path = self.getResource(TEST_PROTO_DATA_NAME)
93        self.assertTrue(os.path.exists(proto_data_path))
94        self.assertTrue(os.path.isfile(proto_data_path))
95        with open(proto_data_path) as f:
96            text_format.Merge(f.read(), test_proto)
97        self.assertEqual(len(test_proto.entries), 2)
98        entry1 = test_proto.entries[0]
99        self.compare_test_entry(entry1, "TestName1", 42,
100                                [("NestedA", AAA), ("NestedB", BBB),
101                                 ("NestedA", AAA)])
102        entry2 = test_proto.entries[1]
103        self.compare_test_entry(entry2, "TestName2", 43,
104                                [("NestedB", BBB), ("NestedA", AAA),
105                                 ("NestedB", BBB)])
106