blob: e5ab348267224f4eab3105bf116a7b1ad7db8039 [file] [log] [blame]
# Copyright 2016 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import glob
import json
import logging
import os
import re
import shutil
import tempfile
from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import autotemp, error
CONFIG_JSON_TEMPLATE = '''
{
"ociVersion": "1.0.0-rc1",
"platform": {
"os": "linux",
"arch": "all"
},
"process": {
"terminal": true,
"user": {
"uid": 10000,
"gid": 10000
},
"args": [
%s
],
"cwd": "/"
},
"root": {
"path": "rootfs",
"readonly": false
},
"hostname": "runc",
"mounts": [
{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
{
"destination": "/dev",
"type": "tmpfs",
"source": "tmpfs",
"options": [
"nosuid",
"noexec"
]
}
],
"hooks": {},
"linux": {
"devices": [
{
"path": "/dev/null",
"type": "c",
"major": 1,
"minor": 3,
"fileMode": 438,
"uid": 0,
"gid": 0
}
],
"uidMappings": [
{
"hostID": 10000,
"containerID": 0,
"size": 10
}
],
"gidMappings": [
{
"hostID": 10000,
"containerID": 0,
"size": 10
}
]
}
}
'''
class security_RunOci(test.test):
version = 1
preserve_srcdir = True
def get_test_option(self, handle):
"""
Gets the test configuration from the json file given in handle.
"""
data = json.load(handle)
return data['run_oci_args'], data['program_argv'], data['expected_result']
def run_test_in_dir(self, run_oci_args, argv, expected, oci_path):
"""
Executes the test in the given directory that points to an OCI image.
"""
ret = 0
cmd_output = utils.system_output(
'/usr/bin/run_oci %s %s' % (run_oci_args, oci_path),
retain_output=True)
if cmd_output != expected:
ret = 1
return ret
def run_test(self, run_oci_args, argv, expected):
"""
Runs one test from the src directory. Return 0 if the test passes,
return 1 on failure.
"""
td = autotemp.tempdir()
os.chown(td.name, 10000, 10000)
with open(os.path.join(td.name, 'config.json'), 'w') as config_file:
config_file.write(CONFIG_JSON_TEMPLATE % argv)
rootfs_path = os.path.join(td.name, 'rootfs')
os.mkdir(rootfs_path)
os.chown(rootfs_path, 10000, 10000)
utils.run(['mount', "--bind", "/", rootfs_path])
ret = self.run_test_in_dir(run_oci_args, argv, expected, td.name)
utils.run(['umount', '-f', rootfs_path])
return ret
def run_once(self):
"""
Runs each of the tests specified in the source directory.
This test fails if any subtest fails. Sub tests exercise the run_oci
command and check that the correct namespace mappings and mounts are
made. If any subtest fails, this test will fail.
"""
failed = []
ran = 0
for p in glob.glob('%s/test-*.json' % self.srcdir):
name = os.path.basename(p)
logging.info('Running: %s', name)
run_oci_args, argv, expected = self.get_test_option(file(p))
if self.run_test(run_oci_args, argv, expected):
failed.append(name)
ran += 1
if ran == 0:
failed.append('No tests found to run from %s!' % (self.srcdir))
if failed:
logging.error('Failed: %s', failed)
raise error.TestFail('Failed: %s' % failed)