xref: /aosp_15_r20/external/deqp/scripts/khr_util/registry_cache.py (revision 35238bce31c2a825756842865a792f8cf7f89930)
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
23import os
24import sys
25import hashlib
26
27from . import registry
28
29scriptPath = os.path.join(os.path.dirname(__file__), "..")
30sys.path.insert(0, scriptPath)
31
32from ctsbuild.common import *
33
34BASE_URL = ""
35
36class RegistrySource:
37    def __init__(self, repository, filename, revision, checksum):
38        self.repository = repository
39        self.filename = filename
40        self.revision = revision
41        self.checksum = checksum
42
43    def __hash__(self):
44        return hash((self.repository, self.filename, self.revision, self.checksum))
45
46    def __eq__(self, other):
47        return (self.repository, self.filename, self.revision, self.checksum) == (other.repository, other.filename, other.revision, other.checksum)
48
49    def getFilename (self):
50        return os.path.basename(self.filename)
51
52    def getCacheFilename (self):
53        return "r%s-%s" % (self.revision, self.getFilename())
54
55    def getChecksum (self):
56        return self.checksum
57
58    def getRevision (self):
59        return self.revision
60
61    def getRepo (self):
62        return self.repository
63
64    def getRevision (self):
65        return self.revision
66
67    def getFilename (self):
68        return self.filename
69
70def computeChecksum (data):
71    dataFiltered = data.replace('\r','')
72    hash = hashlib.sha256(dataFiltered.encode("utf-8")).hexdigest()
73    return hash
74
75def makeSourceUrl (repository, revision, filename):
76    return "%s/%s/%s" % (repository, revision, filename)
77
78def checkoutGit (repository, revision, fullDstPath):
79    if not os.path.exists(fullDstPath):
80        execute(["git", "clone", "--no-checkout", repository, fullDstPath])
81
82    pushWorkingDir(fullDstPath)
83    try:
84        execute(["git", "fetch", repository, "+refs/heads/*:refs/remotes/origin/*"])
85        execute(["git", "checkout", revision])
86    finally:
87        popWorkingDir()
88
89def checkoutFile (repository, revision, filename, cacheDir):
90    if sys.version_info < (3, 0):
91        from urllib2 import urlopen
92    else:
93        from urllib.request import urlopen
94
95    try:
96        req = urlopen(makeSourceUrl(repository, revision, filename))
97        data = req.read()
98        if sys.version_info >= (3, 0):
99            data = data.decode("utf-8")
100    except IOError:
101        fullDstPath = os.path.join(cacheDir, "git")
102
103        checkoutGit(repository, revision, fullDstPath)
104        f = open(os.path.join(fullDstPath, filename), "rt")
105        data = f.read()
106        f.close()
107    except:
108        print("Unexpected error:", sys.exc_info()[0])
109
110    return data
111
112def fetchFile (dstPath, repository, revision, filename, checksum, cacheDir):
113    def writeFile (filename, data):
114        f = open(filename, 'wt')
115        f.write(data)
116        f.close()
117
118    if not os.path.exists(os.path.dirname(dstPath)):
119        os.makedirs(os.path.dirname(dstPath))
120
121    print("Fetching %s/%s@%s" % (repository, filename, revision))
122    data = checkoutFile(repository, revision, filename, cacheDir)
123    gotChecksum = computeChecksum(data)
124
125    if checksum != gotChecksum:
126        raise Exception("Checksum mismatch, expected %s, got %s" % (checksum, gotChecksum))
127
128    writeFile(dstPath, data)
129
130def checkFile (filename, checksum):
131    def readFile (filename):
132        f = open(filename, 'rt')
133        data = f.read()
134        f.close()
135        return data
136
137    if os.path.exists(filename):
138        return computeChecksum(readFile(filename)) == checksum
139    else:
140        return False
141
142g_registryCache = {}
143
144def getRegistry (source):
145    global g_registryCache
146
147    if source in g_registryCache:
148        return g_registryCache[source]
149
150    cacheDir = os.path.join(os.path.dirname(__file__), "cache")
151    cachePath = os.path.join(cacheDir, source.getCacheFilename())
152
153    if not checkFile(cachePath, source.checksum):
154        fetchFile(cachePath, source.getRepo(), source.getRevision(), source.getFilename(), source.getChecksum(), cacheDir)
155
156    parsedReg = registry.parse(cachePath)
157
158    g_registryCache[source] = parsedReg
159
160    return parsedReg
161