Merge vk-gl-cts/vulkan-cts-1.1.3 into vk-gl-cts/vulkan-cts-1.1.4
[platform/upstream/VK-GL-CTS.git] / scripts / khr_util / registry_cache.py
1 # -*- coding: utf-8 -*-
2
3 #-------------------------------------------------------------------------
4 # drawElements Quality Program utilities
5 # --------------------------------------
6 #
7 # Copyright 2015-2017 The Android Open Source Project
8 #
9 # Licensed under the Apache License, Version 2.0 (the "License");
10 # you may not use this file except in compliance with the License.
11 # You may obtain a copy of the License at
12 #
13 #      http://www.apache.org/licenses/LICENSE-2.0
14 #
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
20 #
21 #-------------------------------------------------------------------------
22
23 import os
24 import sys
25 import hashlib
26
27 from . import registry
28
29 sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
30
31 from build.common import *
32
33 BASE_URL = ""
34
35 class RegistrySource:
36         def __init__(self, repository, filename, revision, checksum):
37                 self.repository = repository
38                 self.filename   = filename
39                 self.revision   = revision
40                 self.checksum   = checksum
41
42         def __hash__(self):
43                 return hash((self.repository, self.filename, self.revision, self.checksum))
44
45         def __eq__(self, other):
46                 return (self.repository, self.filename, self.revision, self.checksum) == (other.repository, other.filename, other.revision, other.checksum)
47
48         def getFilename (self):
49                 return os.path.basename(self.filename)
50
51         def getCacheFilename (self):
52                 return "r%s-%s" % (self.revision, self.getFilename())
53
54         def getChecksum (self):
55                 return self.checksum
56
57         def getRevision (self):
58                 return self.revision
59
60         def getRepo (self):
61                 return self.repository
62
63         def getRevision (self):
64                 return self.revision
65
66         def getFilename (self):
67                 return self.filename
68
69 def computeChecksum (data):
70         return hashlib.sha256(data.replace('\r','').encode("utf-8")).hexdigest()
71
72 def makeSourceUrl (repository, revision, filename):
73         return "%s/%s/%s" % (repository, revision, filename)
74
75 def checkoutGit (repository, revision, fullDstPath):
76         if not os.path.exists(fullDstPath):
77                 execute(["git", "clone", "--no-checkout", repository, fullDstPath])
78
79         pushWorkingDir(fullDstPath)
80         try:
81                 execute(["git", "fetch", repository, "+refs/heads/*:refs/remotes/origin/*"])
82                 execute(["git", "checkout", revision])
83         finally:
84                 popWorkingDir()
85
86 def checkoutFile (repository, revision, filename, cacheDir):
87         if sys.version_info < (3, 0):
88                 from urllib2 import urlopen
89         else:
90                 from urllib.request import urlopen
91
92         try:
93                 req             = urlopen(makeSourceUrl(repository, revision, filename))
94                 data    = req.read()
95         except IOError:
96                 fullDstPath = os.path.join(cacheDir, "git")
97
98                 checkoutGit(repository, revision, fullDstPath)
99                 f               = open(os.path.join(fullDstPath, filename), "rt")
100                 data    = f.read()
101                 f.close()
102         except:
103                 print(("Unexpected error:", sys.exc_info()[0]))
104
105         return data
106
107 def fetchFile (dstPath, repository, revision, filename, checksum, cacheDir):
108         def writeFile (filename, data):
109                 f = open(filename, 'wt')
110                 f.write(data)
111                 f.close()
112
113         if not os.path.exists(os.path.dirname(dstPath)):
114                 os.makedirs(os.path.dirname(dstPath))
115
116         print(("Fetching %s/%s@%s" % (repository, filename, revision)))
117         data            = checkoutFile(repository, revision, filename, cacheDir)
118         gotChecksum     = computeChecksum(data)
119
120         if checksum != gotChecksum:
121                 raise Exception("Checksum mismatch, expected %s, got %s" % (checksum, gotChecksum))
122
123         writeFile(dstPath, data)
124
125 def checkFile (filename, checksum):
126         def readFile (filename):
127                 f = open(filename, 'rt')
128                 data = f.read()
129                 f.close()
130                 return data
131
132         if os.path.exists(filename):
133                 return computeChecksum(readFile(filename)) == checksum
134         else:
135                 return False
136
137 g_registryCache = {}
138
139 def getRegistry (source):
140         global g_registryCache
141
142         if source in g_registryCache:
143                 return g_registryCache[source]
144
145         cacheDir        = os.path.join(os.path.dirname(__file__), "cache")
146         cachePath       = os.path.join(cacheDir, source.getCacheFilename())
147
148         if not checkFile(cachePath, source.checksum):
149                 fetchFile(cachePath, source.getRepo(), source.getRevision(), source.getFilename(), source.getChecksum(), cacheDir)
150
151         parsedReg       = registry.parse(cachePath)
152
153         g_registryCache[source] = parsedReg
154
155         return parsedReg