1#!/usr/bin/env python3
2import os
3import subprocess
4import json
5import time
6import concurrent.futures
7import argparse
8import tempfile
9
10#
11# preparation calls for the examples
12#
13
14def prep_eina_file_02():
15  f = tempfile.NamedTemporaryFile(delete=False)
16  f.write(b"Simulation")
17  return [f.name, "/tmp/copy_file"]
18
19def prep_eina_xattr_01():
20  f = tempfile.NamedTemporaryFile(delete=False)
21  f.write(b"Simulation")
22  return ["list", f.name]
23
24def prep_eina_xattr_02():
25  f1 = tempfile.NamedTemporaryFile(delete=False)
26  f1.write(b"Simulation")
27  f2 = tempfile.NamedTemporaryFile(delete=False)
28  f2.write(b"Simulation2")
29  return [f1.name, f2.name]
30
31def prep_eet_data_simple():
32  f1 = tempfile.NamedTemporaryFile(delete=False)
33  f1.write(b"Simulation")
34  f2 = tempfile.NamedTemporaryFile(delete=False)
35  f2.write(b"Simulation2")
36  return [f1.name, f2.name]
37
38def prep_eet_data_nested():
39  f1 = tempfile.NamedTemporaryFile(delete=False)
40  f1.write(b"Simulation")
41  f2 = tempfile.NamedTemporaryFile(delete=False)
42  f2.write(b"Simulation2")
43  return [f1.name, f2.name]
44
45def prep_eet_data_file_descriptor_01():
46  f1 = tempfile.NamedTemporaryFile(delete=False)
47  f1.write(b"Simulation")
48  f2 = tempfile.NamedTemporaryFile(delete=False)
49  f2.write(b"Simulation2")
50  return [f1.name, f2.name, "acc", "Example-Simulation"]
51
52def prep_eet_data_file_descriptor_02():
53  f1 = tempfile.NamedTemporaryFile(delete=False)
54  f1.write(b"Simulation")
55  f2 = tempfile.NamedTemporaryFile(delete=False)
56  f2.write(b"Simulation2")
57  return [f1.name, f2.name, "union", "5", "Example-Simulation"]
58
59def prep_ecore_getopt_example():
60  return ["string-1", "120", "apple", "none-optional-arg"]
61
62def prep_eio_file_copy():
63  f1 = tempfile.NamedTemporaryFile(delete=False)
64  f1.write(b"Simulation")
65  return [f1.name, "/tmp/eio_dst_file"]
66
67def prep_eio_file_ls():
68  return ["/tmp/"]
69
70def prep_edje_color_class():
71  return ["beta", "red", "green", "blue"]
72
73def prep_ecore_con_url_headers_example():
74  return ["GET", "www.enlightenment.org"]
75
76def prep_ecore_con_url_download_example():
77  return ["www.enlightenment.org"]
78
79def prep_ecore_con_url_cookies_example():
80  return ["www.enlightenment.org"]
81
82def prep_ecore_con_client_example():
83  return ["enlightenment.org", "80"]
84
85def prep_ecore_con_lookup_example():
86  return ["enlightenment.org"]
87
88def prep_ecore_con_server_example():
89  return ["enlightenment.org", "1234"]
90
91def prep_ecore_con_client_simple_example():
92  return ["enlightenment.org", "80"]
93
94example_preparation = {
95  "eina_file_02" : prep_eina_file_02,
96  "eina_xattr_01" : prep_eina_xattr_01,
97  "eina_xattr_02" : prep_eina_xattr_02,
98  "eet-data-nested" : prep_eet_data_nested,
99  "eet-data-simple" : prep_eet_data_simple,
100  "eet-data-file_descriptor_01" : prep_eet_data_file_descriptor_01,
101  "eet-data-file_descriptor_02" : prep_eet_data_file_descriptor_02,
102  "ecore_getopt_example" : prep_ecore_getopt_example,
103  "eio_file_copy" : prep_eio_file_copy,
104  "eio_file_ls" : prep_eio_file_ls,
105  "edje-color-class" : prep_edje_color_class,
106  "ecore_con_url_headers_example" : prep_ecore_con_url_headers_example,
107  "ecore_con_url_download_example" : prep_ecore_con_url_download_example,
108  "ecore_con_url_cookies_example" : prep_ecore_con_url_cookies_example,
109  "ecore_con_client_example" : prep_ecore_con_client_example,
110  "ecore_con_lookup_example" : prep_ecore_con_lookup_example,
111  "ecore_con_server_example" : prep_ecore_con_server_example,
112  "ecore_con_client_simple_example" : prep_ecore_con_client_simple_example,
113}
114
115#
116# Holds up the state of the ran examples
117#
118
119class State:
120  def __init__(self, examples):
121    self.max_n = examples
122    self.n = 1
123    self.count_fail = 0
124    self.count_success = 0
125    self.count_err_output = 0
126    print("Found "+str(self.max_n)+" Examples")
127
128  def add_run(self, command, error_in_output, exitcode):
129    print("{}/{} {} {} {} ".format(self.n, self.max_n, ("SUCCESS" if exitcode == 0 else "FAIL"), ("CLEAN" if error_in_output == False else "ERR"), command))
130    self.n = self.n + 1
131    if exitcode != 0:
132      self.count_fail += 1
133    if error_in_output == True:
134      self.count_err_output += 1
135    if exitcode == 0 and error_in_output == False:
136      self.count_success += 1
137
138  def print_summary(self):
139    print("Summary")
140    print("  Failed: "+str(self.count_fail)+"/"+str(self.max_n))
141    print("  Errored: "+str(self.count_err_output)+"/"+str(self.max_n))
142    print("  Success: "+str(self.count_success)+"/"+str(self.max_n))
143
144#
145# this simulates the startup of the example, and the closing after 1s
146#
147
148def simulate_example(example):
149  args = []
150  if os.path.basename(example) in example_preparation:
151    args = example_preparation[os.path.basename(example)]()
152
153  #meson changed behaviour from 0.49 to 0.50 so we need this:
154  if os.path.isabs(example):
155    example_dir = example
156  else:
157    example_dir = os.path.join(G.builddir, example)
158
159  run = subprocess.Popen([example_dir] + args,
160      stdout = subprocess.PIPE,
161      stderr = subprocess.PIPE,
162  )
163  time.sleep(1)
164  run.terminate()
165  try:
166    outs, errs = run.communicate(timeout=2)
167  except Exception as e:
168    run.kill()
169    return (example, True, -1)
170  else:
171    return (example, True if b'ERR' in outs or b'ERR' in errs else False, run.poll())
172
173#meson changed behaviour from 0.49 to 0.50 so we need this:
174def meson_fetch_filename(filename_object):
175  if isinstance(filename_object, str):
176    return filename_object
177  else:
178    return filename_object[0]
179
180
181parser = argparse.ArgumentParser(description='Run the examples of efl')
182parser.add_argument('builddir', metavar='build', help='the path where to find the meson build directory')
183
184
185G = parser.parse_args()
186#Run meson to fetch all examples
187meson_introspect = subprocess.Popen(["meson", "introspect", G.builddir, "--targets"],
188      stdout = subprocess.PIPE,
189      stderr = subprocess.PIPE,
190)
191meson_introspect.poll()
192build_targets = json.loads(meson_introspect.stdout.read())
193examples = [meson_fetch_filename(b["filename"]) for b in build_targets if "examples" in meson_fetch_filename(b["filename"]) and b["type"] == "executable"]
194state = State(len(examples))
195#simulate all examples in parallel with up to 5 runners
196with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
197  futures = [executor.submit(simulate_example, example) for example in examples]
198  for future in concurrent.futures.as_completed(futures):
199    example_run = future.result()
200    state.add_run(example_run[0], example_run[1], example_run[2])
201state.print_summary()
202