blob: fc9f476250ead2d8a0615bd45d2c01fc4a050fe2 [file] [log] [blame]
/*
* Copyright (c) 2020 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @defgroup driver_sensor_subsys_tests sensor_subsys
* @ingroup all_tests
* @{
* @}
*/
#include <ztest.h>
#include "dummy_sensor.h"
K_SEM_DEFINE(sem, 0, 1);
#define RETURN_SUCCESS (0)
struct channel_sequence {
enum sensor_channel chan;
struct sensor_value data;
};
struct trigger_sequence {
struct sensor_trigger trig;
struct sensor_value data;
enum sensor_attribute attr;
};
static struct channel_sequence chan_elements[] = {
{ SENSOR_CHAN_LIGHT, { 0, 0 } },
{ SENSOR_CHAN_RED, { 1, 1 } },
{ SENSOR_CHAN_GREEN, { 2, 4 } },
{ SENSOR_CHAN_BLUE, { 3, 9 } },
{ SENSOR_CHAN_PROX, { 4, 16 } }
};
static struct trigger_sequence trigger_elements[] = {
/* trigger for SENSOR_TRIG_THRESHOLD */
{ {SENSOR_TRIG_THRESHOLD, SENSOR_CHAN_PROX},
{ 127, 0 }, SENSOR_ATTR_UPPER_THRESH },
/* trigger for SENSOR_TRIG_TIMER */
{ {SENSOR_TRIG_TIMER, SENSOR_CHAN_PROX},
{ 130, 127 }, SENSOR_ATTR_UPPER_THRESH },
/* trigger for SENSOR_TRIG_DATA_READY */
{ {SENSOR_TRIG_DATA_READY, SENSOR_CHAN_PROX},
{ 150, 130 }, SENSOR_ATTR_UPPER_THRESH },
/* trigger for SENSOR_TRIG_DELTA */
{ {SENSOR_TRIG_DELTA, SENSOR_CHAN_PROX},
{ 180, 150 }, SENSOR_ATTR_UPPER_THRESH },
/* trigger for SENSOR_TRIG_NEAR_FAR */
{ {SENSOR_TRIG_NEAR_FAR, SENSOR_CHAN_PROX},
{ 155, 180 }, SENSOR_ATTR_UPPER_THRESH }
};
#define TOTAL_CHAN_ELEMENTS (sizeof(chan_elements) / \
sizeof(struct channel_sequence))
#define TOTAL_TRIG_ELEMENTS (sizeof(trigger_elements) / \
sizeof(struct trigger_sequence))
/**
* @brief Test get multiple channels values.
*
* @ingroup driver_sensor_subsys_tests
*
* @details
* Test Objective:
* - get multiple channels values consistently in two operations:
* fetch sample and get the values of each channel individually.
* - check the results with sensor_value type avoids use of
* floating point values
*
* Testing techniques:
* - function and block box testing,Interface testing,
* Dynamic analysis and testing, Equivalence classes.
*
* Prerequisite Conditions:
* - N/A
*
* Input Specifications:
* - N/A
*
* Test Procedure:
* -# Define a device and bind to dummy sensor.
* -# Fetch the sample of dummy senor and check the result.
* -# Get SENSOR_CHAN_LIGHT/SENSOR_CHAN_RED/SENSOR_CHAN_GREEN/
* SENSOR_CHAN_BLUE/SENSOR_CHAN_BLUE channels from the sensor,
* and check the result.
*
* Expected Test Result:
* - Application can get multiple channels for dummy sensor.
*
* Pass/Fail Criteria:
* - Successful if check points in test procedure are all passed, otherwise failure.
*
* Assumptions and Constraints:
* - N/A
*
* @see sensor_sample_fetch(), sensor_channel_get()
*/
void test_sensor_get_channels(void)
{
const struct device *dev;
struct sensor_value data;
dev = device_get_binding(DUMMY_SENSOR_NAME);
zassert_not_null(dev, "failed: dev is null.");
/* test fetch single channel */
zassert_equal(sensor_sample_fetch_chan(dev, chan_elements[0].chan),
RETURN_SUCCESS, "fail to fetch sample.");
/* Get and check channel 0 value. */
zassert_equal(sensor_channel_get(dev, chan_elements[0].chan,
&data), RETURN_SUCCESS, "fail to get channel.");
zassert_equal(data.val1, chan_elements[0].data.val1,
"the data is not match.");
zassert_equal(data.val2, chan_elements[0].data.val2,
"the data is not match.");
/* test fetch all channel */
zassert_equal(sensor_sample_fetch(dev), RETURN_SUCCESS,
"fail to fetch sample.");
/* Get and check channels value except for chanel 0. */
for (int i = 1; i < TOTAL_CHAN_ELEMENTS; i++) {
zassert_equal(sensor_channel_get(dev, chan_elements[i].chan,
&data), RETURN_SUCCESS, "fail to get channel.");
zassert_equal(data.val1, chan_elements[i].data.val1,
"the data is not match.");
zassert_equal(data.val2, chan_elements[i].data.val2,
"the data is not match.");
}
/* Get data with invalid channel. */
zassert_not_equal(sensor_channel_get(dev, SENSOR_CHAN_DISTANCE,
&data), RETURN_SUCCESS, "should fail for invalid channel.");
}
static void trigger_handler(const struct device *dev,
const struct sensor_trigger *trigger)
{
ARG_UNUSED(dev);
ARG_UNUSED(trigger);
k_sem_give(&sem);
}
/**
* @brief Test sensor multiple triggers.
*
* @ingroup driver_sensor_subsys_tests
*
* @details
* Test Objective:
* Check if sensor subsys can set multiple triggers and
* can set/get sensor attribute.
*
* Testing techniques:
* - function and block box testing,Interface testing,
* Dynamic analysis and testing.
*
* Prerequisite Conditions:
* - N/A
*
* Input Specifications:
* - N/A
*
* Test Procedure:
* -# Define a device and bind to dummy sensor and
* check the result.
* -# set multiple triggers for the dummy sensor and no trig sensor.
* then check the result.
* -# Handle different types of triggers, based on time, data,threshold,
* based on a delta value, near/far events and single/double tap and
* check the result.
*
* Expected Test Result:
* - Application can get multiple channels for dummy sensor.
*
* Pass/Fail Criteria:
* - Successful if check points in test procedure are all passed, otherwise failure.
*
* Assumptions and Constraints:
* - N/A
*
* @see sensor_attr_set(), sensor_trigger_set()
*/
void test_sensor_handle_triggers(void)
{
const struct device *dev;
const struct device *dev_no_trig;
struct sensor_value data;
dev = device_get_binding(DUMMY_SENSOR_NAME);
dev_no_trig = device_get_binding(DUMMY_SENSOR_NAME_NO_TRIG);
zassert_not_null(dev, "failed: dev is null.");
zassert_equal(sensor_sample_fetch(dev), RETURN_SUCCESS,
"fail to fetch sample.");
/* setup multiple triggers */
for (int i = 0; i < TOTAL_TRIG_ELEMENTS; i++) {
/* set attributes for trigger */
zassert_equal(sensor_attr_set(dev,
trigger_elements[i].trig.chan,
trigger_elements[i].attr,
&trigger_elements[i].data),
RETURN_SUCCESS, "fail to set attributes");
/* read-back attributes for trigger */
zassert_equal(sensor_attr_get(dev,
trigger_elements[i].trig.chan,
trigger_elements[i].attr,
&data),
RETURN_SUCCESS, "fail to get attributes");
zassert_equal(trigger_elements[i].data.val1,
data.val1, "read-back returned wrong val1");
zassert_equal(trigger_elements[i].data.val2,
data.val2, "read-back returned wrong val2");
/* setting a sensor's trigger and handler */
zassert_equal(sensor_trigger_set(dev,
&trigger_elements[i].trig,
trigger_handler),
RETURN_SUCCESS, "fail to set trigger");
/* get channels value after trigger fired */
k_sem_take(&sem, K_FOREVER);
zassert_equal(sensor_channel_get(dev,
trigger_elements[i].trig.chan,
&data), RETURN_SUCCESS, "fail to get channel.");
/* check the result of the trigger channel */
zassert_equal(data.val1, trigger_elements[i].data.val1,
"retrieved data is not match.");
zassert_equal(data.val2, trigger_elements[i].data.val2,
"retrieved data is not match.");
/* set attributes for no trig dev */
zassert_equal(sensor_attr_set(dev_no_trig,
trigger_elements[i].trig.chan,
trigger_elements[i].attr,
&trigger_elements[i].data),
-ENOSYS, "fail to set attributes");
/* read-back attributes for no trig dev*/
zassert_equal(sensor_attr_get(dev_no_trig,
trigger_elements[i].trig.chan,
trigger_elements[i].attr,
&data),
-ENOSYS, "fail to get attributes");
/* setting a sensor's trigger and handler for no trig dev */
zassert_equal(sensor_trigger_set(dev_no_trig,
&trigger_elements[i].trig,
trigger_handler),
-ENOSYS, "fail to set trigger");
}
}
/**
* @brief Test unit conversion of sensor module
* @details Verify helper function to convert acceleration from
* Gs to m/s^2 and from m/s^2 to Gs. Verify helper function
* to convert radians to degrees and degrees to radians. Verify
* helper function for converting struct sensor_value to double.
*/
void test_sensor_unit_conversion(void)
{
struct sensor_value data;
/* Test acceleration unit conversion */
sensor_g_to_ms2(1, &data);
zassert_equal(data.val1, SENSOR_G/1000000LL,
"the data is not match.");
zassert_equal(data.val2, SENSOR_G%(data.val1 * 1000000LL),
"the data is not match.");
zassert_equal(sensor_ms2_to_g(&data), 1,
"the data is not match.");
/* set test data to negative value */
data.val1 = -data.val1;
data.val2 = -data.val2;
zassert_equal(sensor_ms2_to_g(&data), -1,
"the data is not match.");
/* Test the conversion between angle and radian */
sensor_degrees_to_rad(180, &data);
zassert_equal(data.val1, SENSOR_PI/1000000LL,
"the data is not match.");
zassert_equal(data.val2, SENSOR_PI%(data.val1 * 1000000LL),
"the data is not match.");
zassert_equal(sensor_rad_to_degrees(&data), 180,
"the data is not match.");
/* set test data to negative value */
data.val1 = -data.val1;
data.val2 = -data.val2;
zassert_equal(sensor_rad_to_degrees(&data), -180,
"the data is not match.");
/* reset test data to positive value */
data.val1 = -data.val1;
data.val2 = -data.val2;
/* Test struct sensor_value to double */
#if defined(CONFIG_FPU)
zassert_equal((long long)(sensor_value_to_double(&data) * 1000000LL),
SENSOR_PI, "the data is not match.");
#endif
}
/*test case main entry*/
void test_main(void)
{
ztest_test_suite(test_sensor_api,
ztest_1cpu_unit_test(test_sensor_get_channels),
ztest_1cpu_unit_test(test_sensor_handle_triggers),
ztest_1cpu_unit_test(test_sensor_unit_conversion));
ztest_run_test_suite(test_sensor_api);
}