1#!/usr/bin/env python3
2#
3#   Copyright 2018 - 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 collections
18import json
19import logging
20import math
21import os
22import random
23import re
24import requests
25import socket
26import time
27
28from urllib.parse import urlparse
29
30from acts import utils
31
32
33class DeviceOffline(Exception):
34    """Exception if the device is no longer reachable via the network."""
35
36
37class BaseLib():
38    def __init__(self, addr, tc, client_id):
39        self.address = addr
40        self.test_counter = tc
41        self.client_id = client_id
42
43    def build_id(self, test_id):
44        """Concatenates client_id and test_id to form a command_id.
45
46        Args:
47            test_id: string, unique identifier of test command.
48        """
49        return self.client_id + "." + str(test_id)
50
51    def send_command(self, test_id, test_cmd, test_args, response_timeout=30):
52        """Builds and sends a JSON command to SL4F server.
53
54        Args:
55            test_id: string, unique identifier of test command.
56            test_cmd: string, sl4f method name of command.
57            test_args: dictionary, arguments required to execute test_cmd.
58            response_timeout: int, seconds to wait for a response before
59                throwing an exception. Defaults to no timeout.
60
61        Returns:
62            Dictionary, Result of sl4f command executed.
63        """
64        if not utils.is_pingable(urlparse(self.address).hostname):
65            raise DeviceOffline("FuchsiaDevice %s is not reachable via the "
66                                "network." % urlparse(self.address).hostname)
67        test_data = json.dumps({
68            "jsonrpc": "2.0",
69            "id": test_id,
70            "method": test_cmd,
71            "params": test_args
72        })
73        try:
74            return requests.get(url=self.address,
75                                data=test_data,
76                                timeout=response_timeout).json()
77        except requests.exceptions.Timeout as e:
78            if not utils.is_pingable(urlparse(self.address).hostname):
79                raise DeviceOffline(
80                    "FuchsiaDevice %s is not reachable via the "
81                    "network." % urlparse(self.address).hostname)
82            else:
83                logging.debug(
84                    'FuchsiaDevice %s is online but SL4f call timed out.' %
85                    urlparse(self.address).hostname)
86                raise e
87