# Copyright 2021 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.

AUTHOR = "dhaddock, Chromium OS"
NAME = "autoupdate_Basic.m2n.full.pin"
TIME = "MEDIUM"
PURPOSE = "Tests an M-to-N update with Nebraska using PIN login."
TEST_CATEGORY = "Functional"
TEST_CLASS = "platform"
TEST_TYPE = "server"

DOC = """
This tests an M-to-N update. That means it will update from the current stable
version for this board to ToT. This test will be used in the CQ to ensure
changes don't break autoupdate.

We supply a job_repo_url to the test when running locally. In the lab this will
be passed directly. The job_repo_url is a link to the autotest packages on a
devserver. The test uses it to find the correct payload to use.

To get a list of available devservers to use execute this command:
atest server list | grep devserver

Example usage:
test_that <DUT> autoupdate_Basic.m2n.full.pin --board=<board> --args="job_repo_url=http://<devserver IP>:8082/static/<board>-release/RXX-XXXXX.X.X/autotest/packages"

"""

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import utils
from autotest_lib.client.cros import cryptohome
args_dict = utils.args_to_dict(args)

def run(machine):
    host = hosts.create_host(machine)
    if not cryptohome.is_low_entropy_credentials_supported(host):
        raise error.TestNAError(
                'Skip test: No hardware support for PIN login')
    job.run_test('autoupdate_Basic', host=host, full_payload=True,
    		 m2n=True, pin_login=True, **args_dict)

job.parallel_simple(run, machines)
