# Copyright 2010-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

"""Tests for the portage.util._xattr module"""

from __future__ import print_function

try:
	# Try python-3.3 module first.
	# pylint: disable=no-name-in-module
	from unittest import mock
except ImportError:
	try:
		# Try standalone module.
		import mock
	except ImportError:
		mock = None

import subprocess

import portage
from portage.tests import TestCase
from portage.util._xattr import (xattr as _xattr, _XattrSystemCommands,
                                 _XattrStub)


orig_popen = subprocess.Popen
def MockSubprocessPopen(stdin):
	"""Helper to mock (closely) a subprocess.Popen call

	The module has minor tweaks in behavior when it comes to encoding and
	python versions, so use a real subprocess.Popen call to fake out the
	runtime behavior.  This way we don't have to also implement different
	encodings as that gets ugly real fast.
	"""
	# pylint: disable=protected-access
	proc = orig_popen(['cat'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
	proc.stdin.write(portage._unicode_encode(stdin, portage._encodings['stdio']))
	return proc


class SystemCommandsTest(TestCase):
	"""Test _XattrSystemCommands"""

	OUTPUT = '\n'.join((
		'# file: /bin/ping',
		'security.capability=0sAQAAAgAgAAAAAAAAAAAAAAAAAAA=',
		'user.foo="asdf"',
		'',
	))

	def _setUp(self):
		if mock is None:
			self.skipTest('need mock for testing')

		return _XattrSystemCommands

	def _testGetBasic(self):
		"""Verify the get() behavior"""
		xattr = self._setUp()
		with mock.patch.object(subprocess, 'Popen') as call_mock:
			# Verify basic behavior, and namespace arg works as expected.
			xattr.get('/some/file', 'user.foo')
			xattr.get('/some/file', 'foo', namespace='user')
			self.assertEqual(call_mock.call_args_list[0], call_mock.call_args_list[1])

			# Verify nofollow behavior.
			call_mock.reset()
			xattr.get('/some/file', 'user.foo', nofollow=True)
			self.assertIn('-h', call_mock.call_args[0][0])

	def testGetParsing(self):
		"""Verify get() parses output sanely"""
		xattr = self._setUp()
		with mock.patch.object(subprocess, 'Popen') as call_mock:
			# Verify output parsing.
			call_mock.return_value = MockSubprocessPopen('\n'.join([
				'# file: /some/file',
				'user.foo="asdf"',
				'',
			]))
			call_mock.reset()
			self.assertEqual(xattr.get('/some/file', 'user.foo'), b'"asdf"')

	def testGetAllBasic(self):
		"""Verify the get_all() behavior"""
		xattr = self._setUp()
		with mock.patch.object(subprocess, 'Popen') as call_mock:
			# Verify basic behavior.
			xattr.get_all('/some/file')

			# Verify nofollow behavior.
			call_mock.reset()
			xattr.get_all('/some/file', nofollow=True)
			self.assertIn('-h', call_mock.call_args[0][0])

	def testGetAllParsing(self):
		"""Verify get_all() parses output sanely"""
		xattr = self._setUp()
		with mock.patch.object(subprocess, 'Popen') as call_mock:
			# Verify output parsing.
			call_mock.return_value = MockSubprocessPopen(self.OUTPUT)
			exp = [
				(b'security.capability', b'0sAQAAAgAgAAAAAAAAAAAAAAAAAAA='),
				(b'user.foo', b'"asdf"'),
			]
			self.assertEqual(exp, xattr.get_all('/some/file'))

	def testSetBasic(self):
		"""Verify the set() behavior"""
		xattr = self._setUp()
		with mock.patch.object(subprocess, 'Popen') as call_mock:
			# Verify basic behavior, and namespace arg works as expected.
			xattr.set('/some/file', 'user.foo', 'bar')
			xattr.set('/some/file', 'foo', 'bar', namespace='user')
			self.assertEqual(call_mock.call_args_list[0], call_mock.call_args_list[1])

	def testListBasic(self):
		"""Verify the list() behavior"""
		xattr = self._setUp()
		with mock.patch.object(subprocess, 'Popen') as call_mock:
			# Verify basic behavior.
			xattr.list('/some/file')

			# Verify nofollow behavior.
			call_mock.reset()
			xattr.list('/some/file', nofollow=True)
			self.assertIn('-h', call_mock.call_args[0][0])

	def testListParsing(self):
		"""Verify list() parses output sanely"""
		xattr = self._setUp()
		with mock.patch.object(subprocess, 'Popen') as call_mock:
			# Verify output parsing.
			call_mock.return_value = MockSubprocessPopen(self.OUTPUT)
			exp = [b'security.capability', b'user.foo']
			self.assertEqual(exp, xattr.list('/some/file'))

	def testRemoveBasic(self):
		"""Verify the remove() behavior"""
		xattr = self._setUp()
		with mock.patch.object(subprocess, 'Popen') as call_mock:
			# Verify basic behavior, and namespace arg works as expected.
			xattr.remove('/some/file', 'user.foo')
			xattr.remove('/some/file', 'foo', namespace='user')
			self.assertEqual(call_mock.call_args_list[0], call_mock.call_args_list[1])

			# Verify nofollow behavior.
			call_mock.reset()
			xattr.remove('/some/file', 'user.foo', nofollow=True)
			self.assertIn('-h', call_mock.call_args[0][0])


class StubTest(TestCase):
	"""Test _XattrStub"""

	def testBasic(self):
		"""Verify the stub is stubby"""
		# Would be nice to verify raised errno is OperationNotSupported.
		self.assertRaises(OSError, _XattrStub.get, '/', '')
		self.assertRaises(OSError, _XattrStub.set, '/', '', '')
		self.assertRaises(OSError, _XattrStub.get_all, '/')
		self.assertRaises(OSError, _XattrStub.remove, '/', '')
		self.assertRaises(OSError, _XattrStub.list, '/')


class StandardTest(TestCase):
	"""Test basic xattr API"""

	MODULES = (_xattr, _XattrSystemCommands, _XattrStub)
	FUNCS = ('get', 'get_all', 'set', 'remove', 'list')

	def testApi(self):
		"""Make sure the exported API matches"""
		for mod in self.MODULES:
			for f in self.FUNCS:
				self.assertTrue(hasattr(mod, f),
					'%s func missing in %s' % (f, mod))
