9c61a0461857d450ececd1e29866de7bca12ebf4
[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         dataFiltered = data.replace('\r','')
71         hash = hashlib.sha256(dataFiltered.encode("utf-8")).hexdigest()
72         return hash
73
74 def makeSourceUrl (repository, revision, filename):
75         return "%s/%s/%s" % (repository, revision, filename)
76
77 def checkoutGit (repository, revision, fullDstPath):
78         if not os.path.exists(fullDstPath):
79                 execute(["git", "clone", "--no-checkout", repository, fullDstPath])
80
81         pushWorkingDir(fullDstPath)
82         try:
83                 execute(["git", "fetch", repository, "+refs/heads/*:refs/remotes/origin/*"])
84                 execute(["git", "checkout", revision])
85         finally:
86                 popWorkingDir()
87
88 def checkoutFile (repository, revision, filename, cacheDir):
89         if sys.version_info < (3, 0):
90                 from urllib2 import urlopen
91         else:
92                 from urllib.request import urlopen
93
94         try:
95                 req             = urlopen(makeSourceUrl(repository, revision, filename))
96                 data    = req.read()
97                 if sys.version_info >= (3, 0):
98                         data    = data.decode("utf-8")
99         except IOError:
100                 fullDstPath = os.path.join(cacheDir, "git")
101
102                 checkoutGit(repository, revision, fullDstPath)
103                 f               = open(os.path.join(fullDstPath, filename), "rt")
104                 data    = f.read()
105                 f.close()
106         except:
107                 print("Unexpected error:", sys.exc_info()[0])
108
109         return data
110
111 def fetchFile (dstPath, repository, revision, filename, checksum, cacheDir):
112         def writeFile (filename, data):
113                 f = open(filename, 'wt')
114                 f.write(data)
115                 f.close()
116
117         if not os.path.exists(os.path.dirname(dstPath)):
118                 os.makedirs(os.path.dirname(dstPath))
119
120         print("Fetching %s/%s@%s" % (repository, filename, revision))
121         data            = checkoutFile(repository, revision, filename, cacheDir)
122         gotChecksum     = computeChecksum(data)
123
124         if checksum != gotChecksum:
125                 raise Exception("Checksum mismatch, expected %s, got %s" % (checksum, gotChecksum))
126
127         writeFile(dstPath, data)
128
129 def checkFile (filename, checksum):
130         def readFile (filename):
131                 f = open(filename, 'rt')
132                 data = f.read()
133                 f.close()
134                 return data
135
136         if os.path.exists(filename):
137                 return computeChecksum(readFile(filename)) == checksum
138         else:
139                 return False
140
141 g_registryCache = {}
142
143 def getRegistry (source):
144         global g_registryCache
145
146         if source in g_registryCache:
147                 return g_registryCache[source]
148
149         cacheDir        = os.path.join(os.path.dirname(__file__), "cache")
150         cachePath       = os.path.join(cacheDir, source.getCacheFilename())
151
152         if not checkFile(cachePath, source.checksum):
153                 fetchFile(cachePath, source.getRepo(), source.getRevision(), source.getFilename(), source.getChecksum(), cacheDir)
154
155         parsedReg       = registry.parse(cachePath)
156
157         g_registryCache[source] = parsedReg
158
159         return parsedReg