| // Copyright 2016 Google Inc. All Rights Reserved. |
| // Author: germuth@google.com (Aaron Germuth) |
| |
| // Humax Hnvram Testing |
| // Methods from hmx_upgrade_flash.c have been replaced with mock methods below. |
| // |
| // Fields are tested by trying to read/write two different fields: |
| // MAC_ADDR and ACTIVATED_KERNEL_NAME, one for each partition. |
| // |
| // Variables are tested by trying to read/write the same variable, but |
| // in each partition seperately (ReadOnly and ReadWrite) |
| |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <fcntl.h> |
| #include <tuple> |
| #include "gtest/gtest.h" |
| |
| #define TEST_MAIN |
| #include "hmx_test_base.cc" |
| #include "hmx_upgrade_nvram.c" |
| |
| using ::testing::TestWithParam; |
| using Partition = HMX_NVRAM_PARTITION_E; |
| |
| // Field Parameters |
| // partition, fieldType, fieldName, fieldVal1, fieldVal2, fieldValLen |
| std::tuple<Partition, NVRAM_FIELD_T, unsigned char*, unsigned char*, |
| unsigned char*,unsigned int> field_tuples[] = { |
| std::make_tuple(HMX_NVRAM_PARTITION_RO, NVRAM_FIELD_MAC_ADDR, |
| (unsigned char*)"MAC_ADDR", |
| (unsigned char*)"\x02\x04:\xAE\x06:\xFF\xE2", |
| (unsigned char*)"\x0\x40:\xDD\x16:\x20\x41", |
| (unsigned int) 8), |
| std::make_tuple(HMX_NVRAM_PARTITION_RW, NVRAM_FIELD_ACTIVATED_KERNEL_NAME, |
| (unsigned char*)"ACTIVATED_KERNEL_NAME", |
| (unsigned char*)"kernel0", |
| (unsigned char*)"kernel1", |
| (unsigned int) 7) |
| }; |
| |
| // Variable Parameters |
| // partition, partitionOther, partitionOffset |
| std::tuple<Partition, Partition, int> var_tuples[] = { |
| std::make_tuple(HMX_NVRAM_PARTITION_RO, // Read only |
| HMX_NVRAM_PARTITION_RW, NVRAM_RO_OFFSET), |
| std::make_tuple(HMX_NVRAM_PARTITION_RW, // Read Write |
| HMX_NVRAM_PARTITION_RO, NVRAM_RW_OFFSET) |
| }; |
| |
| // Global Test Parameters, populated by var_tuples and field_tuples |
| NVRAM_FIELD_T fieldType; |
| unsigned char* fieldName; |
| unsigned char* fieldVal; |
| unsigned char* fieldValOther; |
| unsigned int fieldValLen; |
| Partition part; |
| Partition partOther; |
| int offset; |
| |
| // Global Test Constants |
| const unsigned char* name = (unsigned char*)"test_name"; |
| const unsigned char* nameOther = (unsigned char*)"test_name2"; |
| const unsigned char* val = (unsigned char*)"TEST\0\x02\x11"; |
| const unsigned int nameLen = 9; |
| const unsigned int nameOtherLen = 10; |
| const unsigned int valLen = 7; |
| |
| // Helper Testing Methods |
| int dlist_size(Partition part) { |
| int i = 0; |
| dlist_hdr_t *entry; |
| DLIST_FOR_EACH(&s_nvram_envvars[part], entry) { |
| i++; |
| } |
| return i; |
| } |
| |
| int dlist_contains(Partition part, const unsigned char* name) { |
| dlist_hdr_t *entry; |
| NVRAM_EVNVAR_T *env; |
| DLIST_FOR_EACH(&s_nvram_envvars[part], entry) { |
| env = (NVRAM_EVNVAR_T *) entry; |
| if (strcmp((char*)env->name, (char*)name) == 0) { |
| return 1; |
| } |
| } |
| return 0; |
| } |
| |
| void clear_dlist() { |
| drv_NVRAM_Delete(HMX_NVRAM_PARTITION_RO, name); |
| drv_NVRAM_Delete(HMX_NVRAM_PARTITION_RW, name); |
| drv_NVRAM_Delete(HMX_NVRAM_PARTITION_RO, nameOther); |
| drv_NVRAM_Delete(HMX_NVRAM_PARTITION_RW, nameOther); |
| drv_NVRAM_Delete(HMX_NVRAM_PARTITION_RO, fieldName); |
| drv_NVRAM_Delete(HMX_NVRAM_PARTITION_RW, fieldName); |
| |
| // Ensure dlist empty |
| EXPECT_EQ(0, dlist_size(HMX_NVRAM_PARTITION_RO)); |
| EXPECT_EQ(0, dlist_size(HMX_NVRAM_PARTITION_RW)); |
| } |
| |
| // Hnvram byte formatting - Used to verify tests |
| // One byte to store name length, 4 bytes for value length |
| const unsigned int recLen = 1 + nameLen + 4 + valLen; |
| // Include 5 intro bytes (1 start byte + 4 bytes for recLen) |
| const unsigned int totalLen = recLen + 5; |
| char* raw_hnvram_bytes(char* bytes) { |
| // Start Byte |
| bytes[0] = '\x01'; |
| |
| // Record Length |
| bytes[1] = '\0'; |
| bytes[2] = '\0'; |
| bytes[3] = '\0'; |
| bytes[4] = recLen; |
| |
| // Name Length |
| bytes[5] = nameLen; |
| |
| // Name |
| memcpy(bytes + 6, name, nameLen); |
| |
| // Val Length |
| bytes[6 + nameLen] = '\0'; |
| bytes[7 + nameLen] = '\0'; |
| bytes[8 + nameLen] = '\0'; |
| bytes[9 + nameLen] = valLen; |
| |
| //Val |
| memcpy(bytes + 10 + nameLen, val, valLen); |
| |
| return bytes; |
| } |
| |
| // Replacement methods for hmx_upgrade_flash.c |
| // We always use a file instead of flash memory |
| const char* hnvram_location = NULL; |
| void HMX_UPGRADE_NVRAM_Init(const char * location) { |
| return; |
| } |
| |
| const char* HMX_UPGRADE_NVRAM_Get_Partition_Path(void) { |
| return "/dev/mtd/hnvram"; |
| } |
| |
| int HMX_UPGRADE_NVRAM_Write(unsigned long offset, const unsigned char * data, |
| unsigned int size ) { |
| int fp = open(hnvramFileName, O_WRONLY); |
| if (fp < 0) { |
| return -1; |
| } |
| int ret = lseek(fp, offset, SEEK_SET); |
| if (ret < 0) { |
| return -1; |
| } |
| ret = write(fp, data, size); |
| if (ret < 0) { |
| return -1; |
| } |
| ret = close(fp); |
| if (ret < 0) { |
| return -1; |
| } |
| return 0; |
| } |
| |
| int HMX_UPGRADE_NVRAM_Read(unsigned long offset, unsigned char * data, |
| unsigned int size ) { |
| int fp = open(hnvramFileName, O_RDONLY); |
| if (fp < 0) { |
| return -1; |
| } |
| int ret = lseek(fp, offset, SEEK_SET); |
| if (ret < 0) { |
| return -1; |
| } |
| ret = read(fp, data, size); |
| if (ret < 0) { |
| return -1; |
| } |
| ret = close(fp); |
| if (ret < 0) { |
| return -1; |
| } |
| return 0; |
| } |
| |
| class HnvramFieldTest : |
| public HnvramTest, public ::testing::WithParamInterface< |
| std::tuple<Partition, NVRAM_FIELD_T, unsigned char*, |
| unsigned char*, unsigned char*,unsigned int> > { |
| public: |
| virtual void SetUp() { |
| // Initialize test Parameters |
| part = std::get<0>(GetParam()); |
| fieldType = std::get<1>(GetParam()); |
| fieldName = std::get<2>(GetParam()); |
| fieldVal = std::get<3>(GetParam()); |
| fieldValOther = std::get<4>(GetParam()); |
| fieldValLen = std::get<5>(GetParam()); |
| |
| HnvramTest::SetUp(); |
| |
| clear_dlist(); |
| // Shouldn't be able to find anything in a empty partition |
| EXPECT_EQ(NULL, drv_NVRAM_FindEnv(HMX_NVRAM_PARTITION_RO, name)); |
| EXPECT_EQ(NULL, drv_NVRAM_FindEnv(HMX_NVRAM_PARTITION_RW, name)); |
| } |
| |
| virtual void TearDown() { |
| clear_dlist(); |
| HnvramTest::TearDown(); |
| |
| part = HMX_NVRAM_PARTITION_UNSPECIFIED; |
| fieldType = NVRAM_FIELD_DUMMY; |
| fieldName = NULL; |
| fieldVal = NULL; |
| fieldValOther = NULL; |
| fieldValLen = 0; |
| } |
| }; |
| |
| TEST_P(HnvramFieldTest, TestGetFieldInfo) { |
| unsigned char buff[255]; |
| unsigned int defSize = 0; |
| HMX_NVRAM_PARTITION_E partUsed; |
| |
| EXPECT_EQ(DRV_ERR, |
| drv_NVRAM_GetFieldInfo(NVRAM_FIELD_DUMMY, |
| &partUsed, buff, &defSize)); |
| |
| EXPECT_EQ(DRV_OK, |
| drv_NVRAM_GetFieldInfo(fieldType, &partUsed, buff, &defSize)); |
| EXPECT_STREQ((char*) buff, (char*)fieldName); |
| EXPECT_EQ(part, partUsed); |
| EXPECT_EQ(defSize, 0); |
| } |
| |
| TEST_P(HnvramFieldTest, TestGetFieldAndSize) { |
| unsigned char buff[255]; |
| unsigned int dataSize = sizeof(buff); |
| unsigned int pDataSize = 0; |
| |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| HMX_NVRAM_GetFieldAndSize(NVRAM_FIELD_DUMMY, |
| 0, buff, dataSize, &pDataSize)); |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| HMX_NVRAM_GetFieldAndSize(fieldType, |
| 0, NULL, dataSize, &pDataSize)); |
| // Nothing to Read |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| HMX_NVRAM_GetFieldAndSize(fieldType, |
| 0, buff, dataSize, &pDataSize)); |
| // Write MAC_ADDR |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_Write(part, fieldName, 0, fieldVal, fieldValLen)); |
| |
| // Read it back |
| EXPECT_EQ(DRV_OK, |
| HMX_NVRAM_GetFieldAndSize(fieldType, |
| 0, buff, dataSize, &pDataSize)); |
| EXPECT_EQ(0, memcmp((char*)buff, (char*)fieldVal, fieldValLen)); |
| EXPECT_EQ(dataSize, 255); |
| EXPECT_EQ(pDataSize, fieldValLen); |
| } |
| |
| TEST_P(HnvramFieldTest, TestSetField) { |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| HMX_NVRAM_SetField(NVRAM_FIELD_DUMMY, 0, fieldVal, fieldValLen)); |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| HMX_NVRAM_SetField(fieldType, 0, NULL, fieldValLen)); |
| |
| // Should add variable |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_SetField(fieldType, 0, fieldVal, fieldValLen)); |
| EXPECT_EQ(1, dlist_size(part)); |
| EXPECT_EQ(1, dlist_contains(part, fieldName)); |
| EXPECT_FALSE(hnvram_empty()); |
| |
| // Should be able to read it back |
| unsigned char buff[255]; |
| unsigned int dataSize = sizeof(buff); |
| |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_GetField(fieldType, 0, buff, dataSize)); |
| EXPECT_EQ(0, memcmp((char*)buff, (char*)fieldVal, fieldValLen)); |
| |
| // Try changing value |
| EXPECT_EQ(DRV_OK, |
| HMX_NVRAM_SetField(fieldType, 0, fieldValOther, fieldValLen)); |
| EXPECT_EQ(1, dlist_size(part)); |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_GetField(fieldType, 0, buff, dataSize)); |
| EXPECT_EQ(0, memcmp((char*)buff, (char*)fieldValOther, fieldValLen)); |
| |
| // Test with Offset |
| int offset = 3; |
| EXPECT_EQ(DRV_OK, |
| HMX_NVRAM_SetField(fieldType, offset, fieldVal, fieldValLen)); |
| EXPECT_EQ(1, dlist_size(part)); |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_GetField(fieldType, offset, buff, dataSize)); |
| EXPECT_EQ(0, memcmp((char*)buff, (char*)(fieldVal + offset), |
| fieldValLen - offset)); |
| } |
| |
| TEST_P(HnvramFieldTest, TestGetLength) { |
| unsigned int readLen; |
| |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| HMX_NVRAM_GetLength(fieldType, NULL)); |
| EXPECT_EQ(DRV_ERR, |
| HMX_NVRAM_GetLength(NVRAM_FIELD_DUMMY, &readLen)); |
| |
| // No field length to grab |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_GetLength(fieldType, &readLen)); |
| EXPECT_EQ(readLen, 0); |
| |
| // Should work after adding |
| EXPECT_EQ(DRV_OK, |
| HMX_NVRAM_SetField(fieldType, 0, fieldVal, fieldValLen)); |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_GetLength(fieldType, &readLen)); |
| EXPECT_EQ(readLen, fieldValLen); |
| } |
| |
| class HnvramVariableTest : |
| public HnvramTest, public ::testing::WithParamInterface< |
| std::tuple<Partition, Partition, int> > { |
| public: |
| virtual void SetUp() { |
| // Initialize test Parameters |
| part = std::get<0>(GetParam()); |
| partOther = std::get<1>(GetParam()); |
| offset = std::get<2>(GetParam()); |
| |
| HnvramTest::SetUp(); |
| |
| clear_dlist(); |
| // Initialize test Parameters |
| } |
| virtual void TearDown() { |
| clear_dlist(); |
| HnvramTest::TearDown(); |
| |
| part = HMX_NVRAM_PARTITION_UNSPECIFIED; |
| partOther = HMX_NVRAM_PARTITION_UNSPECIFIED; |
| offset = -1; |
| } |
| }; |
| |
| TEST_P(HnvramVariableTest, TestDrvRead) { |
| unsigned char read[30]; |
| // Should be able to read 0s |
| EXPECT_EQ(10, drv_NVRAM_Read(read, offset, 10)); |
| EXPECT_STREQ("\0\0\0\0\0\0\0\0\0\0", (char*)read); |
| EXPECT_EQ(22, drv_NVRAM_Read(read, offset, 22)); |
| EXPECT_STREQ("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", (char*) read); |
| |
| // Should be able to read back a raw write |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Write(offset, val, valLen)); |
| EXPECT_EQ(valLen, drv_NVRAM_Read(read, offset, valLen)); |
| EXPECT_STREQ((char*)val, (char*)read); |
| } |
| |
| TEST_P(HnvramVariableTest, TestDrvWrite) { |
| unsigned char read[255]; |
| EXPECT_EQ(valLen, drv_NVRAM_Write(val, offset, valLen)); |
| |
| // raw read should return same string |
| EXPECT_EQ(0, hnvram_empty()); |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Read(offset, read, valLen)); |
| EXPECT_EQ(0, memcmp((char*)read, (char*) val, valLen)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestFindEnv) { |
| // Should be able to read after SetEnv |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, name, val, valLen)); |
| NVRAM_EVNVAR_T* env = drv_NVRAM_FindEnv(part, name); |
| EXPECT_FALSE(NULL == env); |
| EXPECT_EQ(0, memcmp((char*)env->value, (char*)val, valLen)); |
| EXPECT_EQ(1, dlist_size(part)); |
| EXPECT_EQ(1, dlist_contains(part, name)); |
| |
| EXPECT_EQ(NULL, drv_NVRAM_FindEnv(partOther, name)); |
| EXPECT_EQ(NULL, drv_NVRAM_FindEnv(part, nameOther)); |
| |
| // Don't mix up with 2nd one |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, nameOther, val, valLen)); |
| env = drv_NVRAM_FindEnv(part, nameOther); |
| EXPECT_FALSE(NULL == env); |
| EXPECT_EQ(0, memcmp((char*)env->name, (char*)nameOther, nameOtherLen)); |
| |
| env = drv_NVRAM_FindEnv(part, name); |
| EXPECT_FALSE(NULL == env); |
| EXPECT_EQ(0, memcmp((char*)env->name, (char*)name, nameLen)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestScanDir) { |
| unsigned char readName[255]; |
| unsigned int readNameLen; |
| unsigned char readVal[255]; |
| unsigned int readValLen; |
| |
| // Ask for 5th var when empty |
| EXPECT_EQ(DRV_ERR, drv_NVRAM_ScanDir(part, 4, readName, &readNameLen, |
| readVal, &readValLen)); |
| |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, name, val, valLen)); |
| |
| // Ask for 5th again, still fail |
| EXPECT_EQ(DRV_ERR, drv_NVRAM_ScanDir(part, 4, readName, &readNameLen, |
| readVal, &readValLen)); |
| |
| // Get back 1st var, should suceed |
| EXPECT_EQ(DRV_OK, drv_NVRAM_ScanDir(part, 0, readName, &readNameLen, |
| readVal, &readValLen)); |
| EXPECT_EQ(readNameLen, nameLen); |
| EXPECT_EQ(readValLen, valLen); |
| EXPECT_EQ(0, memcmp((char*)name, readName, nameLen)); |
| EXPECT_EQ(0, memcmp((char*)val, readVal, valLen)); |
| |
| // Add second, make it doesn't mix them up |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, nameOther, val, valLen)); |
| |
| EXPECT_EQ(DRV_OK, drv_NVRAM_ScanDir(part, 1, readName, &readNameLen, |
| readVal, &readValLen)); |
| EXPECT_EQ(readNameLen, nameOtherLen); |
| EXPECT_EQ(0, memcmp((char*)nameOther, readName, nameOtherLen)); |
| |
| EXPECT_EQ(DRV_OK, drv_NVRAM_ScanDir(part, 0, readName, &readNameLen, |
| readVal, &readValLen)); |
| EXPECT_EQ(readNameLen, nameLen); |
| EXPECT_EQ(0, memcmp((char*)name, readName, nameLen)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestDrvDelete) { |
| // Nothing to delete |
| EXPECT_EQ(DRV_ERR, drv_NVRAM_Delete(part, name)); |
| |
| // Add single variable to delete |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, name, val, valLen)); |
| EXPECT_EQ(DRV_OK, drv_NVRAM_Delete(part, name)); |
| EXPECT_EQ(0, dlist_size(part)); |
| |
| // Don't mix them up |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, name, val, valLen)); |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, nameOther, val, valLen)); |
| EXPECT_EQ(2, dlist_size(part)); |
| |
| EXPECT_EQ(DRV_OK, drv_NVRAM_Delete(part, name)); |
| EXPECT_EQ(1, dlist_size(part)); |
| NVRAM_EVNVAR_T* env = drv_NVRAM_FindEnv(part, nameOther); |
| EXPECT_TRUE(NULL != env); |
| EXPECT_EQ(0, memcmp(env->name, nameOther, nameOtherLen)); |
| |
| EXPECT_EQ(DRV_OK, drv_NVRAM_Delete(part, nameOther)); |
| EXPECT_EQ(0, dlist_size(part)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestDrvGetEnv) { |
| unsigned char read[255]; |
| unsigned int readLen; |
| unsigned int maxCopied = 10; |
| |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| drv_NVRAM_GetEnv(part, NULL, 0, read, maxCopied, &readLen)); |
| |
| // Try to read empty dlist |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| drv_NVRAM_GetEnv(part, name, 0, read, maxCopied, &readLen)); |
| |
| // Should be able to read after SetEnv |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, name, val, valLen)); |
| EXPECT_EQ(DRV_OK, drv_NVRAM_GetEnv(part, name, 0, read, maxCopied, &readLen)); |
| EXPECT_EQ(0, memcmp((char*)val, read, readLen)); |
| |
| // Should work with offset (2) |
| EXPECT_EQ(DRV_OK, drv_NVRAM_GetEnv(part, name, 2, read, maxCopied, &readLen)); |
| EXPECT_EQ(0, memcmp((char*)(val + 2), read, readLen)); |
| |
| // Should respect maxCopied, and not overwrite |
| read[3] = '\xAE'; |
| maxCopied = 3; |
| EXPECT_EQ(DRV_OK, drv_NVRAM_GetEnv(part, name, 0, read, maxCopied, &readLen)); |
| EXPECT_EQ(0, memcmp((char*)val, read, maxCopied)); |
| EXPECT_EQ('\xAE', (char)read[3]); |
| |
| // Shouldn't be able to find other variables |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| drv_NVRAM_GetEnv(part, nameOther, 0, read, maxCopied, &readLen)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestDrvGetLength) { |
| unsigned int readLen; |
| |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| drv_NVRAM_GetLength(part, NULL, &readLen)); |
| |
| // Try to read empty dlist |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| drv_NVRAM_GetLength(part, name, &readLen)); |
| |
| // Should be able to read after SetEnv |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, name, val, valLen)); |
| EXPECT_EQ(DRV_OK, drv_NVRAM_GetLength(part, name, &readLen)); |
| EXPECT_EQ(valLen, readLen); |
| |
| // Shouldn't be able to find other variables |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| drv_NVRAM_GetLength(part, nameOther, &readLen)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestSetEnv) { |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, name, val, valLen)); |
| |
| // Check dlists |
| EXPECT_EQ(1, dlist_size(part)); |
| EXPECT_EQ(1, dlist_contains(part, name)); |
| EXPECT_EQ(0, dlist_size(partOther)); |
| |
| // Should be findable by findEnv |
| NVRAM_EVNVAR_T* env = drv_NVRAM_FindEnv(part, name); |
| EXPECT_TRUE(env != NULL); |
| |
| // Params should match |
| EXPECT_STREQ((char*)env->name, (char*)name); |
| EXPECT_EQ(0, memcmp((char*)env->value, (char*)val, valLen)); |
| |
| EXPECT_EQ(env->nameLen, nameLen); |
| EXPECT_EQ(env->valueLen, valLen); |
| EXPECT_EQ(env->recLen, nameLen + valLen + 5); |
| |
| // Make sure just anything isn't findable |
| EXPECT_EQ(NULL, drv_NVRAM_FindEnv(part, nameOther)); |
| EXPECT_EQ(NULL, drv_NVRAM_FindEnv(partOther, name)); |
| |
| // Check RAWFS, just to be thorough |
| EXPECT_EQ(0, dlist_size(HMX_NVRAM_PARTITION_W_RAWFS)); |
| EXPECT_EQ(NULL, drv_NVRAM_FindEnv(HMX_NVRAM_PARTITION_W_RAWFS, name)); |
| EXPECT_EQ(0, dlist_size(HMX_NVRAM_PARTITION_W_RAWFS)); |
| |
| // Make sure we can add more than one |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, nameOther, val, valLen)); |
| EXPECT_EQ(2, dlist_size(part)); |
| EXPECT_EQ(1, dlist_contains(part, name)); |
| EXPECT_EQ(1, dlist_contains(part, nameOther)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestLoadByAddress) { |
| int size; |
| if (part == HMX_NVRAM_PARTITION_RO) { |
| size = NVRAM_RO_SIZE; |
| } else { |
| size = NVRAM_RW_SIZE; |
| } |
| |
| // Nothing to load |
| EXPECT_EQ(DRV_OK, drv_NVRAM_LoadByAddress(part, offset, size)); |
| EXPECT_EQ(0, dlist_size(part)); |
| |
| // Corrupt Hnvram start bit |
| char rhb[255]; |
| raw_hnvram_bytes(rhb); |
| rhb[0] = '\xAE'; |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Write(offset, (unsigned char*)rhb, recLen)); |
| EXPECT_EQ(DRV_ERR_EVENT_INITIALIZATION, |
| drv_NVRAM_LoadByAddress(part, offset, size)); |
| |
| // corrupt record length sizes |
| raw_hnvram_bytes(rhb); |
| rhb[1] = '\xFF'; |
| rhb[2] = '\xFF'; |
| rhb[3] = '\xFF'; |
| rhb[4] = '\xFF'; |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Write(offset, (unsigned char*)rhb, recLen)); |
| EXPECT_EQ(DRV_ERR_EVENT_INITIALIZATION, |
| drv_NVRAM_LoadByAddress(part, offset, size)); |
| |
| raw_hnvram_bytes(rhb); |
| rhb[4] = '\0'; |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Write(offset, (unsigned char*)rhb, recLen)); |
| EXPECT_EQ(DRV_ERR_EVENT_INITIALIZATION, |
| drv_NVRAM_LoadByAddress(part, offset, size)); |
| |
| // Proper load |
| raw_hnvram_bytes(rhb); |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Write(offset, (unsigned char*)rhb, recLen)); |
| EXPECT_EQ(DRV_OK, drv_NVRAM_LoadByAddress(part, offset, size)); |
| EXPECT_EQ(1, dlist_size(part)); |
| EXPECT_EQ(1, dlist_contains(part, name)); |
| |
| // Fail cleanly with no partition |
| hnvramFileName = (const char*)"/oops"; |
| EXPECT_EQ(DRV_ERR_EXTERNAL_ERROR, |
| drv_NVRAM_LoadByAddress(part, offset, size)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestSave) { |
| unsigned char valueLarge[hnvramFileSize + 10]; |
| // Variable doesn't fit in partition (fake the value length) |
| EXPECT_EQ(DRV_OK, |
| drv_NVRAM_SetEnv(part, name, valueLarge, sizeof(valueLarge) - 10)); |
| EXPECT_EQ(DRV_ERR_OUTOFMEMORY, drv_NVRAM_Save(part)); |
| EXPECT_EQ(DRV_OK, drv_NVRAM_Delete(part, name)); |
| |
| // file should still be empty if dlist has nothing to save |
| EXPECT_EQ(DRV_OK, drv_NVRAM_Save(part)); |
| EXPECT_EQ(0, dlist_size(part)); |
| EXPECT_TRUE(hnvram_empty()); |
| |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, name, val, valLen)); |
| EXPECT_EQ(DRV_OK, drv_NVRAM_Save(part)); |
| |
| // Raw read back partition and try to match |
| unsigned char read[255]; |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Read(offset, read, totalLen)); |
| |
| char rhb[255]; |
| raw_hnvram_bytes(rhb); |
| EXPECT_EQ(0, memcmp((char*)read, rhb, totalLen)); |
| |
| // Writes to RW should have also saved to RWB partition, other should be 0s |
| if (part == HMX_NVRAM_PARTITION_RW) { |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Read(NVRAM_RWB_OFFSET, read, totalLen)); |
| EXPECT_EQ(0, memcmp((char*)read, rhb, totalLen)); |
| } else { |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Read(NVRAM_RWB_OFFSET, read, 7)); |
| EXPECT_EQ(0, memcmp((char*)read, "\0\0\0\0\0\0\0", 7)); |
| } |
| |
| // Should be null byte after var to indicate no more variables |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Read(offset + totalLen, read, 1)); |
| EXPECT_EQ(0, memcmp((char*)read, "\0", 1)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestHMXWrite) { |
| unsigned char read[255]; |
| |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_Write(part, name, 0, val, valLen)); |
| |
| // Write should have inserted into dlist |
| EXPECT_EQ(1, dlist_size(part)); |
| EXPECT_EQ(1, dlist_contains(part, name)); |
| |
| // And saved bytes to file |
| EXPECT_FALSE(hnvram_empty()); |
| EXPECT_EQ(0, HMX_UPGRADE_NVRAM_Read(offset, read, totalLen)); |
| |
| char rhb[255]; |
| raw_hnvram_bytes(rhb); |
| EXPECT_EQ(0, memcmp((char*)read, rhb, totalLen)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestHMXRead) { |
| unsigned char read[255]; |
| unsigned int readLen; |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| HMX_NVRAM_Read(part, NULL, 0, NULL, 0, NULL)); |
| |
| // Should fail to find variable |
| EXPECT_EQ(DRV_ERR_INVALID_PARAMETER, |
| HMX_NVRAM_Read(part, name, 0, read, sizeof(read), NULL)); |
| |
| // Add val to dlist and make sure Read gets them correct |
| EXPECT_EQ(DRV_OK, drv_NVRAM_SetEnv(part, name, val, valLen)); |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_Read(part, name, 0, |
| read, sizeof(read), &readLen)); |
| EXPECT_EQ(readLen, valLen); |
| EXPECT_EQ(0, memcmp((char*)read, (char*)val, valLen)); |
| } |
| |
| TEST_P(HnvramVariableTest, TestRemove) { |
| // Nothing to delete |
| EXPECT_EQ(DRV_ERR, HMX_NVRAM_Remove(part, name)); |
| |
| // Write to file and make sure its removed |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_Write(part, name, 0, val, valLen)); |
| |
| EXPECT_EQ(DRV_OK, HMX_NVRAM_Remove(part, name)); |
| EXPECT_EQ(0, dlist_size(part)); |
| // Remove operation doesn't 0 entire partition, only needs to clear start byte |
| // If LoadbyAddr doesn't add anything to dlist, partition effectively empty |
| int size; |
| if (part == HMX_NVRAM_PARTITION_RO) { |
| size = NVRAM_RO_SIZE; |
| } else { |
| size = NVRAM_RW_SIZE; |
| } |
| EXPECT_EQ(DRV_OK, drv_NVRAM_LoadByAddress(part, offset, size)); |
| EXPECT_EQ(0, dlist_size(part)); |
| } |
| |
| INSTANTIATE_TEST_CASE_P(TryBothFields, HnvramFieldTest, |
| ::testing::ValuesIn(field_tuples)); |
| |
| INSTANTIATE_TEST_CASE_P(TryAllPartitions, HnvramVariableTest, |
| ::testing::ValuesIn(var_tuples)); |
| |
| int main(int argc, char** argv) { |
| ::testing::InitGoogleTest(&argc, argv); |
| ::testing::AddGlobalTestEnvironment(new HnvramEnvironment); |
| return RUN_ALL_TESTS(); |
| } |