forked from CCExtractor/sample-platform
-
Notifications
You must be signed in to change notification settings - Fork 0
/
models.py
245 lines (199 loc) · 8.9 KB
/
models.py
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
"""
Maintain database models regarding various regression tests, categories, storing output of tests.
List of models corresponding to mysql tables:
[
'Category' => 'category',
'RegressionTest' => 'regression_test',
'RegressionTestOutput' => 'regression_test_output'
'RegressionTestOutputFiles' => 'regression_test_output_files'
]
"""
from typing import Any, Dict, Tuple, Type
from sqlalchemy import (Boolean, Column, ForeignKey, Integer, String, Table,
Text)
from sqlalchemy.orm import relationship
import database
from database import Base, DeclEnum
regressionTestLinkTable = Table(
'regression_test_category',
Base.metadata,
Column('regression_id', Integer, ForeignKey('regression_test.id', onupdate='CASCADE', ondelete='RESTRICT')),
Column('category_id', Integer, ForeignKey('category.id', onupdate='CASCADE', ondelete='RESTRICT'))
)
class Category(Base):
"""Model to store categories of regression tests."""
__tablename__ = 'category'
__table_args__ = {'mysql_engine': 'InnoDB'}
id = Column(Integer, primary_key=True)
name = Column(String(64), unique=True)
description = Column(Text(), nullable=False)
regression_tests = relationship('RegressionTest', secondary=regressionTestLinkTable, back_populates='categories')
def __init__(self, name, description) -> None:
"""
Parametrized constructor for the Category model.
:param name: The value of the 'name' field of Category model
:type name: str
:param description: The value of the 'description' field of Category model
:type description: str
"""
self.name = name
self.description = description
def __repr__(self) -> str:
"""
Represent a Category Model by its 'name' Field.
:return: Returns the string containing 'name' field of the Category model
:rtype: str
"""
return f"<Category {self.name}>"
class InputType(DeclEnum):
"""Enumerator types for input."""
file = "file", "File"
stdin = "stdin", "Stdin"
udp = "udp", "UDP"
class OutputType(DeclEnum):
"""Enumerator types for input."""
file = "file", "File"
null = "null", "Null"
tcp = "tcp", "TCP"
cea708 = "cea708", "CEA-708"
multi_program = "multiprogram", "Multi-program"
stdout = "stdout", "Stdout"
report = "report", "Report"
class RegressionTest(Base):
"""Model to store regression tests."""
__tablename__ = 'regression_test'
__table_args__ = {'mysql_engine': 'InnoDB'}
id = Column(Integer, primary_key=True)
sample_id = Column(Integer, ForeignKey('sample.id', onupdate='CASCADE', ondelete='CASCADE'))
sample = relationship('Sample', uselist=False, back_populates='tests')
command = Column(Text(), nullable=False)
input_type = Column(InputType.db_type())
output_type = Column(OutputType.db_type())
categories = relationship('Category', secondary=regressionTestLinkTable, back_populates='regression_tests')
output_files = relationship('RegressionTestOutput', back_populates='regression_test')
expected_rc = Column(Integer)
active = Column(Boolean(), default=True)
def __init__(self, sample_id, command, input_type, output_type, category_id, expected_rc, active=True) -> None:
"""
Parametrized constructor for the RegressionTest model.
:param sample_id: The value of the 'name' field of RegressionTest model
:type sample_id: int
:param command: The value of the 'command' field of RegressionTest model
:type command: str
:param input_type: The value of the 'input_type' field of RegressionTest model
:type input_type: InputType
:param output_type: The value of the 'output_type' field of RegressionTest model
:type output_type: OutputType
:param category_id: The value of the 'category_id' field of RegressionTest model
:type category_id: int
:param expected_rc: The value of the 'expected_rc' field of RegressionTest model
:type expected_rc: int
:param active: The value of the 'active' field of RegressionTest model
:type active: bool
"""
self.sample_id = sample_id
self.command = command
self.input_type = input_type
self.output_type = output_type
self.category_id = category_id
self.expected_rc = expected_rc
self.active = active
def __repr__(self) -> str:
"""
Represent a RegressionTest Model by its 'id' Field.
:return: Returns the string containing 'id' field of the RegressionTest model
:rtype: str
"""
return f"<RegressionTest {self.id}>"
class RegressionTestOutput(Base):
"""Model to store output of regression test."""
__tablename__ = 'regression_test_output'
__table_args__ = {'mysql_engine': 'InnoDB'}
id = Column(Integer, primary_key=True)
regression_id = Column(Integer, ForeignKey('regression_test.id', onupdate='CASCADE', ondelete='RESTRICT'))
regression_test = relationship('RegressionTest', back_populates='output_files')
correct = Column(Text())
correct_extension = Column(String(64), nullable=False) # contains the .
expected_filename = Column(Text())
ignore = Column(Boolean(), default=False)
multiple_files = relationship('RegressionTestOutputFiles', back_populates='output')
def __init__(self, regression_id, correct, correct_extension, expected_filename, ignore=False) -> None:
"""
Parametrized constructor for the RegressionTestOutput model.
:param regression_id: The value of the 'regression_id' field of RegressionTestOutput model
:type regression_id: int
:param correct: The value of the 'correct' field of RegressionTestOutput model
:type correct: str
:param correct_extension: The value of the 'correct_extension' field of RegressionTestOutput model
:type correct_extension: str
:param expected_filename: The value of the 'expected_filename' field of RegressionTestOutput model
:type expected_filename: str
:param ignore: The value of the 'ignore' field of RegressionTestOutput model (False by default)
:type ignore: bool
"""
self.regression_id = regression_id
self.correct = correct
self.correct_extension = correct_extension
self.expected_filename = expected_filename
self.ignore = ignore
def __repr__(self) -> str:
"""
Represent a RegressionTestOutput Model by its 'id' Field.
:return: Returns the string containing 'id' field of the RegressionTestOutput model.
:rtype: str
"""
return f"<RegressionTestOutput {self.id}>"
@property
def filename_correct(self):
"""
Return the filename of a particular regression output.
:return: String containing name and particular extension
:rtype: str
"""
return self.create_correct_filename(self.correct)
def filename_expected(self, sample_hash) -> str:
"""
Return expected filename.
:param sample_hash: sample_hash of RegressionTestOutput
:type name: str
:return: String containing name, expected filename, particular extension
:rtype: str
"""
return f"{sample_hash}{self.expected_filename}{self.correct_extension}"
def create_correct_filename(self, name) -> str:
"""
Create correct filename.
:param name: name of the file
:type name: str
:return: correct file name with extension
:rtype: str
"""
return f"{name}{self.correct_extension}"
class RegressionTestOutputFiles(Base):
"""Model to store multiple correct output files for a regression_test."""
__tablename__ = 'regression_test_output_files'
__table_args__ = {'mysql_engine': 'InnoDB'}
id = Column(Integer, primary_key=True)
file_hashes = Column(Text())
regression_test_output_id = Column(
Integer,
ForeignKey('regression_test_output.id', onupdate='CASCADE', ondelete='RESTRICT')
)
output = relationship('RegressionTestOutput', back_populates='multiple_files')
def __init__(self, file_hashes, regression_test_output_id) -> None:
"""
Parametrized constructor for the RegressionTestOutput model.
:param regression_test_output_id: ForeignKey refering to id of RegressionTestOutput model
:type regression_id: int
:param file_hashes: The value of the 'file_hashes' field of RegressionTestOutputFiles model
:type correct: str
"""
self.file_hashes = file_hashes
self.regression_test_output_id = regression_test_output_id
def __repr__(self) -> str:
"""
Represent a RegressionTestOutputFile Model by its 'id' Field.
:return: Returns the string containing 'id' field of the RegressionTestOutputFile model.
:rtype: str
"""
return f"{self.id}"