# Copyright (C) 2015 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Brillo device `adb` tests.

This module contains some tests exercising `adb` functionality for
Brillo devices. This pulls in some tests from the generic test_device
module, but omits tests which require framework-level functionality not
available on Brillo Tier 1 devices. We also add some additional tests
such as large file transfers and some common operations.

Requirements:
  * Python "unittest" module must be installed.
  * Exactly 1 device must be connected, or the ANDROID_SERIAL
    environment variable must be set to select the desired device.
"""

import os
import subprocess
import tempfile
import unittest

from adb import test_device


def create_data_file(size):
    """Creates a data file of |size| bytes.

    Args:
        size: desired file size in bytes.

    Returns:
        New file name. Caller is responsible for deleting the file.
    """
    temp = tempfile.NamedTemporaryFile('wb', delete=False)
    if size > 0:
        data_str = ''.join(chr(i) for i in range(256)) * 1000
        while len(data_str) < size:
            temp.write(data_str)
            size -= len(data_str)
        temp.write(data_str[:size])
    temp.close()
    return temp.name


class ShellTest(test_device.ShellTest):
    """Basic shell tests imported from test_device."""


class FileTest(test_device.FileOperationsTest):
    """Small file push/pull tests imported from test_device."""

    def test_large_file(self):
        """Tests pushing and pulling a larger file."""
        # Use a 10MB file to test larger push/pull operations.
        f1_name = create_data_file(10 * 1000 * 1000)
        self.device.push(local=f1_name, remote=self.DEVICE_TEMP_FILE)

        f2_name = create_data_file(0)
        self.device.pull(remote=self.DEVICE_TEMP_FILE, local=f2_name)

        if os.name == 'nt':
            file_comp_program = 'fc'
        else:
            file_comp_program = 'cmp'
        subprocess.check_output([file_comp_program, f1_name, f2_name])

        os.remove(f1_name)
        os.remove(f2_name)
        self.device.shell(['rm', '-rf', self.DEVICE_TEMP_DIR])

    def test_pull_error_reporting(self):
      """Skips FileOperationsTest.test_pull_error_reporting().

      test_pull_error_reporting() requires non-root, but currently
      adb doesn't handle rooting and unrooting TCP devices well; it
      will spin forever since the TCP disconnects and makes no attempt
      to reconnect.

      This is the only Brillo test that uses root/unroot functionality
      and it's not critical, so until adb works properly just skip it.
      """
      # TODO(dpursell): re-enable this and add specific root/unroot tests
      # once adb root/unroot works over TCP (http://b/27846794).
      raise unittest.SkipTest('adb [un]root not yet functional for all boards')


class BasicUsageTest(test_device.DeviceTest):
    """Tests some common operations users might perform."""

    def test_logcat(self):
        """Check that logcat gives some output."""
        stdout = subprocess.check_output(self.device.adb_cmd + ['logcat', '-d'])
        self.assertTrue(len(stdout) > 0)

    def test_shell_dmesg(self):
        """Check that `adb shell dmesg` gives some output."""
        stdout, stderr = self.device.shell(['dmesg'])
        self.assertTrue(len(stdout) > 0)
        self.assertTrue(stderr == "")


def suite():
    """Returns the full test suite for this module."""
    return unittest.TestLoader().loadTestsFromName(__name__)
