1 /**
2  * collectd - src/smart_test.c
3  * MIT License
4  *
5  * Copyright (C) 2020  Intel Corporation. All rights reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a
8  * copy of this software and associated documentation files (the "Software"),
9  * to deal in the Software without restriction, including without limitation
10  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11  * and/or sell copies of the Software, and to permit persons to whom the
12  * Software is furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  *
25  * Authors:
26  *   Bartlomiej Kotlowski <bartlomiej.kotlowski@intel.com>
27  *   Slawomir Strehlau <slawomir.strehlau@intel.com>
28  **/
29 
30 #include "smart.c"
31 #include "testing.h"
32 
33 #define INTEL_VID 0x8086
34 
35 int VENDOR_ID = INTEL_VID;
36 const char *CORRECT_DEV_PATH = "/dev/nvme0n1";
37 const char *INCORRECT_DEV_PATH = "dev/nvme0nXX";
38 
ioctl(int __fd,unsigned long int __request,...)39 int ioctl(int __fd, unsigned long int __request, ...) {
40   va_list valist;
41   va_start(valist, __request);
42   struct nvme_admin_cmd *admin_cmd = va_arg(valist, struct nvme_admin_cmd *);
43   va_end(valist);
44   void *addr = (void *)(unsigned long)admin_cmd->addr;
45 
46   if (admin_cmd->opcode == NVME_ADMIN_IDENTIFY) {
47     // ioctl asked about vid
48     __le16 *vid = (__le16 *)addr;
49     *vid = VENDOR_ID;
50     return 0;
51   } else if (admin_cmd->opcode == NVME_ADMIN_GET_LOG_PAGE) {
52     // ioctl asked about smart attributes
53     if (admin_cmd->cdw10 == NVME_SMART_INTEL_CDW10) {
54       // set intel specific attributes
55       struct nvme_additional_smart_log *intel_smart_log =
56           (struct nvme_additional_smart_log *)addr;
57       intel_smart_log->program_fail_cnt.norm = 100;
58       return 0;
59     } else if (admin_cmd->cdw10 == NVME_SMART_CDW10) {
60       // set generic smart attributes
61       union nvme_smart_log *smart_log = (union nvme_smart_log *)addr;
62       smart_log->data.critical_warning = 0;
63       return 0;
64     }
65   }
66   return -1; // functionality not mocked
67 };
68 
open(const char * __path,int __oflag,...)69 int open(const char *__path, int __oflag, ...) {
70   if (__path == CORRECT_DEV_PATH) {
71     return 0;
72   }
73   return -1;
74 }
75 
DEF_TEST(x)76 DEF_TEST(x) {
77   int ret;
78 
79   ret = get_vendor_id(CORRECT_DEV_PATH, "stub");
80   EXPECT_EQ_INT(VENDOR_ID, ret);
81 
82   VENDOR_ID = 0x0;
83   ret = get_vendor_id(CORRECT_DEV_PATH, "stub");
84   EXPECT_EQ_INT(VENDOR_ID, ret);
85   VENDOR_ID = INTEL_VID;
86 
87   ret = get_vendor_id(INCORRECT_DEV_PATH, "stub");
88   EXPECT_EQ_INT(-1, ret);
89 
90   ret = smart_read_nvme_intel_disk(CORRECT_DEV_PATH, "stub");
91   EXPECT_EQ_INT(0, ret);
92 
93   ret = smart_read_nvme_intel_disk(INCORRECT_DEV_PATH, "stub");
94   EXPECT_EQ_INT(-1, ret);
95 
96   ret = smart_read_nvme_disk(CORRECT_DEV_PATH, "stub");
97   EXPECT_EQ_INT(0, ret);
98 
99   ret = smart_read_nvme_disk(INCORRECT_DEV_PATH, "stub");
100   EXPECT_EQ_INT(-1, ret);
101 
102   return 0;
103 }
104 
main(void)105 int main(void) {
106   RUN_TEST(x);
107   END_TEST;
108 }
109