[Fuego] [PATCH 2/2] ftc: implement put-run for squad

Daniel Sangorrin daniel.sangorrin at toshiba.co.jp
Thu Jan 10 09:00:32 UTC 2019


This is an early implementation, more debugging is needed
and there are several FIXTHIS included, but it works.
You can try it on Ubuntu Xenial with the instructions below.

Install server application
	host$ sudo apt-get install rabbitmq-server
		[Note] this is required for squad to communicate with celery worker tasks
	host$ git clone https://github.com/Linaro/squad
	host$ cd squad/
	host$ mkvirtualenv --python=python3  mysquad
	host$ cd squad
	host$ pip3 install -r requirements-dev.txt
	host$ ./manage.py test
	host$ ./manage.py migrate
	host$ ./manage.py createsuperuser
	host$ ./manage.py runserver

[Note] The next time you use it use this:
	host$ cd squad
	host$ workon squad
	host$ ./manage.py runserver

Configure a team and project in Squad
	host$ firefox http://localhost:8000/
		- click upright > settings
			- profile: write your name
			- API token: copy the token
				-> assign it to "server_squad_token" in fuego-ro/fuego.conf
		- click upright > Administration
			- Authentication and authorization
				- Add group (this is a user group!)
					- name: myusergroup
					- permissons: choose all
			- Core
				- Add group (this is a team)
					- slug=name=fuego
						-> assign it to "server_squad_team" in fuego-ro/fuego.conf
					- description: whatever
					- usergroups: myusergroup
				- Add project
					- group: fuego
					- slug=name=jessie
						-> assign it to "server_squad_project" in fuego-ro/fuego.conf

Upload a run from Fuego
	fuego-docker# ftc list-runs -q
		Benchmark.IOzone-default-1-bbb
	fuego-docker# ftc put-run Benchmark.IOzone-default-1-bbb
		Packaging run 'Benchmark.IOzone-default-1-bbb'
		run/
		run/devlog.after.txt
		run/syslog.before.txt
		run/build.xml
		run/devlog.txt
		run/testlog.txt
		run/consolelog.txt
		run/run.json
		Run packaged successfully, and is at: /tmp/run-Benchmark.IOzone-default-1-on-fuegohost:bbb.frp
		WARNING: not adding attachment syslog.after
		WARNING: not adding attachment test_spec
		POSTING to http://localhost:8000/api/submit/fuego/jessie/a80be74d1629bdb2455b08db453beba0-4.9.133/bbb-4.9
		Run package run-Benchmark.IOzone-default-1-on-fuegohost:bbb.frp was accepted by the server.

Signed-off-by: Daniel Sangorrin <daniel.sangorrin at toshiba.co.jp>
---
 engine/scripts/ftc | 131 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 119 insertions(+), 12 deletions(-)

diff --git a/engine/scripts/ftc b/engine/scripts/ftc
index 73fd98a..ab2d2cb 100755
--- a/engine/scripts/ftc
+++ b/engine/scripts/ftc
@@ -519,9 +519,16 @@ class config_class:
         # set values from conf_map
         self.host = conf_map.get("host_name", "localhost")
         self.host_name = conf_map.get("host_name", "localhost")
-        self.fuego_server = conf_map.get("fuego_server", "fuegotest.org")
-        #self.SERVER_URL_BASE = "http://%s/server/Fuego_Server?action=Fuego." % self.fuego_server
-        self.SERVER_URL_BASE = "http://%s/fserver.py/?action=" % self.fuego_server
+        self.server_type = conf_map.get("server_type", "fuego")
+        self.server_domain = conf_map.get("server_domain", "fuegotest.org")
+        #self.SERVER_URL_BASE = "http://%s/server/Fuego_Server?action=Fuego." % self.server_domain
+        if self.server_type == "fuego":
+            self.SERVER_URL_BASE = "http://%s/fserver.py/?action=" % self.server_domain
+        elif self.server_type == "squad":
+            self.SERVER_URL_BASE = "http://%s/api" % self.server_domain
+            self.token = conf_map.get("server_squad_token", "WRITE_TOKEN_IN_FUEGO.CONF")
+            self.team = conf_map.get("server_squad_team", "fuego")
+            self.project_id = conf_map.get("server_squad_project", "myproject")
 
         # handle paths (including relative ones)
         conf_dir = os.path.dirname(os.path.abspath(config_path))
@@ -3282,6 +3289,103 @@ def do_put_test(conf, options):
 
     print "Test package %s was accepted by the server." % os.path.basename(test_filepath)
 
+def put_run_fuego(conf, run_filepath):
+    url = conf.SERVER_URL_BASE+"put_run"
+    run_files = {"file1": open(run_filepath, "rb")}
+    resp = requests.post(url, files=run_files)
+    return resp.text.split('\n', 1)
+
+def put_run_squad(conf, run_filepath):
+    # squad doesn't know about fuego run formats
+    dirpath = tempfile.mkdtemp()
+    try:
+        subprocess.check_call('tar -C %s -xf %s' % (dirpath, run_filepath), shell=True)
+        with open(dirpath + '/run/run.json') as f:
+            json_data = json.load(f)
+        # create submit url
+        # Ex: http://localhost:8000/api/submit/fuego/Benchmark.Dhrystone/713c5342/bbb
+        # project_id: this is a name for something you want to test periodically.
+        #   For example, the major version of some software that will be updated
+        #   with bug fixes periodically such as the stable kernel v4.4.y
+        #   or a rootfs built with a specific yocto branch
+        #   -> For now, the project_id is specified in fuego.conf using server_squad_project.
+        #      [FIXTHIS] add a command line argument to override it (we don't have this concept in fuego)
+        # build_id: this is something like an unique identifier for a snapshot
+        #    of your project when you built it. For example, the commit hash of
+        #    the kernel/yocto repo, the kernel minor version or the date. You
+        #    can test the same build_id on multiple environments (boards/kernels)
+        #    for comparison.
+        #   -> For now, just use the testsuite_version and kernel_version
+        #      [FIXTHIS] add a command line argument to override it (we don't have this concept in fuego)
+        # env_id: this is the environment for the test
+        #   -> For now, use the board name and kernel_major_version
+        #      [FIXTHIS] add a command line argument to override it
+        project_id = conf.project_id
+        build_id = json_data['metadata']['testsuite_version'] + '-' + json_data['metadata']['kernel_version']
+        kernel_major_version = '.'.join(json_data['metadata']['kernel_version'].split('.')[:2])
+        env_id = json_data['metadata']['board'] + '-' + kernel_major_version
+        url = "%s/submit/%s/%s/%s/%s" % (conf.SERVER_URL_BASE, conf.team, project_id, build_id, env_id)
+
+        # prepare a multipart files dict for posting
+        files = []
+        ## prepare metadata file
+        metadata = json_data['metadata']
+        # the job_id needs to be unique within the project, it identifies a run
+        timestamp = metadata['timestamp'].replace(':', 'colon').replace('+', 'plus')
+        metadata['job_id'] = '-'.join((metadata['job_name'], metadata['build_number'], metadata['kernel_version'], timestamp))
+        metadata['job_status'] = json_data['status']
+        metadata['datetime'] = metadata['timestamp']
+        files.append(('metadata', ('metadata', json.dumps(metadata))))
+        ## prepare tests and metrics files
+        test_sets = json_data['test_sets']
+        tests = dict()
+        metrics = dict()
+        suite = json_data['name'].split('.')[1]
+        #tests[suite] = json_data['status']
+        for test_set in test_sets:
+            test_set_key = os.path.join(suite, test_set['name'])
+            #tests[test_set_key] = test_set['status']
+            for test_case in test_set['test_cases']:
+                test_case_key = os.path.join(test_set_key, test_case['name'])
+                if 'measurements' in test_case:
+                    for test_measure in test_case['measurements']:
+                        test_measure_key = os.path.join(test_case_key, test_measure['name'])
+                        # use the suite name to group all subtests
+                        squad_key = suite + '/' + test_measure_key.replace('/','_')
+                        tests[squad_key] = test_measure['status']
+                        if test_measure['status'] != 'SKIP':
+                            metrics[squad_key] = [test_measure['measure']]
+                else:
+                    squad_key= suite + '/' + test_case_key.replace('/','_')
+                    tests[squad_key] = test_case['status']
+        files.append(('tests', ('tests', json.dumps(tests))))
+        files.append(('metrics', ('metrics', json.dumps(metrics))))
+        ## prepare attachments
+        for attachment in metadata['attachments']:
+            abs_path = dirpath + '/run/' + attachment['path']
+            if os.path.isfile(abs_path):
+                files.append(('attachment', (attachment['path'], open(abs_path, 'rb'))))
+            else:
+                print("WARNING: not adding attachment " + attachment['name'])
+
+        # set token
+        headers = {}
+        headers['Auth-Token'] = conf.token
+
+        print("POSTING to " + url)
+        response = requests.post(url, headers=headers, files=files)
+        if str(response.status_code)[:1] == "2":
+            result = 'OK'
+        else:
+            result = 'NG'
+        content = response.text.split('\n', 1)
+    except Exception as e:
+        result = "NG"
+        content = 'Exception in ftc'
+        print_error(str(e))
+    finally:
+        shutil.rmtree(dirpath)
+    return result, content
 
 def do_put_run(conf, options):
     # FIXTHIS - could consolidate do_put_test and do_put_run into do_put_item
@@ -3302,16 +3406,19 @@ def do_put_run(conf, options):
         created_package = True
         run_filepath = do_package_run(conf, [run_arg, "-o", "/tmp"])
 
-    url = conf.SERVER_URL_BASE+"put_run"
-    run_files = {"file1": open(run_filepath, "rb")}
-    resp = requests.post(url, files=run_files)
-    if created_package:
-        os.remove(run_filepath)
-    result, content = resp.text.split('\n', 1)
-    if result != "OK":
-        error_out("Can't put run to server\nServer returned message: %s" % content)
+    try:
+        if conf.server_type == "fuego":
+            result, content = put_run_fuego(conf, run_filepath)
+        elif conf.server_type == "squad":
+            result, content = put_run_squad(conf, run_filepath)
+    finally:
+        if created_package:
+            os.remove(run_filepath)
 
-    print "Run package %s was accepted by the server." % os.path.basename(run_filepath)
+    if result != "OK":
+        print("Can't put run to server\nServer returned message: %s" % content)
+    else:
+        print "Run package %s was accepted by the server." % os.path.basename(run_filepath)
 
 # returns a matching item (which must be unique)
 # from a list.  A matching item is one with leading
-- 
2.7.4



More information about the Fuego mailing list