13 from dashboard.common import elastic_access
14 from dashboard.common import logger_utils
15 from dashboard.conf import testcases
16 from dashboard.conf.config import APIConfig
17 from dashboard.mongo2elastic import format
19 logger = logger_utils.DashboardLogger('mongo2elastic').get
21 parser = argparse.ArgumentParser()
22 parser.add_argument("-c", "--config-file",
24 help="Config file location")
25 parser.add_argument('-ld', '--latest-days',
29 help='get entries old at most N days from mongodb and'
30 ' parse those that are not already in elasticsearch.'
31 ' If not present, will get everything from mongodb, which is the default')
33 args = parser.parse_args()
34 CONF = APIConfig().parse(args.config_file)
37 tmp_docs_file = './mongo-{}.json'.format(uuid.uuid4())
40 class DocumentVerification(object):
41 def __init__(self, doc):
42 super(DocumentVerification, self).__init__()
44 self.doc_id = doc['_id'] if '_id' in doc else None
47 def mandatory_fields_exist(self):
48 mandatory_fields = ['installer',
56 for key, value in self.doc.items():
57 if key in mandatory_fields:
59 logger.info("Skip testcase '%s' because field '%s' missing" %
63 mandatory_fields.remove(key)
67 if len(mandatory_fields) > 0:
68 logger.info("Skip testcase '%s' because field(s) '%s' missing" %
69 (self.doc_id, mandatory_fields))
74 def modify_start_date(self):
77 self.doc[field] = self._fix_date(self.doc[field])
81 def modify_scenario(self):
85 if (scenario not in self.doc) or \
86 (scenario in self.doc and self.doc[scenario] is None):
87 self.doc[scenario] = self.doc[version]
94 def _fix_date(self, date_string):
95 if date_string == 'None':
97 if isinstance(date_string, dict):
98 return date_string['$date']
99 if 'T' not in date_string:
100 date_string = date_string[:-3].replace(' ', 'T')
101 if not date_string.endswith('Z'):
107 class DocumentPublisher(object):
109 def __init__(self, doc, fmt, exist_docs, creds, elastic_url):
113 self.exist_docs = exist_docs
114 self.elastic_url = elastic_url
115 self.is_formatted = True
119 if self._verify_document() and self.fmt:
120 self.is_formatted = vars(format)[self.fmt](self.doc)
122 self.is_formatted = False
124 logger.error("Fail in format testcase[%s]\nerror message: %s" %
125 (self.doc, traceback.format_exc()))
126 self.is_formatted = False
131 if self.is_formatted and self.doc not in self.exist_docs:
135 status, data = elastic_access.publish_docs(self.elastic_url, self.creds, self.doc)
137 logger.error('Publish record[{}] failed, due to [{}]'
138 .format(self.doc, json.loads(data)['error']['reason']))
140 def _fix_date(self, date_string):
141 if isinstance(date_string, dict):
142 return date_string['$date']
144 return date_string[:-3].replace(' ', 'T') + 'Z'
146 def _verify_document(self):
147 return not (DocumentVerification(self.doc)
150 .mandatory_fields_exist()
154 class DocumentsPublisher(object):
156 def __init__(self, project, case, fmt, days, elastic_url, creds):
157 self.project = project
161 self.elastic_url = elastic_url
163 self.existed_docs = []
167 past_time = datetime.datetime.today() - datetime.timedelta(days=self.days)
169 "project_name": "{}",
171 "start_date": {{"$gt" : "{}"}}
172 }}'''.format(self.project, self.case, past_time)
175 "project_name": "{}",
177 }}'''.format(self.project, self.case)
178 cmd = ['mongoexport',
179 '--db', 'test_results_collection',
180 '--collection', 'results',
181 '--query', '{}'.format(query),
182 '--out', '{}'.format(tmp_docs_file)]
184 subprocess.check_call(cmd)
186 except Exception, err:
187 logger.error("export mongodb failed: %s" % err)
191 def get_existed_docs(self):
197 {{ "match": {{ "project_name": "{}" }} }},
198 {{ "match": {{ "case_name": "{}" }} }}
202 }}'''.format(self.project, self.case)
208 {{ "match": {{ "project_name": "{}" }} }},
209 {{ "match": {{ "case_name": "{}" }} }}
213 "start_date": {{ "gte": "now-{}d" }}
218 }}'''.format(self.project, self.case, self.days)
220 raise Exception('Update days must be non-negative')
221 self.existed_docs = elastic_access.get_docs(self.elastic_url, self.creds, body)
227 with open(tmp_docs_file) as fdocs:
228 for doc_line in fdocs:
229 DocumentPublisher(json.loads(doc_line),
233 self.elastic_url).format().publish()
240 if os.path.exists(tmp_docs_file):
241 os.remove(tmp_docs_file)
245 base_elastic_url = urlparse.urljoin(CONF.es_url, '/testapi/results')
246 days = args.latest_days
247 es_creds = CONF.es_creds
249 for project, case_dicts in testcases.testcases_yaml.items():
250 for case_dict in case_dicts:
251 case = case_dict.get('name')
252 fmt = testcases.compose_format(case_dict.get('format'))
253 DocumentsPublisher(project,
258 es_creds).export().get_existed_docs().publish()