Merge "hnvram: Added option to choose target file + tests"
diff --git a/hnvram/Makefile b/hnvram/Makefile
index 2790f4d..badf27a 100644
--- a/hnvram/Makefile
+++ b/hnvram/Makefile
@@ -11,7 +11,7 @@
BINDIR=$(DESTDIR)$(PREFIX)/bin
HUMAX_UPGRADE_DIR ?= ../../../humax/misc/libupgrade
-CFLAGS += -g -Os -I$(HUMAX_UPGRADE_DIR) $(EXTRACFLAGS)
+CFLAGS += -g -Os -I$(HUMAX_UPGRADE_DIR) -I$(HUMAX_UPGRADE_DIR)/test $(EXTRACFLAGS)
LDFLAGS += -L$(HUMAX_UPGRADE_DIR) $(EXTRALDFLAGS)
all: hnvram
@@ -22,12 +22,16 @@
$(CC) $(CFLAGS) $(SRCS) -o $@ $(LDFLAGS) -lhmxupgrade
unit_test: test
-test: hnvram_test
- ./hnvram_test
+test: clean hnvram_unit_test hnvram_integration_test
+ ./hnvram_unit_test
+ ./hnvram_integration_test
-hnvram_test: hnvram_test.cc hnvram_main.c $(INCS)
+hnvram_unit_test: hnvram_test.cc hnvram_main.c $(INCS)
$(CPP) $(CFLAGS) hnvram_test.cc -o $@ $(LDFLAGS) -lgtest -lpthread
+hnvram_integration_test: hnvram_integration_test.cc
+ $(CPP) $(CFLAGS) hnvram_integration_test.cc -o $@ $(LDFLAGS) -lgtest -lpthread
+
install:
mkdir -p $(BINDIR)
cp hnvram $(BINDIR)/hnvram_binary
@@ -36,4 +40,4 @@
@echo "No libs to install."
clean:
- rm -f hnvram hnvram_test *.o
+ rm -f hnvram hnvram_unit_test hnvram_integration_test *.o
diff --git a/hnvram/hnvram_integration_test.cc b/hnvram/hnvram_integration_test.cc
new file mode 100644
index 0000000..b7ceda1
--- /dev/null
+++ b/hnvram/hnvram_integration_test.cc
@@ -0,0 +1,205 @@
+// Copyright 2016 Google Inc. All Rights Reserved.
+// Author: germuth@google.com (Aaron Germuth)
+
+// Tests external methods of hnvram_main end-to-end. No stubbing of lower-level
+// methods (Black box testing)
+
+#include <stdio.h>
+#include "gtest/gtest.h"
+#include "hmx_upgrade_nvram.h"
+
+#define TEST_MAIN
+#include "hnvram_main.c"
+#include "hmx_test_base.cc"
+#include "hmx_upgrade_nvram.c"
+#include "hmx_upgrade_flash.c"
+
+// Test constants
+const char* name = "NEW_VAR";
+const char* val = "ABCDEF";
+const char* val2 = "ZZZZZZZZZ";
+const int valLen = 6;
+const int valLen2 = 9;
+
+const char* fieldName = "MAC_ADDR_BT";
+const char* fieldVal = "\x01\x02\x03\x04\x05\x06";
+const char* fieldValStr = "01:02:03:04:05:06";
+const char* fieldVal2 = "12:34:56:78:0a:bc";
+const int fieldValLen = 6;
+
+// Test parameters
+const HMX_NVRAM_PARTITION_E partitions[] =
+ {HMX_NVRAM_PARTITION_RO, HMX_NVRAM_PARTITION_RW};
+HMX_NVRAM_PARTITION_E part;
+
+class HnvramIntegrationTest : public HnvramTest,
+ public ::testing::WithParamInterface<HMX_NVRAM_PARTITION_E> {
+ public:
+ HnvramIntegrationTest() {}
+ virtual ~HnvramIntegrationTest() {}
+
+ virtual void SetUp() {
+ part = GetParam();
+
+ libupgrade_verbose = 0;
+ can_add_flag = 0;
+
+ HnvramTest::SetUp();
+
+ HMX_NVRAM_Init(hnvramFileName);
+ }
+
+ virtual void TearDown() {
+ part = HMX_NVRAM_PARTITION_UNSPECIFIED;
+
+ // clear dlists
+ drv_NVRAM_Delete(HMX_NVRAM_PARTITION_RO, (unsigned char*)fieldName);
+ drv_NVRAM_Delete(HMX_NVRAM_PARTITION_RW, (unsigned char*)name);
+ drv_NVRAM_Delete(HMX_NVRAM_PARTITION_RO, (unsigned char*)name);
+
+ HnvramTest::TearDown();
+ }
+};
+
+TEST_P(HnvramIntegrationTest, TestWriteNvramNew) {
+ // Should fail without can_add
+ EXPECT_EQ(-1, write_nvram_new(name, val, part));
+
+ // Should fail to parse
+ can_add_flag = 1;
+ char valLarge[NVRAM_MAX_DATA + 1];
+ memset(valLarge, 1, sizeof(valLarge));
+ EXPECT_EQ(-2, write_nvram_new(name, valLarge, part));
+
+ // Should fail cleanly with bad partition
+ HMX_NVRAM_Init("/tmp/");
+ EXPECT_EQ(-3, write_nvram_new(name, val, part));
+
+ // Read back writes
+ HMX_NVRAM_Init(hnvramFileName);
+ unsigned char read[255];
+ unsigned int readLen = 0;
+ EXPECT_EQ(0, write_nvram_new(name, val, part));
+ EXPECT_EQ(DRV_OK,
+ HMX_NVRAM_Read(part, (unsigned char*)name, 0,
+ read, sizeof(read), &readLen));
+ EXPECT_EQ(0, memcmp(val, read, valLen));
+ EXPECT_EQ(valLen, readLen);
+}
+
+TEST_P(HnvramIntegrationTest, TestWriteNvram) {
+ // Should fail with large val
+ char valLarge[NVRAM_MAX_DATA + 1];
+ memset(valLarge, 1, sizeof(valLarge));
+ EXPECT_EQ(-1, write_nvram(name, valLarge, part));
+
+ // Failure to parse
+ EXPECT_EQ(-2, write_nvram(fieldName, "not-proper-mac-addr", part));
+
+ // Variable doesn't already exist
+ EXPECT_EQ(-3, write_nvram(name, val, part));
+
+ // Variable exists in wrong partition
+ can_add_flag = 1;
+ EXPECT_EQ(0, write_nvram_new(name, val, part));
+ EXPECT_EQ(-4, write_nvram(name, val, HMX_NVRAM_PARTITION_W_RAWFS));
+
+ // Fail cleanly from lower-level write
+ HMX_NVRAM_Init("/tmp/");
+ EXPECT_EQ(-5, write_nvram(name, val, part));
+ HMX_NVRAM_Init(hnvramFileName);
+
+ // Try to specify partition with a field variable
+ EXPECT_EQ(0, write_nvram_new(fieldName, fieldVal, part));
+ HMX_NVRAM_Init(hnvramFileName);
+ EXPECT_EQ(-6, write_nvram(fieldName, fieldVal2, part));
+
+ // Failure from lower-level write w/field
+ HMX_NVRAM_Init("/tmp/");
+ char out[255];
+ EXPECT_EQ(-7, write_nvram(fieldName, fieldValStr,
+ HMX_NVRAM_PARTITION_UNSPECIFIED));
+ HMX_NVRAM_Init(hnvramFileName);
+
+ // Read back val after changing val
+ EXPECT_EQ(0, write_nvram(name, val2, part));
+ unsigned char read[255];
+ unsigned int readLen = 0;
+ EXPECT_EQ(DRV_OK, HMX_NVRAM_Read(part, (unsigned char*)name, 0,
+ read, sizeof(read), &readLen));
+ EXPECT_EQ(0, memcmp(read, val2, readLen));
+ EXPECT_EQ(readLen, valLen2);
+}
+
+TEST_P(HnvramIntegrationTest, TestClearNvram) {
+ // Delete non-existing variable
+ HMX_NVRAM_Init(hnvramFileName);
+ EXPECT_EQ(DRV_OK, clear_nvram(name));
+
+ can_add_flag = 1;
+ EXPECT_EQ(0, write_nvram_new(name, val, part));
+
+ // No hnvram partition
+ HMX_NVRAM_Init("/tmp/");
+ EXPECT_EQ(DRV_ERR, clear_nvram(name));
+
+ // Delete Existing
+ HMX_NVRAM_Init(hnvramFileName);
+ EXPECT_EQ(DRV_OK, clear_nvram(name));
+}
+
+TEST_P(HnvramIntegrationTest, TestReadNvram) {
+ char readR[255];
+ memset(readR, 56, 30);
+ HMX_NVRAM_PARTITION_E part_used;
+ EXPECT_TRUE(NULL == read_nvram(fieldName, readR, sizeof(readR), 0, &part_used));
+
+ // No variable to find
+ EXPECT_EQ(NULL, read_nvram(name, readR, sizeof(readR), 0, &part_used));
+
+ // Find field
+ can_add_flag = 1;
+ EXPECT_EQ(0, write_nvram_new(fieldName, fieldVal, HMX_NVRAM_PARTITION_RO));
+ EXPECT_FALSE(NULL == read_nvram(fieldName, readR, sizeof(readR), 1, &part_used));
+ EXPECT_EQ(0, memcmp(readR, fieldValStr, 18));
+ EXPECT_EQ(part_used, HMX_NVRAM_PARTITION_RO);
+
+ // Find variable
+ EXPECT_EQ(0, write_nvram_new(name, val, part));
+ EXPECT_FALSE(NULL == read_nvram(name, readR, sizeof(readR), 1, &part_used));
+ EXPECT_EQ(0, memcmp(readR, val, valLen));
+ EXPECT_EQ(part_used, part);
+}
+
+TEST_P(HnvramIntegrationTest, TestInitNvram) {
+ char readR[255];
+ HMX_NVRAM_PARTITION_E part_used;
+
+ // Set envvar to bad file
+ EXPECT_EQ(0, setenv("HNVRAM_LOCATION", "/tmp/", 1));
+ EXPECT_EQ(DRV_OK, init_nvram());
+
+ // Should fail to read
+ EXPECT_TRUE(NULL == read_nvram(name, readR, sizeof(readR), 1, &part_used));
+
+ // Set envvar to proper, empty file
+ EXPECT_EQ(0, setenv("HNVRAM_LOCATION", hnvramFileName, 1));
+ EXPECT_EQ(DRV_OK, init_nvram());
+
+ // Write and read it back
+ can_add_flag = 1;
+ EXPECT_EQ(0, write_nvram_new(name, val, part));
+
+ EXPECT_FALSE(NULL == read_nvram(name, readR, sizeof(readR), 1, &part_used));
+ EXPECT_EQ(0, memcmp(readR, val, valLen));
+ EXPECT_EQ(part_used, part);
+}
+
+INSTANTIATE_TEST_CASE_P(TryAllPartitions, HnvramIntegrationTest,
+ ::testing::ValuesIn(partitions));
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ ::testing::AddGlobalTestEnvironment(new HnvramEnvironment);
+ return RUN_ALL_TESTS();
+}
diff --git a/hnvram/hnvram_main.c b/hnvram/hnvram_main.c
index a406caa..4ba0cde 100644
--- a/hnvram/hnvram_main.c
+++ b/hnvram/hnvram_main.c
@@ -42,6 +42,8 @@
printf("\t-n : toggles whether -w can create new variables. Default is off\n");
printf("\t-p [RW|RO] : toggles what partition new writes (-n) used. Default is RW\n");
printf("\t-k VARNAME : delete existing key/value pair from NVRAM.\n");
+ printf("\t Set environment variable: $HNVRAM_LOCATION to change where read/writes are performed.");
+ printf("\t By default hnvram uses '/dev/mtd/hnvram'\n");
}
// Format of data in the NVRAM
@@ -369,7 +371,7 @@
return NULL;
}
-DRV_Error clear_nvram(char* optarg) {
+DRV_Error clear_nvram(const char* optarg) {
DRV_Error err1 = HMX_NVRAM_Remove(HMX_NVRAM_PARTITION_RW,
(unsigned char*)optarg);
DRV_Error err2 = HMX_NVRAM_Remove(HMX_NVRAM_PARTITION_RO,
@@ -387,7 +389,8 @@
}
-int write_nvram(char* name, char* value, HMX_NVRAM_PARTITION_E desired_part) {
+int write_nvram(const char* name, const char* value,
+ HMX_NVRAM_PARTITION_E desired_part) {
const hnvram_field_t* field = get_nvram_field(name);
int is_field = (field != NULL);
@@ -400,8 +403,8 @@
if (strlen(value) > NVRAM_MAX_DATA) {
fprintf(stderr, "Value length %d exceeds maximum data size of %d\n",
- strlen(value), NVRAM_MAX_DATA);
- return -2;
+ (int)strlen(value), NVRAM_MAX_DATA);
+ return -1;
}
unsigned char nvram_value[NVRAM_MAX_DATA];
@@ -444,18 +447,18 @@
}
// Adds new variable to HNVRAM in desired_partition as STRING
-int write_nvram_new(char* name, char* value,
+int write_nvram_new(const char* name, const char* value,
HMX_NVRAM_PARTITION_E desired_part) {
+ if (!can_add_flag) {
+ fprintf(stderr, "Key not found in NVRAM. Add -n to allow creation %s\n",
+ name);
+ return -1;
+ }
+
char tmp[NVRAM_MAX_DATA] = {0};
unsigned char nvram_value[NVRAM_MAX_DATA];
unsigned int nvram_len = sizeof(nvram_value);
if (parse_nvram(HNVRAM_STRING, value, nvram_value, &nvram_len) == NULL) {
- return -1;
- }
-
- if (!can_add_flag) {
- fprintf(stderr, "Key not found in NVRAM. Add -n to allow creation %s\n",
- name);
return -2;
}
@@ -472,13 +475,19 @@
return 0;
}
+int init_nvram() {
+ const char* location = secure_getenv("HNVRAM_LOCATION");
+ return (int)HMX_NVRAM_Init(location);
+}
+
int hnvram_main(int argc, char* const argv[]) {
DRV_Error err;
libupgrade_verbose = 0;
- if ((err = HMX_NVRAM_Init()) != DRV_OK) {
- fprintf(stderr, "NVRAM Init failed: %d\n", err);
+ int ret = init_nvram();
+ if (ret != 0) {
+ fprintf(stderr, "NVRAM Init failed: %d\n", ret);
exit(1);
}
@@ -524,13 +533,13 @@
char* value = equal + 1;
int ret = write_nvram(name, value, desired_part);
- if (ret == -3 && can_add_flag) {
- // key not found, and we are authorized to add a new one
+ if (ret == -3) {
+ // key not found, try to add a new one
ret = write_nvram_new(name, value, desired_part);
}
if (ret != 0) {
- fprintf(stderr, "Unable to write %s\n", duparg);
+ fprintf(stderr, "Err %d: Unable to write %s\n", ret, duparg);
free(duparg);
exit(1);
}
diff --git a/hnvram/hnvram_test.cc b/hnvram/hnvram_test.cc
index 643a436..dbc05a1 100644
--- a/hnvram/hnvram_test.cc
+++ b/hnvram/hnvram_test.cc
@@ -85,7 +85,7 @@
return HMX_NVRAM_SetField_Return;
}
-DRV_Error HMX_NVRAM_Init(void) {
+DRV_Error HMX_NVRAM_Init(const char* target_mtd) {
return DRV_OK;
}