examples_check: fix for meson-0.50
[platform/upstream/efl.git] / examples_checks.py
1 #!/usr/bin/python3
2 import os
3 import sys
4 import subprocess
5 import json
6 import time
7 import concurrent.futures
8 import argparse
9 import tempfile
10
11 #
12 # preparation calls for the examples
13 #
14
15 def prep_eina_file_02():
16   f = tempfile.NamedTemporaryFile(delete=False)
17   f.write(b"Simulation")
18   return [f.name, "/tmp/copy_file"]
19
20 def prep_eina_xattr_01():
21   f = tempfile.NamedTemporaryFile(delete=False)
22   f.write(b"Simulation")
23   return ["list", f.name]
24
25 def prep_eina_xattr_02():
26   f1 = tempfile.NamedTemporaryFile(delete=False)
27   f1.write(b"Simulation")
28   f2 = tempfile.NamedTemporaryFile(delete=False)
29   f2.write(b"Simulation2")
30   return [f1.name, f2.name]
31
32 def prep_eet_data_simple():
33   f1 = tempfile.NamedTemporaryFile(delete=False)
34   f1.write(b"Simulation")
35   f2 = tempfile.NamedTemporaryFile(delete=False)
36   f2.write(b"Simulation2")
37   return [f1.name, f2.name]
38
39 def prep_eet_data_nested():
40   f1 = tempfile.NamedTemporaryFile(delete=False)
41   f1.write(b"Simulation")
42   f2 = tempfile.NamedTemporaryFile(delete=False)
43   f2.write(b"Simulation2")
44   return [f1.name, f2.name]
45
46 def prep_eet_data_file_descriptor_01():
47   f1 = tempfile.NamedTemporaryFile(delete=False)
48   f1.write(b"Simulation")
49   f2 = tempfile.NamedTemporaryFile(delete=False)
50   f2.write(b"Simulation2")
51   return [f1.name, f2.name, "acc", "Example-Simulation"]
52
53 def prep_eet_data_file_descriptor_02():
54   f1 = tempfile.NamedTemporaryFile(delete=False)
55   f1.write(b"Simulation")
56   f2 = tempfile.NamedTemporaryFile(delete=False)
57   f2.write(b"Simulation2")
58   return [f1.name, f2.name, "union", "5", "Example-Simulation"]
59
60 example_preparation = {
61   "eina_file_02" : prep_eina_file_02,
62   "eina_xattr_01" : prep_eina_xattr_01,
63   "eina_xattr_02" : prep_eina_xattr_02,
64   "eet-data-simple" : prep_eet_data_simple,
65   "eet-data-nested" : prep_eet_data_nested,
66   "eet-data-simple" : prep_eet_data_simple,
67   "eet-data-file_descriptor_01" : prep_eet_data_file_descriptor_01,
68   "eet-data-file_descriptor_02" : prep_eet_data_file_descriptor_02,
69 }
70
71 #
72 # Holds up the state of the ran examples
73 #
74
75 class State:
76   def __init__(self, examples):
77     self.max_n = examples
78     self.n = 1
79     self.count_fail = 0
80     self.count_success = 0
81     self.count_err_output = 0
82     print("Found "+str(self.max_n)+" Examples")
83
84   def add_run(self, command, error_in_output, exitcode):
85     print("{}/{} {} {} {} ".format(self.n, self.max_n, ("SUCCESS" if exitcode == 0 else "FAIL"), ("CLEAN" if error_in_output == False else "ERR"), command))
86     self.n = self.n + 1
87     if exitcode != 0:
88       self.count_fail += 1
89     if error_in_output == True:
90       self.count_err_output += 1
91     if exitcode == 0 and error_in_output == False:
92       self.count_success += 1
93
94   def print_summary(self):
95     print("Summary")
96     print("  Failed: "+str(self.count_fail)+"/"+str(self.max_n))
97     print("  Errored: "+str(self.count_err_output)+"/"+str(self.max_n))
98     print("  Success: "+str(self.count_success)+"/"+str(self.max_n))
99
100 #
101 # this simulates the startup of the example, and the closing after 1s
102 #
103
104 def simulate_example(example):
105   args = []
106   if os.path.basename(example) in example_preparation:
107     args = example_preparation[os.path.basename(example)]()
108
109   #meson changed behaviour from 0.49 to 0.50 so we need this:
110   if os.path.isabs(example):
111     example_dir = example
112   else:
113     example_dir = os.path.join(G.builddir, example)
114
115   run = subprocess.Popen([example_dir] + args,
116       stdout = subprocess.PIPE,
117       stderr = subprocess.PIPE,
118   )
119   time.sleep(1)
120   run.terminate()
121   try:
122     outs, errs = run.communicate(timeout=2)
123   except Exception as e:
124     run.kill()
125     return (example, True, -1)
126   else:
127     return (example, True if b'ERR' in outs or b'ERR' in errs else False, run.poll())
128
129 #meson changed behaviour from 0.49 to 0.50 so we need this:
130 def meson_fetch_filename(filename_object):
131   if isinstance(filename_object, str):
132     return filename_object
133   else:
134     return filename_object[0]
135
136
137 parser = argparse.ArgumentParser(description='Run the examples of efl')
138 parser.add_argument('builddir', metavar='build', help='the path where to find the meson build directory')
139
140
141 G = parser.parse_args()
142 #Run meson to fetch all examples
143 meson_introspect = subprocess.Popen(["meson", "introspect", G.builddir, "--targets"],
144       stdout = subprocess.PIPE,
145       stderr = subprocess.PIPE,
146 )
147 meson_introspect.poll()
148 build_targets = json.loads(meson_introspect.stdout.read())
149 examples = [meson_fetch_filename(b["filename"]) for b in build_targets if "examples" in meson_fetch_filename(b["filename"]) and b["type"] == "executable"]
150 state = State(len(examples))
151 #simulate all examples in parallel with up to 5 runners
152 with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
153   futures = [executor.submit(simulate_example, example) for example in examples]
154   for future in concurrent.futures.as_completed(futures):
155     example_run = future.result()
156     state.add_run(example_run[0], example_run[1], example_run[2])
157 state.print_summary()