<commit_before>/* Copyright 2022 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <zephyr/shell/shell.h>
#include <zephyr/ztest.h>

#include "charge_state.h"
#include "charge_state_v2.h"
#include "console.h"
#include "ec_commands.h"
#include "test/drivers/test_state.h"
#include "test/drivers/utils.h"

ZTEST_USER(console_cmd_charge_state, test_idle_too_few_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate idle");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_idle_arg_not_a_bool)
{
	int rv;

	/*
	 * There are many strings that will fail parse_bool(), just test one to
	 * test the code path in the command, other tests for parse_bool are
	 * done in the respective unit test.
	 */
	rv = shell_execute_cmd(get_ec_shell(), "chgstate idle g");
	zassert_equal(rv, EC_ERROR_PARAM2, "Expected %d, but got %d",
		      EC_ERROR_PARAM2, rv);
}

ZTEST_USER(console_cmd_charge_state, test_idle_on__no_ac)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate idle on");
	zassert_equal(rv, EC_ERROR_NOT_POWERED, "Expected %d, but got %d",
		      EC_ERROR_NOT_POWERED, rv);
}

ZTEST_USER(console_cmd_charge_state, test_discharge_on__no_ac)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate discharge on");
	zassert_equal(rv, EC_ERROR_NOT_POWERED, "Expected %d, but got %d",
		      EC_ERROR_NOT_POWERED, rv);
}

ZTEST_USER(console_cmd_charge_state, test_discharge_too_few_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate discharge");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_discharge_arg_not_a_bool)
{
	int rv;

	/*
	 * There are many strings that will fail parse_bool(), just test one to
	 * test the code path in the command, other tests for parse_bool are
	 * done in the respective unit test.
	 */
	rv = shell_execute_cmd(get_ec_shell(), "chgstate discharge g");
	zassert_equal(rv, EC_ERROR_PARAM2, "Expected %d, but got %d",
		      EC_ERROR_PARAM2, rv);
}

ZTEST_USER(console_cmd_charge_state, test_debug_too_few_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate debug");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_debug_arg_not_bool)
{
	int rv;

	/*
	 * There are many strings that will fail parse_bool(), just test one to
	 * test the code path in the command, other tests for parse_bool are
	 * done in the respective unit test.
	 */
	rv = shell_execute_cmd(get_ec_shell(), "chgstate debug g");
	zassert_equal(rv, EC_ERROR_PARAM2, "Expected %d, but got %d",
		      EC_ERROR_PARAM2, rv);
}

ZTEST_USER(console_cmd_charge_state, test_debug_on)
{
	zassert_ok(shell_execute_cmd(get_ec_shell(), "chgstate debug on"),
		   NULL);
}

ZTEST_USER(console_cmd_charge_state, test_debug_on_show_charging_progress)
{
	/*
	 * Force reset the previous display charge so the charge state task
	 * prints on the next iteration.
	 */
	reset_prev_disp_charge();
	charging_progress_displayed();

	/* Enable debug printing */
	zassert_ok(shell_execute_cmd(get_ec_shell(), "chgstate debug on"),
		   NULL);

	/* Sleep at least 1 full iteration of the charge state loop */
	k_sleep(K_USEC(CHARGE_MAX_SLEEP_USEC + 1));

	zassert_true(charging_progress_displayed());
}

ZTEST_USER(console_cmd_charge_state, test_sustain_too_few_args__2_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate sustain");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_sustain_too_few_args__3_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate sustain 5");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_sustain_invalid_params)
{
	/* Verify that lower bound is less than upper bound */
	zassert_equal(shell_execute_cmd(get_ec_shell(),
					"chgstate sustain 50 30"),
		      EC_ERROR_INVAL, NULL);

	/* Verify that lower bound is at least 0 (when upper bound is given) */
	zassert_equal(shell_execute_cmd(get_ec_shell(),
					"chgstate sustain -5 30"),
		      EC_ERROR_INVAL, NULL);

	/* Verify that upper bound is at most 100 */
	zassert_equal(shell_execute_cmd(get_ec_shell(),
					"chgstate sustain 50 101"),
		      EC_ERROR_INVAL, NULL);
}

struct console_cmd_charge_state_fixture {
	struct tcpci_partner_data source_5v_3a;
	struct tcpci_src_emul_data source_ext;
	const struct emul *tcpci_emul;
	const struct emul *charger_emul;
};

static void *console_cmd_charge_state_setup(void)
{
	static struct console_cmd_charge_state_fixture fixture;

	/* Get references for the emulators */
	fixture.tcpci_emul = EMUL_GET_USBC_BINDING(0, tcpc);
	fixture.charger_emul = EMUL_GET_USBC_BINDING(0, chg);
<commit_msg>test: add more edge case tests for "chgstate sustain"<commit_after>/* Copyright 2022 The ChromiumOS Authors
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <zephyr/shell/shell.h>
#include <zephyr/ztest.h>

#include "charge_state.h"
#include "charge_state_v2.h"
#include "console.h"
#include "ec_commands.h"
#include "test/drivers/test_state.h"
#include "test/drivers/utils.h"

ZTEST_USER(console_cmd_charge_state, test_idle_too_few_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate idle");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_idle_arg_not_a_bool)
{
	int rv;

	/*
	 * There are many strings that will fail parse_bool(), just test one to
	 * test the code path in the command, other tests for parse_bool are
	 * done in the respective unit test.
	 */
	rv = shell_execute_cmd(get_ec_shell(), "chgstate idle g");
	zassert_equal(rv, EC_ERROR_PARAM2, "Expected %d, but got %d",
		      EC_ERROR_PARAM2, rv);
}

ZTEST_USER(console_cmd_charge_state, test_idle_on__no_ac)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate idle on");
	zassert_equal(rv, EC_ERROR_NOT_POWERED, "Expected %d, but got %d",
		      EC_ERROR_NOT_POWERED, rv);
}

ZTEST_USER(console_cmd_charge_state, test_discharge_on__no_ac)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate discharge on");
	zassert_equal(rv, EC_ERROR_NOT_POWERED, "Expected %d, but got %d",
		      EC_ERROR_NOT_POWERED, rv);
}

ZTEST_USER(console_cmd_charge_state, test_discharge_too_few_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate discharge");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_discharge_arg_not_a_bool)
{
	int rv;

	/*
	 * There are many strings that will fail parse_bool(), just test one to
	 * test the code path in the command, other tests for parse_bool are
	 * done in the respective unit test.
	 */
	rv = shell_execute_cmd(get_ec_shell(), "chgstate discharge g");
	zassert_equal(rv, EC_ERROR_PARAM2, "Expected %d, but got %d",
		      EC_ERROR_PARAM2, rv);
}

ZTEST_USER(console_cmd_charge_state, test_debug_too_few_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate debug");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_debug_arg_not_bool)
{
	int rv;

	/*
	 * There are many strings that will fail parse_bool(), just test one to
	 * test the code path in the command, other tests for parse_bool are
	 * done in the respective unit test.
	 */
	rv = shell_execute_cmd(get_ec_shell(), "chgstate debug g");
	zassert_equal(rv, EC_ERROR_PARAM2, "Expected %d, but got %d",
		      EC_ERROR_PARAM2, rv);
}

ZTEST_USER(console_cmd_charge_state, test_debug_on)
{
	zassert_ok(shell_execute_cmd(get_ec_shell(), "chgstate debug on"),
		   NULL);
}

ZTEST_USER(console_cmd_charge_state, test_debug_on_show_charging_progress)
{
	/*
	 * Force reset the previous display charge so the charge state task
	 * prints on the next iteration.
	 */
	reset_prev_disp_charge();
	charging_progress_displayed();

	/* Enable debug printing */
	zassert_ok(shell_execute_cmd(get_ec_shell(), "chgstate debug on"),
		   NULL);

	/* Sleep at least 1 full iteration of the charge state loop */
	k_sleep(K_USEC(CHARGE_MAX_SLEEP_USEC + 1));

	zassert_true(charging_progress_displayed());
}

ZTEST_USER(console_cmd_charge_state, test_sustain_too_few_args__2_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate sustain");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_sustain_too_few_args__3_args)
{
	int rv;

	rv = shell_execute_cmd(get_ec_shell(), "chgstate sustain 5");
	zassert_equal(rv, EC_ERROR_PARAM_COUNT, "Expected %d, but got %d",
		      EC_ERROR_PARAM_COUNT, rv);
}

ZTEST_USER(console_cmd_charge_state, test_sustain_invalid_params)
{
	/* Verify that lower bound is less than upper bound */
	zassert_equal(shell_execute_cmd(get_ec_shell(),
					"chgstate sustain 50 30"),
		      EC_ERROR_INVAL, NULL);

	/* Verify that lower bound is at least 0 (when upper bound is given) */
	zassert_equal(shell_execute_cmd(get_ec_shell(),
					"chgstate sustain -5 30"),
		      EC_ERROR_INVAL, NULL);

	/* Verify that upper bound is at most 100 */
	zassert_equal(shell_execute_cmd(get_ec_shell(),
					"chgstate sustain 50 101"),
		      EC_ERROR_INVAL, NULL);

	/* Verify invalid lower bound (not a number) */
	zassert_equal(shell_execute_cmd(get_ec_shell(),
					"chgstate sustain a 50"),
		      EC_ERROR_PARAM2);

	/* Verify invalid uppoer bound (not a number) */
	zassert_equal(shell_execute_cmd(get_ec_shell(),
					"chgstate sustain 30 a"),
		      EC_ERROR_PARAM3);
}

struct console_cmd_charge_state_fixture {
	struct tcpci_partner_data source_5v_3a;
	struct tcpci_src_emul_data source_ext;
	const struct emul *tcpci_emul;
	const struct emul *charger_emul;
};

static void *console_cmd_charge_state_setup(void)
{
	static struct console_cmd_charge_state_fixture fixture;

	/* Get references for the emulators */
	fixture.tcpci_emul = EMUL_GET_USBC_BINDING(0, tcpc);
	fixture.charger_emul = EMUL_GET_USBC_BINDING(0, chg);

{'fraction_non_alphanumeric': 0.09972430839433406, 'fraction_numerical': 0.007415153531704534, 'mean_word_length': 5.1628588166373754, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4890333', 'n_tokens_mistral': 4017, 'n_tokens_neox': 3843, 'n_words': 920}