#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""LXD container integration tests."""

from __future__ import print_function

import argparse
import os
import pylxd
import sys
import time
import unittest
import xmlrunner

STOPPED = 102
RUNNING = 103

class LxdTestCase(unittest.TestCase):
  """LxdTestCase includes all test cases for CrOS LXD containers."""
  UNIFIED_TARBALL = 'unified.tar.xz'
  IMAGE_ALIAS = 'lxd_test_image'
  CONTAINER_NAME = 'lxd-test'
  TEST_PROFILE = 'test-profile'
  TEST_USER = 'testuser'

  @classmethod
  def setUpClass(cls):
    cls.client = pylxd.Client()
    cls.image = None
    if cls.client.images.exists(cls.IMAGE_ALIAS, alias=True):
      cls.image = cls.client.images.get_by_alias(cls.IMAGE_ALIAS)
    else:
      with open(cls.UNIFIED_TARBALL, 'rb') as unified_tarball:
        cls.image = cls.client.images.create(unified_tarball)
        cls.image.add_alias(cls.IMAGE_ALIAS, 'lxd test image')
        cls.image.save(wait=True)

    # Profile setup + mocks to bind-mount in.
    cls.profile = None
    if cls.client.profiles.exists(cls.TEST_PROFILE):
      cls.profile = cls.client.profiles.get(cls.TEST_PROFILE)
      cls.profile.delete(wait=True)

    script_dir = os.path.dirname(os.path.abspath(__file__))
    lddtree_dir = os.path.join(script_dir, 'mocks', 'lddtree')
    sshd_dir = os.path.join(script_dir, 'mocks', 'sshd_config')

    cls.profile = cls.client.profiles.create(
        cls.TEST_PROFILE,
        config={
            'boot.autostart': 'false',
            'security.syscalls.blacklist': 'keyctl errno 38'
        },
        devices={
            'root': {
                'path': '/',
                'pool': 'default',
                'type': 'disk',
            },
            'eth0': {
                'nictype': 'bridged',
                'parent': 'lxdbr0',
                'type': 'nic',
            },
            'cros_containers': {
                'source': lddtree_dir,
                'path': '/opt/google/cros-containers',
                'type': 'disk',
            },
            'sshd_config': {
                'source': sshd_dir,
                'path': '/dev/.ssh',
                'type': 'disk',
            },
        })

  @classmethod
  def tearDownClass(cls):
    cls.image.sync()
    cls.image.delete(wait=True)
    cls.profile.sync()
    cls.profile.delete(wait=True)

  def setUp(self):
    if self.client.containers.exists(self.CONTAINER_NAME):
      self.container = self.client.containers.get(self.CONTAINER_NAME)
      if self.container.status_code != STOPPED:
        self.container.stop(wait=True)
      self.container.delete(wait=True)

    self.container = self.client.containers.create(
        {
            'name': self.CONTAINER_NAME,
            'source': {
                'type': 'image',
                'alias': self.IMAGE_ALIAS
            },
            'profiles': [self.TEST_PROFILE],
        },
        wait=True)

  def tearDown(self):
    self.container.sync()
    if self.container.status_code != STOPPED:
      self.container.stop(wait=True)
    self.container.delete(wait=True)

  def test_system_services(self):
    self.container.start(wait=True)
    time.sleep(10)
    self.container.sync()
    self.assertEqual(self.container.status_code, RUNNING)
    ret, _, _ = self.container.execute(
        ['systemctl', 'is-active', 'cros-sftp.service'])
    self.assertEqual(ret, 0)

  def test_user_services_no_gpu(self):
    self.container.start(wait=True)
    time.sleep(10)
    self.assertEqual(self.container.status_code, RUNNING)
    ret, _, _ = self.container.execute(
        ['useradd', '-u', '1000', '-s', '/bin/bash', '-m', self.TEST_USER])
    self.assertEqual(ret, 0)

    groups = [
        'audio', 'cdrom', 'dialout', 'floppy', 'plugdev', 'sudo', 'users',
        'video'
    ]
    for group in groups:
      ret, _, _ = self.container.execute(
          ['usermod', '-aG', group, self.TEST_USER])
      self.assertEqual(ret, 0)

    ret, _, _ = self.container.execute(
        ['loginctl', 'enable-linger', self.TEST_USER])
    self.assertEqual(ret, 0)
    time.sleep(10)

    ret, _, _ = self.container.execute([
        'su', '-c', 'systemctl --user is-active cros-garcon.service',
        self.TEST_USER
    ])
    self.assertEqual(ret, 0)
    ret, _, _ = self.container.execute([
        'su', '-c', 'systemctl --user is-active sommelier@0.service',
        self.TEST_USER
    ])
    self.assertEqual(ret, 0)
    ret, _, _ = self.container.execute([
        'su', '-c', 'systemctl --user is-active sommelier-x@0.service',
        self.TEST_USER
    ])
    self.assertEqual(ret, 0)
    ret, _, _ = self.container.execute([
        'su', '-c',
        'systemctl --user show-environment | grep -q SOMMELIER_GLAMOR',
        self.TEST_USER
    ])
    self.assertEqual(ret, 1)
    ret, _, _ = self.container.execute([
        'su', '-c',
        'systemctl --user show-environment | grep -q SOMMELIER_DRM_DEVICE',
        self.TEST_USER
    ])
    self.assertEqual(ret, 1)

  def test_user_services_gpu(self):
    self.container.start(wait=True)
    self.container.devices.update({
        'renderD128': {
            'major': '226',
            'minor': '128',
            'mode': '0666',
            'path': '/dev/dri/renderD128',
            'type': 'unix-char',
        },
    })
    self.container.save()
    time.sleep(10)
    self.assertEqual(self.container.status_code, RUNNING)
    ret, _, _ = self.container.execute(
        ['useradd', '-u', '1000', '-s', '/bin/bash', '-m', self.TEST_USER])
    self.assertEqual(ret, 0)

    groups = [
        'audio', 'cdrom', 'dialout', 'floppy', 'plugdev', 'sudo', 'users',
        'video'
    ]
    for group in groups:
      ret, _, _ = self.container.execute(
          ['usermod', '-aG', group, self.TEST_USER])
      self.assertEqual(ret, 0)

    ret, _, _ = self.container.execute(
        ['loginctl', 'enable-linger', self.TEST_USER])
    self.assertEqual(ret, 0)
    time.sleep(10)

    ret, _, _ = self.container.execute([
        'su', '-c', 'systemctl --user is-active cros-garcon.service',
        self.TEST_USER
    ])
    self.assertEqual(ret, 0)
    ret, _, _ = self.container.execute([
        'su', '-c', 'systemctl --user is-active sommelier@0.service',
        self.TEST_USER
    ])
    self.assertEqual(ret, 0)
    ret, _, _ = self.container.execute([
        'su', '-c', 'systemctl --user is-active sommelier-x@0.service',
        self.TEST_USER
    ])
    self.assertEqual(ret, 0)
    ret, _, _ = self.container.execute([
        'su', '-c',
        'systemctl --user show-environment | grep -q SOMMELIER_GLAMOR',
        self.TEST_USER
    ])
    self.assertEqual(ret, 0)
    ret, _, _ = self.container.execute([
        'su', '-c',
        'systemctl --user show-environment | grep -q SOMMELIER_DRM_DEVICE',
        self.TEST_USER
    ])
    self.assertEqual(ret, 0)


if __name__ == '__main__':
  if len(sys.argv) != 3:
    print('usage: test.py result_dir unified_tarball')
    sys.exit(1)

  LxdTestCase.UNIFIED_TARBALL = sys.argv.pop()
  result_dir = sys.argv.pop()

  with open(os.path.join(result_dir, 'sponge_log.xml'), 'wb') as output:
    unittest.main(
        testRunner=xmlrunner.XMLTestRunner(output=output),
        failfast=False,
        buffer=False,
        catchbreak=False,
        verbosity=2)
