Browse code

Added support in build system to recognize/install specific build time required packages which are required only when check is enabled.

Example:
In rpm spec file, use "with_check" macro to add additional buildrequires which are required for check
%if %{with_check}
BuildRequires: python-py
BuildRequires: python-pytest
%endif

Change-Id: I035825557a81e8ebeecbfaed4906d02d322e0986
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/3248
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Alexey Makhalov <amakhalov@vmware.com>

dthaluru authored on 2017/07/15 03:49:55
Showing 6 changed files
... ...
@@ -108,8 +108,10 @@ class PackageBuilder(object):
108 108
             listInstalledPackages=self.findInstalledPackages(chrootID)
109 109
             listDependentPackages=self.findBuildTimeRequiredPackages(package)
110 110
             if constants.rpmCheck and package in constants.testForceRPMS:
111
+                listDependentPackages.extend(self.findBuildTimeCheckRequiredPackages(package))
111 112
                 testPackages=set(constants.listMakeCheckRPMPkgtoInstall)-set(listInstalledPackages)-set([package])
112 113
                 listDependentPackages.extend(testPackages)
114
+                listDependentPackages=list(set(listDependentPackages))
113 115
 
114 116
             pkgUtils = PackageUtils(self.logName,self.logPath)
115 117
             if len(listDependentPackages) != 0:
... ...
@@ -141,6 +143,10 @@ class PackageBuilder(object):
141 141
         listRequiredPackages=constants.specData.getBuildRequiresForPackage(package)
142 142
         return listRequiredPackages
143 143
 
144
+    def findBuildTimeCheckRequiredPackages(self,package):
145
+        listRequiredPackages=constants.specData.getCheckBuildRequiresForPackage(package)
146
+        return listRequiredPackages
147
+
144 148
     def installPackage(self,pkgUtils,package,chrootID,destLogPath,listInstalledPackages):
145 149
         if package in listInstalledPackages:
146 150
             return
... ...
@@ -11,6 +11,7 @@ class SerializableSpecObject(object):
11 11
         self.version=""
12 12
         self.release=""
13 13
         self.buildRequirePackages=[]
14
+        self.checkBuildRequirePackages=[]
14 15
         self.installRequiresAllPackages=[]
15 16
         self.installRequiresPackages={}
16 17
         self.specFile=""
... ...
@@ -42,6 +43,7 @@ class SerializableSpecObjectsUtils(object):
42 42
             specObj.name=specName
43 43
             specObj.buildRequirePackages=spec.getBuildRequiresAllPackages()
44 44
             specObj.installRequiresAllPackages=spec.getRequiresAllPackages()
45
+            specObj.checkBuildRequirePackages=spec.getCheckBuildRequiresAllPackages()
45 46
             specObj.listPackages=spec.getPackageNames()
46 47
             specObj.specFile=specFile
47 48
             specObj.version=spec.getVersion()
... ...
@@ -90,6 +92,10 @@ class SerializableSpecObjectsUtils(object):
90 90
             return self.mapSerializableSpecObjects[specName].installRequiresPackages[package]
91 91
         return None
92 92
 
93
+    def getCheckBuildRequiresForPackage(self, package):
94
+        specName=self.getSpecName(package)
95
+        return self.mapSerializableSpecObjects[specName].checkBuildRequirePackages
96
+
93 97
     def addMacro(self, macroName, macroValue):
94 98
         if macroName == "":
95 99
             self.logger.error("Given invalid macro: name:"+macroName+" value:"+macroValue)
... ...
@@ -14,6 +14,7 @@ class SpecParser(object):
14 14
         self.specAdditionalContent=""
15 15
         self.globalSecurityHardening=""
16 16
         self.defs={}
17
+        self.conditionalCheckMacroEnabled = False
17 18
 
18 19
 
19 20
     def readPkgNameFromPackageMacro(self,data,basePkgName=None):
... ...
@@ -74,6 +75,10 @@ class SpecParser(object):
74 74
                 self.readChecksum(line, self.packages[currentPkg])
75 75
             elif self.isDefinition(line):
76 76
                 self.readDefinition(line)
77
+            elif self.isConditionalCheckMacro(line):
78
+                self.conditionalCheckMacroEnabled = True
79
+            elif self.conditionalCheckMacroEnabled and self.isConditionalMacroCompleted(line):
80
+                self.conditionalCheckMacroEnabled = False
77 81
             else:
78 82
                 self.specAdditionalContent+=line+"\n"
79 83
             i=i+1
... ...
@@ -327,7 +332,10 @@ class SpecParser(object):
327 327
             if headerName == 'conflicts':
328 328
                 pkg.conflicts.extend(dpkg)
329 329
             if headerName == 'buildrequires':
330
-                pkg.buildrequires.extend(dpkg)
330
+                if self.conditionalCheckMacroEnabled:
331
+                    pkg.checkbuildrequires.extend(dpkg)
332
+                else:
333
+                    pkg.buildrequires.extend(dpkg)
331 334
             if headerName == 'buildprovides':
332 335
                 pkg.buildprovides.extend(dpkg)
333 336
 
... ...
@@ -373,3 +381,23 @@ class SpecParser(object):
373 373
             return False
374 374
         pkg.checksums[sourceName] = value[1]
375 375
         return True;
376
+
377
+    def isConditionalCheckMacro(self,line):
378
+        data = line.strip()
379
+        words = data.split()
380
+        nrWords = len(words)
381
+        if(nrWords != 2):
382
+            return False
383
+        if(words[0] != "%if" or words[1] != "%{with_check}"):
384
+            return False
385
+        return True
386
+
387
+    def isConditionalMacroCompleted(self,line):
388
+        data = line.strip()
389
+        words = data.split()
390
+        nrWords = len(words)
391
+        if(nrWords != 1):
392
+            return False
393
+        if(words[0] != "%endif"):
394
+            return False
395
+        return True
... ...
@@ -9,18 +9,18 @@ class rpmMacro(object):
9 9
 
10 10
     def setName(self,name):
11 11
         self.macroName=name
12
-        
12
+
13 13
     def displayMacro(self):
14 14
         print "Macro:\n", self.macroName, " ",self.macroFlag," ",self.position," ",self.endposition
15 15
         print self.content
16
-    
16
+
17 17
 class dependentPackageData(object):
18 18
 
19 19
     def __init__(self):
20 20
         self.package=""
21 21
         self.version=""
22 22
         self.compare=""
23
-        
23
+
24 24
 class Package(object):
25 25
     def __init__(self, basePkg=None):
26 26
         self.summary=""
... ...
@@ -33,25 +33,26 @@ class Package(object):
33 33
         self.distribution="Photon"
34 34
         self.basePkgName=""
35 35
         self.URL=""
36
-        
36
+
37 37
         self.sources=[]
38 38
         self.checksums={}
39 39
         self.patches=[]
40 40
         self.buildrequires=[]
41 41
         self.buildprovides=[]
42
-        
43
-        
42
+        self.checkbuildrequires=[]
43
+
44
+
44 45
         self.requires=[]
45 46
         self.provides=[]
46 47
         self.obsoletes=[]
47 48
         self.conflicts=[]
48
-        
49
+
49 50
         self.descriptionMacro= None
50 51
         self.postMacro=None
51 52
         self.postunMacro=None
52 53
         self.filesMacro=None
53 54
         self.packageMacro=None
54
-        
55
+
55 56
         if basePkg is not None:
56 57
             self.basePkgName=basePkg.name
57 58
             self.group=basePkg.group
... ...
@@ -60,22 +61,22 @@ class Package(object):
60 60
             self.buildarch=basePkg.buildarch
61 61
             self.release=basePkg.release
62 62
             self.distribution=basePkg.distribution
63
-        
63
+
64 64
     def decodeContents(self,content):
65 65
         if content.find("%{name}") != -1:
66 66
             if self.basePkgName == "":
67 67
                 content = content.replace('%{name}',self.name)
68 68
             else:
69 69
                 content = content.replace('%{name}',self.basePkgName)
70
-        
70
+
71 71
         if content.find("%{release}") != -1:
72 72
             content = content.replace('%{release}',self.release)
73
-        
73
+
74 74
         if content.find("%{version}") != -1:
75 75
             content = content.replace('%{version}',self.version)
76
-        
76
+
77 77
         return content
78
-    
78
+
79 79
     def updatePackageMacro(self,macro):
80 80
         if macro.macroName == "%post":
81 81
             self.postMacro=macro
... ...
@@ -142,31 +142,39 @@ class Specutils(object):
142 142
         return buildArch
143 143
 
144 144
     def getRequiresAllPackages(self):
145
-        depedentPackages=[]
145
+        dependentPackages=[]
146 146
         for key in self.spec.packages.keys():
147 147
             pkg = self.spec.packages.get(key)
148 148
             for dpkg in pkg.requires:
149
-                depedentPackages.append(dpkg.package)
150
-        depedentPackages=list(set(depedentPackages))
149
+                dependentPackages.append(dpkg.package)
150
+        dependentPackages=list(set(dependentPackages))
151 151
         packageNames=self.getPackageNames()
152 152
         for pkgName in packageNames:
153
-            if pkgName in depedentPackages:
154
-                depedentPackages.remove(pkgName)
155
-        return depedentPackages
153
+            if pkgName in dependentPackages:
154
+                dependentPackages.remove(pkgName)
155
+        return dependentPackages
156 156
 
157 157
     def getBuildRequiresAllPackages(self):
158
-        depedentPackages=[]
158
+        dependentPackages=[]
159 159
         for key in self.spec.packages.keys():
160 160
             pkg = self.spec.packages.get(key)
161 161
             for dpkg in pkg.buildrequires:
162
-                depedentPackages.append(dpkg.package)
163
-        depedentPackages=list(set(depedentPackages))
162
+                dependentPackages.append(dpkg.package)
163
+        dependentPackages=list(set(dependentPackages))
164 164
         packageNames=self.getPackageNames()
165 165
         for pkgName in packageNames:
166
-            if pkgName in depedentPackages:
167
-                depedentPackages.remove(pkgName)
168
-        return depedentPackages
166
+            if pkgName in dependentPackages:
167
+                dependentPackages.remove(pkgName)
168
+        return dependentPackages
169 169
 
170
+    def getCheckBuildRequiresAllPackages(self):
171
+        dependentPackages=[]
172
+        for key in self.spec.packages.keys():
173
+            pkg = self.spec.packages.get(key)
174
+            for dpkg in pkg.checkbuildrequires:
175
+                dependentPackages.append(dpkg.package)
176
+        dependentPackages=list(set(dependentPackages))
177
+        return dependentPackages
170 178
 
171 179
     def getRequires(self,pkgName):
172 180
         dependentPackages=[]
... ...
@@ -186,8 +194,17 @@ class Specutils(object):
186 186
                     dependentPackages.append(dpkg.package)
187 187
         return dependentPackages
188 188
 
189
+    def getCheckBuildRequires(self,pkgName):
190
+        dependentPackages=[]
191
+        for key in self.spec.packages.keys():
192
+            pkg = self.spec.packages.get(key)
193
+            if pkg.name == pkgName:
194
+                for dpkg in pkg.checkbuildrequires:
195
+                    dependentPackages.append(dpkg.package)
196
+        return dependentPackages
197
+
189 198
     def getProvides(self,packageName):
190
-        depedentPackages=[]
199
+        dependentPackages=[]
191 200
         defaultPkgName=self.spec.packages['default'].name
192 201
         pkg = None
193 202
         if self.spec.packages.has_key(packageName):
... ...
@@ -196,10 +213,10 @@ class Specutils(object):
196 196
             pkg=self.spec.packages['default']
197 197
         if pkg is not None:
198 198
             for dpkg in pkg.provides:
199
-                depedentPackages.append(dpkg.package)
199
+                dependentPackages.append(dpkg.package)
200 200
         else:
201 201
             print "package not found"
202
-        return depedentPackages
202
+        return dependentPackages
203 203
 
204 204
     def getVersion(self):
205 205
         pkg = self.spec.packages.get('default')
... ...
@@ -325,14 +325,14 @@ class constants(object):
325 325
         constants.specData.readSpecsAndConvertToSerializableObjects(constants.specPath)
326 326
         constants.pullsourcesConfig = options.pullsourcesConfig
327 327
         constants.inputRPMSPath=options.inputRPMSPath
328
-        constants.updateRPMMacros()
329 328
         constants.testForceRPMS=[]
330 329
         constants.rpmCheck = options.rpmCheck
331 330
         constants.rpmCheckStopOnError = options.rpmCheckStopOnError
332
-	constants.publishBuildDependencies=options.publishBuildDependencies
333
-	constants.packageWeightsPath=options.packageWeightsPath
331
+        constants.publishBuildDependencies=options.publishBuildDependencies
332
+        constants.packageWeightsPath=options.packageWeightsPath
334 333
         if constants.rpmCheck:
335 334
             constants.testLogger=Logger.getLogger("MakeCheckTest",constants.logPath)
335
+        constants.updateRPMMacros()
336 336
 
337 337
     @staticmethod
338 338
     def updateRPMMacros():
... ...
@@ -367,6 +367,12 @@ class constants(object):
367 367
             kernelsubrelease = "."+kernelsubrelease
368 368
             constants.specData.addMacro("kernelsubrelease",kernelsubrelease)
369 369
 
370
+        #adding check rpm macro
371
+        if constants.rpmCheck:
372
+            constants.specData.addMacro("with_check","1")
373
+        else:
374
+            constants.specData.addMacro("with_check","0")
375
+
370 376
     @staticmethod
371 377
     def setTestForceRPMS(listsPackages):
372 378
          constants.testForceRPMS=listsPackages