blob: 08fe3393e9fcd5b46c6f0e6730c365b613b5e628 [file] [log] [blame]
// 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();
}