aboutsummaryrefslogtreecommitdiff
blob: 3f34ca729a37dcf5f7319c5456ff14fe78246a1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#	vim:fileencoding=utf-8
# (c) 2011-2012 Michał Górny <mgorny@gentoo.org>
# Released under the terms of the 2-clause BSD license.

from .case import EbuildTestCase, AssertionResult
from .eclass_case import EclassTestCase

class DepWrappedAssertion(AssertionResult):
	"""
	Assertion which have occured in a dependency ebuild.

	It basically wraps the original assertion, adding a prefix.
	"""

	def __init__(self, assertion, prefix):
		self._assert = assertion
		self._prefix = prefix

	@property
	def name(self):
		return '[%s] %s' % (self._prefix, self._assert.name)

	@property
	def prefix(self):
		return self._prefix

	@property
	def unprefixed_name(self):
		return self._assert.name

	@property
	def undefined(self):
		return self._assert.undefined

	@property
	def expected(self):
		return self._assert.expected

	@property
	def actual(self):
		return self._assert.actual

	def __bool__(self):
		return bool(self._assert)

	def __str__(self):
		return str(self._assert)

class BaseDependencyTestCase(object):
	"""
	@cvar depend_classes: classes for C{DEPEND} generation
	@type depend_classes: iterable(L{EbuildTestCase})
	@cvar rdepend_classes: classes for C{RDEPEND} generation
	@type rdepend_classes: iterable(L{EbuildTestCase})
	@cvar pdepend_classes: classes for C{PDEPEND} generation
	@type pdepend_classes: iterable(L{EbuildTestCase})
	"""

	depend_classes = []
	rdepend_classes = []
	pdepend_classes = []

	def __init__(self, *args, **kwargs):
		"""
		Instantiate the dependency test case and dependant sub-cases. Set
		C{DEPEND}, C{RDEPEND} and C{PDEPEND}.
		"""

		self.dependant_ebuilds = []

		for class_list, v in ((self.depend_classes, 'DEPEND'),
				(self.rdepend_classes, 'RDEPEND'),
				(self.pdepend_classes, 'PDEPEND')):
			if v not in self.ebuild_vars:
				self.ebuild_vars[v] = ''

			for i, d in enumerate(class_list):
				o = d(*args, **kwargs)
				o._dep_prefix = '%s %d' % (v[:-3], i)
				self.ebuild_vars[v] += '\n\t=%s' % o.cpv
				self.dependant_ebuilds.append(o)

	def clean(self, pm):
		for o in self.dependant_ebuilds:
			o.clean(pm)

	def _append_output_files(self, of):
		for o in self.dependant_ebuilds:
			of.update(o.get_output_files())

	def check_result(self, pm):
		for o in self.dependant_ebuilds:
			o.check_result(pm)
			self.assertions.extend([DepWrappedAssertion(x, o._dep_prefix)
				for x in o.assertions])

class EbuildDependencyTestCase(BaseDependencyTestCase, EbuildTestCase):
	"""
	Test case utilizing multiple ebuilds in order to check dependency
	resolution.

	In order to perform a dependency test, please:

		1. create EbuildTestCase subclasses for the dependencies like usual,
		2. create EbuildDependencyTestCase and refer to the classes created
		above in depend_classes or rdepend_classes.

	The class is going to set up all ebuilds, DEPEND and RDEPEND automagically.
	However, you need to provide phase functions to perform the actual
	dependency test (i.e. check whether the dependency was merged successfully).
	"""

	def __init__(self, *args, **kwargs):
		EbuildTestCase.__init__(self, *args, **kwargs)
		BaseDependencyTestCase.__init__(self, *args, **kwargs)

	def clean(self, pm):
		EbuildTestCase.clean(self, pm)
		BaseDependencyTestCase.clean(self, pm)

	def get_output_files(self):
		of = EbuildTestCase.get_output_files(self)
		BaseDependencyTestCase._append_output_files(self, of)
		return of

	def check_result(self, pm):
		try:
			BaseDependencyTestCase.check_result(self, pm)
		except AssertionError as e:
			exc = e
		else:
			exc = None

		EbuildTestCase.check_result(self, pm)

		if exc is not None:
			raise exc

class EclassDependencyTestCase(BaseDependencyTestCase, EclassTestCase):
	"""
	Test case utilizing multiple ebuilds in order to check dependency
	resolution in an eclass.

	In order to perform a dependency test, please:

		1. create EbuildTestCase subclasses for the dependencies like usual,
		2. create EclassDependencyTestCase and refer to the classes created
		above in depend_classes, rdepend_classes and eclass_*.

	The class is going to set up all ebuilds, DEPEND and RDEPEND automagically.
	However, you need to provide phase functions to perform the actual
	dependency test (i.e. check whether the dependency was merged successfully).

	@cvar eclass_depend_classes: classes for eclass DEPEND generation
	@type eclass_depend_classes: iterable(L{EbuildTestCase})
	@cvar eclass_rdepend_classes: classes for eclass RDEPEND generation
	@type eclass_rdepend_classes: iterable(L{EbuildTestCase})
	@cvar eclass_pdepend_classes: classes for eclass PDEPEND generation
	@type eclass_pdepend_classes: iterable(L{EbuildTestCase})
	"""

	eclass_depend_classes = []
	eclass_rdepend_classes = []
	eclass_pdepend_classes = []

	def __init__(self, *args, **kwargs):
		"""
		Instantiate the dependency test case and dependant sub-cases. Set
		C{DEPEND}, C{RDEPEND} and C{PDEPEND}.
		"""

		EclassTestCase.__init__(self, *args, **kwargs)
		BaseDependencyTestCase.__init__(self, *args, **kwargs)

		for class_list, v in ((self.eclass_depend_classes, 'DEPEND'),
				(self.eclass_rdepend_classes, 'RDEPEND'),
				(self.eclass_pdepend_classes, 'PDEPEND')):

			ev = ''
			for i, d in enumerate(class_list):
				o = d(*args, **kwargs)
				o._dep_prefix = 'eclass %s %d' % (v[:-3], i)
				ev += '\n\t=%s' % o.cpv
				self.dependant_ebuilds.append(o)
			self.eclass_contents = '%s="%s"\n%s' % (v, ev,
					self.eclass_contents)

	def clean(self, pm):
		EclassTestCase.clean(self, pm)
		BaseDependencyTestCase.clean(self, pm)

	def get_output_files(self):
		of = EclassTestCase.get_output_files(self)
		BaseDependencyTestCase._append_output_files(self, of)
		return of

	def check_result(self, pm):
		try:
			BaseDependencyTestCase.check_result(self, pm)
		except AssertionError as e:
			exc = e
		else:
			exc = None

		EclassTestCase.check_result(self, pm)

		if exc is not None:
			raise exc