]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[5584] Checkpoint: core code and test done
authorFrancis Dupont <fdupont@isc.org>
Thu, 21 Jun 2018 23:05:09 +0000 (01:05 +0200)
committerFrancis Dupont <fdupont@isc.org>
Thu, 21 Jun 2018 23:05:09 +0000 (01:05 +0200)
24 files changed:
src/bin/admin/kea-admin.in
src/bin/admin/tests/cql_tests.sh.in
src/bin/admin/tests/data/cql.lease4_dump_test.reference.csv
src/bin/admin/tests/data/cql.lease6_dump_test.reference.csv
src/bin/admin/tests/data/mysql.lease4_dump_test.reference.csv
src/bin/admin/tests/data/mysql.lease6_dump_test.reference.csv
src/bin/admin/tests/data/pgsql.lease4_dump_test.reference.csv
src/bin/admin/tests/data/pgsql.lease6_dump_test.reference.csv
src/bin/admin/tests/mysql_tests.sh.in
src/bin/admin/tests/pgsql_tests.sh.in
src/lib/dhcpsrv/cql_lease_mgr.cc
src/lib/dhcpsrv/lease.cc
src/lib/dhcpsrv/tests/csv_lease_file4_unittest.cc
src/lib/dhcpsrv/tests/csv_lease_file6_unittest.cc
src/lib/dhcpsrv/tests/generic_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/lease_file_loader_unittest.cc
src/lib/dhcpsrv/tests/lease_unittest.cc
src/lib/dhcpsrv/tests/memfile_lease_mgr_unittest.cc
src/lib/dhcpsrv/tests/test_utils.cc
src/share/database/scripts/cql/upgrade_2.0_to_3.0.sh.in
src/share/database/scripts/mysql/dhcpdb_create.mysql
src/share/database/scripts/mysql/upgrade_6.0_to_6.1.sh.in
src/share/database/scripts/pgsql/dhcpdb_create.pgsql
src/share/database/scripts/pgsql/upgrade_4.0_to_4.1.sh.in

index 4be383ddb4e17383172bd3586d921c14c840fc1e..885d1a4765a6930a7f1bf4fd3c98e29bb7e31a5d 100644 (file)
@@ -490,9 +490,9 @@ cql_dump() {
     # Get the query appropriate to lease version. Explicitly specify all columns
     # so that they are returned in expected order.
     if [ $dump_type -eq 4 ]; then
-        dump_query="SELECT address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state FROM lease4"
+        dump_query="SELECT address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context FROM lease4"
     elif [ $dump_type -eq 6 ]; then
-        dump_query="SELECT address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state FROM lease6"
+        dump_query="SELECT address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state,user_context FROM lease6"
     else
         log_error "lease-dump: lease type ( -4 or -6 ) needs to be specified"
         usage
index 0478fd87f80342f1c81efe58a76abf7a94dcc561..082101ad9f3b1c3de56c40db240093aed9f7efbb 100644 (file)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-# Copyright (C) 2014-2017 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2014-2018 Internet Systems Consortium, Inc. ("ISC")
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -40,11 +40,11 @@ cql_lease_init_test() {
     assert_eq 0 $? "schema_version table check failed, expected exit code: %d, actual: %d"
 
     # Check lease4 table
-    cql_execute "SELECT address, hwaddr, client_id, valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, state FROM lease4;"
+    cql_execute "SELECT address, hwaddr, client_id, valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, state, user_context FROM lease4;"
     assert_eq 0 $? "lease4 table check failed, expected exit code: %d, actual: %d"
 
     # Check lease6 table
-    cql_execute "SELECT address, duid, valid_lifetime, expire, subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, state FROM lease6;"
+    cql_execute "SELECT address, duid, valid_lifetime, expire, subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, state, user_context FROM lease6;"
     assert_eq 0 $? "lease6 table check failed, expected exit code: %d, actual: %d"
 
     # Check lease6_types table
@@ -82,7 +82,7 @@ cql_lease_version_test() {
 
     # Verify that kea-admin lease-version returns the correct version.
     version=$($keaadmin lease-version cql -u $db_user -p $db_password -n $db_name)
-    assert_str_eq "2.0" $version "Expected kea-admin to return %s, returned value was %s"
+    assert_str_eq "3.0" $version "Expected kea-admin to return %s, returned value was %s"
 
     # Wipe the database.
     cql_execute_script $db_scripts_dir/cql/dhcpdb_drop.cql
@@ -152,16 +152,16 @@ cql_lease4_dump_test() {
     # 1436173267 corresponds to 2015-06-06 11:01:07
     insert_cql="\
 INSERT INTO lease4(address, hwaddr, client_id, valid_lifetime, expire, subnet_id,\
- fqdn_fwd, fqdn_rev, hostname, state)\
+ fqdn_fwd, fqdn_rev, hostname, state, user_context)\
  VALUES(-1073741302,textAsBlob('20'),textAsBlob('30'),40,1430694930,50,true,true,\
- 'one.example.com', 0);\
+ 'one.example.com', 0, '');\
 INSERT INTO lease4(address, hwaddr, client_id, valid_lifetime, expire, subnet_id,\
- fqdn_fwd, fqdn_rev, hostname, state)\
- VALUES(-1073741301,NULL,textAsBlob('123'),40,1433464245,50,true,true,'', 1);\
+ fqdn_fwd, fqdn_rev, hostname, state, user_context)\
+ VALUES(-1073741301,NULL,textAsBlob('123'),40,1433464245,50,true,true,'', 1, '');\
 INSERT INTO lease4(address, hwaddr, client_id, valid_lifetime, expire, subnet_id,\
- fqdn_fwd, fqdn_rev, hostname, state)\
+ fqdn_fwd, fqdn_rev, hostname, state, user_context)\
  VALUES(-1073741300,textAsBlob('22'),NULL,40,1436173267,50,true,true,\
- 'three.example.com', 2);"
+ 'three.example.com', 2, '');"
 
     cql_execute "$insert_cql"
     assert_eq 0 $? "insert into lease4 failed, expected exit code %d, actual %d"
@@ -222,19 +222,19 @@ cql_lease6_dump_test() {
     insert_cql="\
 INSERT INTO lease6(address, duid, valid_lifetime, expire, subnet_id,\
  pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname,\
- hwaddr, hwtype, hwaddr_source, state)\
+ hwaddr, hwtype, hwaddr_source, state, user_context)\
  VALUES('2001:db8::10',textAsBlob('20'),30,1430694930,40,50,1,60,70,true,true,\
- 'one.example.com',textAsBlob('80'),90,16,0);\
+ 'one.example.com',textAsBlob('80'),90,16,0,'');\
 INSERT INTO lease6(address, duid, valid_lifetime, expire, subnet_id,\
  pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname,\
- hwaddr, hwtype, hwaddr_source, state)\
+ hwaddr, hwtype, hwaddr_source, state, user_context)\
  VALUES('2001:db8::11',NULL,30,1433464245,40,50,1,60,70,true,true,\
- '',textAsBlob('80'),90,1,1);\
+ '',textAsBlob('80'),90,1,1,'');\
 INSERT INTO lease6(address, duid, valid_lifetime, expire, subnet_id,\
  pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname,\
- hwaddr, hwtype, hwaddr_source, state)\
+ hwaddr, hwtype, hwaddr_source, state, user_context)\
  VALUES('2001:db8::12',textAsBlob('21'),30,1436173267,40,50,1,60,70,true,true,\
- 'three.example.com',textAsBlob('80'),90,4,2);"
+ 'three.example.com',textAsBlob('80'),90,4,2,'');"
 
     cql_execute "$insert_cql"
     assert_eq 0 $? "insert into lease6 failed, expected exit code %d, actual %d"
index 5316f1e734afde82819d300c2e4245ed912a3834..8da31db3ea0b2b97c1907e30a31cdcc344c32f8d 100644 (file)
@@ -1,4 +1,4 @@
-address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state
--1073741302,0x3230,0x3330,40,1430694930,50,True,True,one.example.com,0
--1073741301,null,0x313233,40,1433464245,50,True,True,,1
--1073741300,0x3232,null,40,1436173267,50,True,True,three.example.com,2
+address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context
+-1073741302,0x3230,0x3330,40,1430694930,50,True,True,one.example.com,0,
+-1073741301,null,0x313233,40,1433464245,50,True,True,,1,
+-1073741300,0x3232,null,40,1436173267,50,True,True,three.example.com,2,
index 63a966d137c59de7fcdc1ddc3c7c9da4de291027..5763429f4ca15f8cb79b01d730caae8c48664bec 100644 (file)
@@ -1,4 +1,4 @@
-address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state
-2001:db8::12,0x3231,30,1436173267,40,50,1,60,70,True,True,three.example.com,0x3830,90,4,2
-2001:db8::11,null,30,1433464245,40,50,1,60,70,True,True,,0x3830,90,1,1
-2001:db8::10,0x3230,30,1430694930,40,50,1,60,70,True,True,one.example.com,0x3830,90,16,0
+address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state,user_context
+2001:db8::12,0x3231,30,1436173267,40,50,1,60,70,True,True,three.example.com,0x3830,90,4,2,
+2001:db8::11,null,30,1433464245,40,50,1,60,70,True,True,,0x3830,90,1,1,
+2001:db8::10,0x3230,30,1430694930,40,50,1,60,70,True,True,one.example.com,0x3830,90,16,0,
index f7e8c711280f562ead0bbaad29562d0780df569f..0155cad0a342334bc41f7e3e6e6c4d16b9a92e7d 100644 (file)
@@ -1,4 +1,4 @@
-address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state
-0.0.0.10,3230,3330,40,2015-01-01 01:15:30,50,1,1,one.example.com,default
-0.0.0.11,,313233,40,2015-02-02 02:30:45,50,1,1,,declined
-0.0.0.12,3232,,40,2015-03-03 11:01:07,50,1,1,three.example.com,expired-reclaimed
+address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context
+0.0.0.10,3230,3330,40,2015-01-01 01:15:30,50,1,1,one.example.com,default,
+0.0.0.11,,313233,40,2015-02-02 02:30:45,50,1,1,,declined,
+0.0.0.12,3232,,40,2015-03-03 11:01:07,50,1,1,three.example.com,expired-reclaimed,
index 696a8919ca0133c321f23aab9d7bcf3a5e282dd2..92a003d8a7fa7b71232728303ac92ed82eed4f46 100644 (file)
@@ -1,4 +1,4 @@
-address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state
-10,3230,30,2015-04-04 01:15:30,40,50,IA_TA,60,70,1,1,one.example.com,3830,90,HWADDR_SOURCE_REMOTE_ID,default
-11,,30,2015-05-05 02:30:45,40,50,IA_TA,60,70,1,1,,3830,90,HWADDR_SOURCE_RAW,declined
-12,3231,30,2015-06-06 11:01:07,40,50,IA_TA,60,70,1,1,three.example.com,3830,90,HWADDR_SOURCE_DUID,expired-reclaimed
+address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state,user_context
+10,3230,30,2015-04-04 01:15:30,40,50,IA_TA,60,70,1,1,one.example.com,3830,90,HWADDR_SOURCE_REMOTE_ID,default,
+11,,30,2015-05-05 02:30:45,40,50,IA_TA,60,70,1,1,,3830,90,HWADDR_SOURCE_RAW,declined,
+12,3231,30,2015-06-06 11:01:07,40,50,IA_TA,60,70,1,1,three.example.com,3830,90,HWADDR_SOURCE_DUID,expired-reclaimed,
index c7a49034fff559ecacf153b91249718962c46600..b194fe6bbaa70b1139f87deb8c4c6506f1aa6301 100644 (file)
@@ -1,4 +1,4 @@
-address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state
-0.0.0.10,20,30,40,<timestamp1>,50,1,1,one.example.com,default
-0.0.0.11,,013233,40,<timestamp2>,50,1,1,,declined
-0.0.0.12,22,,40,<timestamp3>,50,1,1,three.example.com,expired-reclaimed
+address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context
+0.0.0.10,20,30,40,<timestamp1>,50,1,1,one.example.com,default,
+0.0.0.11,,013233,40,<timestamp2>,50,1,1,,declined,
+0.0.0.12,22,,40,<timestamp3>,50,1,1,three.example.com,expired-reclaimed,
index fb42171456646af9543dea0e0e6b3e384a7eb992..c88ab9e67d2e042dab641779f4e335e309009aa4 100644 (file)
@@ -1,4 +1,4 @@
-address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,state,hwaddr,hwtype,hwaddr_source
-10,20,30,<timestamp1>,40,50,IA_TA,60,70,1,1,one.example.com,default,80,90,HWADDR_SOURCE_REMOTE_ID
-11,,30,<timestamp2>,40,50,IA_TA,60,70,1,1,,declined,80,90,HWADDR_SOURCE_RAW
-12,21,30,<timestamp3>,40,50,IA_TA,60,70,1,1,three.example.com,expired-reclaimed,80,90,HWADDR_SOURCE_DUID
+address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,state,user_context,hwaddr,hwtype,hwaddr_source
+10,20,30,<timestamp1>,40,50,IA_TA,60,70,1,1,one.example.com,default,,80,90,HWADDR_SOURCE_REMOTE_ID
+11,,30,<timestamp2>,40,50,IA_TA,60,70,1,1,,declined,,80,90,HWADDR_SOURCE_RAW
+12,21,30,<timestamp3>,40,50,IA_TA,60,70,1,1,three.example.com,expired-reclaimed,,80,90,HWADDR_SOURCE_DUID
index 85c1a9558f2afcbee94f08d50202c38892021105..89988bcf7b12ac3c4b3926bc599fbff6b0ec46b2 100644 (file)
@@ -258,7 +258,7 @@ mysql_upgrade_test() {
 
     assert_str_eq "1.0" ${version} "Expected kea-admin to return %s, returned value was %s"
 
-    # Ok, we have a 1.0 database. Let's upgrade it to 6.0
+    # Ok, we have a 1.0 database. Let's upgrade it to 6.1
     ${keaadmin} lease-upgrade mysql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir
     ERRCODE=$?
 
@@ -449,9 +449,30 @@ EOF
 
     # lease4/6_stats changes are tested separately
 
-    # Verify upgraded schema reports version 6.0
+    #table: user_context to lease4 and lease6 (upgrade 6.0 -> 6.1)
+    # verify that lease4 table includes user_context
+    qry="select user_context from lease4";
+    count=`mysql_execute "${qry}"`
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "select user_context from lease4 failed. (expected status code %d, returned %d)"
+
+    # verify that lease6 table includes user_context
+    qry="select user_context from lease6";
+    count=`mysql_execute "${qry}"`
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "select user_context from lease6 failed. (expected status code %d, returned %d)"
+
+    #table: logs (upgrade 6.0 -> 6.1)
+    mysql -u$db_user -p$db_password $db_name >/dev/null 2>&1 <<EOF
+    SELECT timestamp, address, log FROM logs;
+EOF
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "logs table is missing or broken. (expected status code %d, returned %d)"
+
+    # Verify upgraded schema reports version 6.1
     version=$(${keaadmin} lease-version mysql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir)
-    assert_str_eq "6.0" ${version} "Expected kea-admin to return %s, returned value was %s"
+    assert_str_eq "6.1" ${version} "Expected kea-admin to return %s, returned value was %s"
+
 
     # Let's wipe the whole database
     mysql_wipe
@@ -492,9 +513,9 @@ mysql_lease4_dump_test() {
 
     # Insert the reference record
     insert_sql="\
-insert into lease4 values(10,20,30,40,'2015-01-01 01:15:30',50,1,1,'one.example.com', 0);\
-insert into lease4 values(11,NULL,123,40,'2015-02-02 02:30:45',50,1,1,'', 1);\
-insert into lease4 values(12,22,NULL,40,'2015-03-03 11:01:07',50,1,1,'three.example.com', 2);"
+insert into lease4 values(10,20,30,40,'2015-01-01 01:15:30',50,1,1,'one.example.com', 0,NULL);\
+insert into lease4 values(11,NULL,123,40,'2015-02-02 02:30:45',50,1,1,'', 1,NULL);\
+insert into lease4 values(12,22,NULL,40,'2015-03-03 11:01:07',50,1,1,'three.example.com', 2,NULL);"
 
     mysql_execute "$insert_sql"
     ERRCODE=$?
@@ -552,9 +573,9 @@ mysql_lease6_dump_test() {
 
     # Insert the reference record
     insert_sql="\
-insert into lease6 values(10,20,30,'2015-04-04 01:15:30',40,50,1,60,70,1,1,'one.example.com',80,90,16,0);\
-insert into lease6 values(11,NULL,30,'2015-05-05 02:30:45',40,50,1,60,70,1,1,'',80,90,1,1);\
-insert into lease6 values(12,21,30,'2015-06-06 11:01:07',40,50,1,60,70,1,1,'three.example.com',80,90,4,2);"
+insert into lease6 values(10,20,30,'2015-04-04 01:15:30',40,50,1,60,70,1,1,'one.example.com',80,90,16,0,NULL);\
+insert into lease6 values(11,NULL,30,'2015-05-05 02:30:45',40,50,1,60,70,1,1,'',80,90,1,1,NULL);\
+insert into lease6 values(12,21,30,'2015-06-06 11:01:07',40,50,1,60,70,1,1,'three.example.com',80,90,4,2,NULL);"
 
     mysql_execute "$insert_sql"
     ERRCODE=$?
index ef0854ef25c14abf1a73f84efb41919e3580e723..b7ca23e4680a29b008c31871ab2563951e30566c 100644 (file)
@@ -80,11 +80,11 @@ pgsql_lease_init_test() {
     assert_eq 0 $? "schema_version table check failed, expected exit code: %d, actual: %d"
 
     # Check lease4 table
-    RESULT=`pgsql_execute "SELECT address, hwaddr, client_id, valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, state FROM lease4;"`
+    RESULT=`pgsql_execute "SELECT address, hwaddr, client_id, valid_lifetime, expire, subnet_id, fqdn_fwd, fqdn_rev, hostname, state, user_context FROM lease4;"`
     assert_eq 0 $? "lease4 table check failed, expected exit code: %d, actual: %d"
 
     # Check lease6 table
-    RESULT=`pgsql_execute "SELECT address, duid, valid_lifetime, expire, subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, state FROM lease6;"`
+    RESULT=`pgsql_execute "SELECT address, duid, valid_lifetime, expire, subnet_id, pref_lifetime, lease_type, iaid, prefix_len, fqdn_fwd, fqdn_rev, hostname, state, user_context FROM lease6;"`
     assert_eq 0 $? "lease6 table check failed, expected exit code: %d, actual: %d"
 
     # Check lease6_types table
@@ -120,7 +120,7 @@ pgsql_lease_version_test() {
 
     # Verify that kea-admin lease-version returns the correct version
     version=$(${keaadmin} lease-version pgsql -u $db_user -p $db_password -n $db_name)
-    assert_str_eq "4.0" ${version} "Expected kea-admin to return %s, returned value was %s"
+    assert_str_eq "4.1" ${version} "Expected kea-admin to return %s, returned value was %s"
 
     # Let's wipe the whole database
     pgsql_wipe
@@ -230,10 +230,25 @@ pgsql_upgrade_2_0_to_3_0() {
     assert_eq 1 "$output" "lease_hwaddr_source does not contain entry for HWADDR_SOURCE_UNKNOWN. (record count %d, expected %d)"
 }
 
-pgsql_upgrade_3_0_to_4_0() {
-    # Verify upgraded schema reports version 4.0.
+pgsql_upgrade_3_0_to_4_1() {
+    # Verify upgraded schema reports version 4.1.
     version=$(${keaadmin} lease-version pgsql -u $db_user -p $db_password -n $db_name -d $db_scripts_dir)
-    assert_str_eq "4.0" ${version} "Expected kea-admin to return %s, returned value was %s"
+    assert_str_eq "4.1" ${version} "Expected kea-admin to return %s, returned value was %s"
+
+    # Added user_context to lease4
+    output=`pgsql_execute "select user_context from lease4;"`
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "lease4 is missing user_context column. (expected status code %d, returned %d)"
+
+    # Added user_context to lease6
+    output=`pgsql_execute "select user_context from lease6;"`
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "lease6 is missing user_context column. (expected status code %d, returned %d)"
+
+    # Added logs table
+    output=`pgsql_execute "select timestamp, address, log from logs;"`
+    ERRCODE=$?
+    assert_eq 0 $ERRCODE "logs table is missing or broken. (expected status code %d, returned %d)"
 }
 
 pgsql_upgrade_test() {
@@ -255,8 +270,8 @@ pgsql_upgrade_test() {
     # Check 2.0 to 3.0 upgrade
     pgsql_upgrade_2_0_to_3_0
 
-    # Check 3.0 to 4.0 upgrade
-    pgsql_upgrade_3_0_to_4_0
+    # Check 3.0 to 4.1 upgrade
+    pgsql_upgrade_3_0_to_4_1
 
     # Let's wipe the whole database
     pgsql_wipe
@@ -328,9 +343,9 @@ pgsql_lease4_dump_test() {
 
     # Insert the reference records
     insert_sql="\
-insert into lease4 values(10,E'\\x20',E'\\x30',40,'$timestamp1',50,'t','t','one.example.com', 0);\
-insert into lease4 values(11,'',E'\\x0123',40,'$timestamp2',50,'t','t','', 1);\
-insert into lease4 values(12,E'\\x22','',40,'$timestamp3',50,'t','t','three.example.com', 2);"
+insert into lease4 values(10,E'\\x20',E'\\x30',40,'$timestamp1',50,'t','t','one.example.com', 0, '');\
+insert into lease4 values(11,'',E'\\x0123',40,'$timestamp2',50,'t','t','', 1, '');\
+insert into lease4 values(12,E'\\x22','',40,'$timestamp3',50,'t','t','three.example.com', 2, '');"
 
     pgsql_execute "$insert_sql"
     ERRCODE=$?
@@ -423,9 +438,9 @@ pgsql_lease6_dump_test() {
 
     # Insert the reference records
     insert_sql="\
-insert into lease6 values(10,E'\\x20',30,'$timestamp1',40,50,1,60,70,'t','t','one.example.com', 0,decode('80','hex'),90,16);\
-insert into lease6 values(11,'',30,'$timestamp2',40,50,1,60,70,'t','t','', 1,decode('80','hex'),90,1);\
-insert into lease6 values(12,E'\\x21',30,'$timestamp3',40,50,1,60,70,'t','t','three.example.com', 2,decode('80','hex'),90,4);"
+insert into lease6 values(10,E'\\x20',30,'$timestamp1',40,50,1,60,70,'t','t','one.example.com', 0,decode('80','hex'),90,16,'');\
+insert into lease6 values(11,'',30,'$timestamp2',40,50,1,60,70,'t','t','', 1,decode('80','hex'),90,1,'');\
+insert into lease6 values(12,E'\\x21',30,'$timestamp3',40,50,1,60,70,'t','t','three.example.com', 2,decode('80','hex'),90,4,'');"
 
     pgsql_execute "$insert_sql"
     ERRCODE=$?
index 36e867547f8d9886ee2d6ea0c5ca23e3b9957810..1a3faadb0b712d644e580f4960ddb97c65e657e4 100644 (file)
@@ -676,8 +676,10 @@ CqlLease4Exchange::retrieve() {
         ConstElementPtr ctx;
         if (!user_context_.empty()) {
             ctx = Element::fromJSON(user_context_);
-            isc_throw(BadValue, "user context '" << user_context_
-                      << "' is not a JSON map");
+            if (!ctx || (ctx->getType() != Element::map)) {
+                isc_throw(BadValue, "user context '" << user_context_
+                          << "' is not a JSON map");
+            }
         }
 
         Lease4Ptr result(new Lease4(addr4, hwaddr, client_id_.data(),
@@ -1424,8 +1426,10 @@ CqlLease6Exchange::retrieve() {
         ConstElementPtr ctx;
         if (!user_context_.empty()) {
             ctx = Element::fromJSON(user_context_);
-            isc_throw(BadValue, "user context '" << user_context_
-                      << "' is not a JSON map");
+            if (!ctx ||(ctx->getType() != Element::map)) {
+                isc_throw(BadValue, "user context '" << user_context_
+                          << "' is not a JSON map");
+            }
         }
 
         // Create the lease and set the cltt (after converting from the
index b96613fe2d1443b9727ff710b7c15663e3389fe3..6b50a3858f8a94daa13675f81462616bbc271a5a 100644 (file)
@@ -545,7 +545,7 @@ Lease6::toText() const {
            << "State:         " << statesToText(state_) << "\n";
 
     if (getContext()) {
-        stream << "User context:  " << getContext() << "\n";
+        stream << "User context:  " << getContext()->str() << "\n";
     }
 
     return (stream.str());
@@ -566,7 +566,7 @@ Lease4::toText() const {
            << "State:         " << statesToText(state_) << "\n";
 
     if (getContext()) {
-        stream << "User context:  " << getContext() << "\n";
+        stream << "User context:  " << getContext()->str() << "\n";
     }
 
     return (stream.str());
index bac7f143e756abba9ae4200b5eb1faf7ee3701e2..d5fafd3bc45ad7203e3155b632a2a9484db4413d 100644 (file)
@@ -15,6 +15,7 @@
 
 using namespace isc;
 using namespace isc::asiolink;
+using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
 using namespace isc::util;
@@ -105,7 +106,7 @@ CSVLeaseFile4Test::writeSampleFile() const {
                   "host.example.com,0,\n"
                   "192.0.2.1,,a:11:01:04,200,200,8,1,1,host.example.com,0,\n"
                   "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,100,100,7,"
-                  "0,0,,1,\n");
+                  "0,0,,1,{ \"foobar\": true }\n");
 }
 
 // This test checks the capability to read and parse leases from the file.
@@ -143,6 +144,7 @@ TEST_F(CSVLeaseFile4Test, parse) {
     EXPECT_TRUE(lease->fqdn_rev_);
     EXPECT_EQ("host.example.com", lease->hostname_);
     EXPECT_EQ(Lease::STATE_DEFAULT, lease->state_);
+    EXPECT_FALSE(lease->getContext());
     }
 
     // Second lease is malformed - HW address is empty when state 
@@ -174,6 +176,8 @@ TEST_F(CSVLeaseFile4Test, parse) {
     EXPECT_FALSE(lease->fqdn_rev_);
     EXPECT_TRUE(lease->hostname_.empty());
     EXPECT_EQ(Lease::STATE_DECLINED, lease->state_);
+    ASSERT_TRUE(lease->getContext());
+    EXPECT_EQ("{ \"foobar\": true }", lease->getContext()->str());
     }
 
     // There are no more leases. Reading should cause no error, but the returned
@@ -216,11 +220,12 @@ TEST_F(CSVLeaseFile4Test, recreate) {
     checkStats(lf, 0, 0, 0, 1, 1, 0);
     }
 
-    // Create second lease, with non-NULL client id.
+    // Create second lease, with non-NULL client id and user context.
     lease.reset(new Lease4(IOAddress("192.0.3.10"),
                            hwaddr1_,
                            CLIENTID, sizeof(CLIENTID),
                            100, 60, 90, 0, 7));
+    lease->setContext(Element::fromJSON("{ \"foobar\": true }"));
     {
     SCOPED_TRACE("Second write");
     ASSERT_NO_THROW(lf.append(*lease));
@@ -235,7 +240,7 @@ TEST_F(CSVLeaseFile4Test, recreate) {
               "192.0.3.2,00:01:02:03:04:05,,200,200,8,1,1,host.example.com,"
               "2,\n"
               "192.0.3.10,0d:0e:0a:0d:0b:0e:0e:0f,01:02:03:04,100,100,7,0,"
-              "0,,0,\n",
+              "0,,0,{ \"foobar\": true }\n",
               io_.readFile());
 }
 
@@ -253,9 +258,9 @@ TEST_F(CSVLeaseFile4Test, mixedSchemaload) {
                   // schema 2.0 record - has state
                   "192.0.2.2,06:07:08:09:2a:bc,,200,200,8,1,1,"
                   "two.example.com,1\n"
-                  // schema 2.0 record - has state
+                  // schema 2.1 record - has state and user context
                   "192.0.2.3,06:07:08:09:3a:bc,,200,200,8,1,1,"
-                  "three.example.com,2\n"
+                  "three.example.com,2,{ \"foobar\": true }\n"
                    );
 
     // Open the lease file.
@@ -283,6 +288,7 @@ TEST_F(CSVLeaseFile4Test, mixedSchemaload) {
     EXPECT_EQ("one.example.com", lease->hostname_);
     // Verify that added state is DEFAULT
     EXPECT_EQ(Lease::STATE_DEFAULT, lease->state_);
+    EXPECT_FALSE(lease->getContext());
     }
 
     {
@@ -302,6 +308,7 @@ TEST_F(CSVLeaseFile4Test, mixedSchemaload) {
     EXPECT_TRUE(lease->fqdn_rev_);
     EXPECT_EQ("two.example.com", lease->hostname_);
     EXPECT_EQ(Lease::STATE_DECLINED, lease->state_);
+    EXPECT_FALSE(lease->getContext());
     }
 
     {
@@ -321,6 +328,8 @@ TEST_F(CSVLeaseFile4Test, mixedSchemaload) {
     EXPECT_TRUE(lease->fqdn_rev_);
     EXPECT_EQ("three.example.com", lease->hostname_);
     EXPECT_EQ(Lease::STATE_EXPIRED_RECLAIMED, lease->state_);
+    ASSERT_TRUE(lease->getContext());
+    EXPECT_EQ("{ \"foobar\": true }", lease->getContext()->str());
     }
 }
 
@@ -384,6 +393,7 @@ TEST_F(CSVLeaseFile4Test, downGrade) {
     EXPECT_TRUE(lease->fqdn_rev_);
     EXPECT_EQ("three.example.com", lease->hostname_);
     EXPECT_EQ(Lease::STATE_EXPIRED_RECLAIMED, lease->state_);
+    EXPECT_FALSE(lease->getContext());
     }
 }
 
index f35798d70b4cdd29116430550ffce82a2fd27823..74bda17ea544e8c6501e1e365044c01d8e3d328f 100644 (file)
@@ -15,6 +15,7 @@
 
 using namespace isc;
 using namespace isc::asiolink;
+using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
 using namespace isc::util;
@@ -107,7 +108,7 @@ CSVLeaseFile6Test::writeSampleFile() const {
                   "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,300,300,6,150,"
                   "0,8,0,0,0,,,1,\n"
                   "3000:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,0,200,8,0,2,"
-                  "16,64,0,0,,,1,\n");
+                  "16,64,0,0,,,1,{ \"foobar\": true }\n");
 }
 
 // This test checks the capability to read and parse leases from the file.
@@ -147,6 +148,8 @@ TEST_F(CSVLeaseFile6Test, parse) {
     EXPECT_TRUE(lease->fqdn_fwd_);
     EXPECT_TRUE(lease->fqdn_rev_);
     EXPECT_EQ("host.example.com", lease->hostname_);
+    EXPECT_EQ(Lease::STATE_DECLINED, lease->state_);
+    EXPECT_FALSE(lease->getContext());
     }
 
     // Second lease is malformed - DUID is empty.
@@ -178,6 +181,8 @@ TEST_F(CSVLeaseFile6Test, parse) {
     EXPECT_FALSE(lease->fqdn_fwd_);
     EXPECT_FALSE(lease->fqdn_rev_);
     EXPECT_TRUE(lease->hostname_.empty());
+    EXPECT_EQ(Lease::STATE_DECLINED, lease->state_);
+    EXPECT_FALSE(lease->getContext());
     }
 
     // Reading the fourth lease should be successful.
@@ -201,6 +206,9 @@ TEST_F(CSVLeaseFile6Test, parse) {
     EXPECT_FALSE(lease->fqdn_fwd_);
     EXPECT_FALSE(lease->fqdn_rev_);
     EXPECT_TRUE(lease->hostname_.empty());
+    EXPECT_EQ(Lease::STATE_DECLINED, lease->state_);
+    ASSERT_TRUE(lease->getContext());
+    EXPECT_EQ("{ \"foobar\": true }", lease->getContext()->str());
     }
 
     // There are no more leases. Reading should cause no error, but the returned
@@ -260,6 +268,7 @@ TEST_F(CSVLeaseFile6Test, recreate) {
                            7, 150, 300, 40, 70, 10, false, false,
                            "", HWAddrPtr(), 64));
     lease->cltt_ = 0;
+    lease->setContext(Element::fromJSON("{ \"foobar\": true }"));
     {
     SCOPED_TRACE("Third write");
     ASSERT_NO_THROW(lf.append(*lease));
@@ -274,7 +283,7 @@ TEST_F(CSVLeaseFile6Test, recreate) {
               "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05"
               ",300,300,6,150,0,8,128,0,0,,,0,\n"
               "3000:1:1::,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-              "300,300,10,150,2,7,64,0,0,,,0,\n",
+              "300,300,10,150,2,7,64,0,0,,,0,{ \"foobar\": true }\n",
               io_.readFile());
 }
 
@@ -296,7 +305,12 @@ TEST_F(CSVLeaseFile6Test, mixedSchemaLoad) {
 
               // schema 3.0 record - has hwaddr and state
               "2001:db8:1::3,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:03,"
-              "200,200,8,100,0,7,0,1,1,three.example.com,0a:0b:0c:0d:0e,1\n");
+              "200,200,8,100,0,7,0,1,1,three.example.com,0a:0b:0c:0d:0e,1\n"
+
+              // schema 3.1 record - has hwaddr, state and user context
+              "2001:db8:1::4,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:03,"
+              "200,200,8,100,0,7,0,1,1,three.example.com,0a:0b:0c:0d:0e,1,"
+              "{ \"foobar\": true }\n");
 
     // Open the lease file.
     CSVLeaseFile6 lf(filename_);
@@ -326,6 +340,7 @@ TEST_F(CSVLeaseFile6Test, mixedSchemaLoad) {
     EXPECT_FALSE(lease->hwaddr_);
     // Verify that added state is STATE_DEFAULT
     EXPECT_EQ(Lease::STATE_DEFAULT, lease->state_);
+    EXPECT_FALSE(lease->getContext());
     }
 
     {
@@ -351,6 +366,7 @@ TEST_F(CSVLeaseFile6Test, mixedSchemaLoad) {
     EXPECT_EQ("01:02:03:04:05", lease->hwaddr_->toText(false));
     // Verify that added state is STATE_DEFAULT
     EXPECT_EQ(Lease::STATE_DEFAULT, lease->state_);
+    EXPECT_FALSE(lease->getContext());
     }
 
     {
@@ -375,6 +391,33 @@ TEST_F(CSVLeaseFile6Test, mixedSchemaLoad) {
     ASSERT_TRUE(lease->hwaddr_);
     EXPECT_EQ("0a:0b:0c:0d:0e", lease->hwaddr_->toText(false));
     EXPECT_EQ(Lease::STATE_DECLINED, lease->state_);
+    EXPECT_FALSE(lease->getContext());
+    }
+
+    {
+    SCOPED_TRACE("Forth lease valid");
+    EXPECT_TRUE(lf.next(lease));
+    ASSERT_TRUE(lease);
+
+    // Verify that the lease attributes are correct.
+    EXPECT_EQ("2001:db8:1::4", lease->addr_.toText());
+    ASSERT_TRUE(lease->duid_);
+    EXPECT_EQ("00:01:02:03:04:05:06:0a:0b:0c:0d:0e:03", lease->duid_->toText());
+    EXPECT_EQ(200, lease->valid_lft_);
+    EXPECT_EQ(0, lease->cltt_);
+    EXPECT_EQ(8, lease->subnet_id_);
+    EXPECT_EQ(100, lease->preferred_lft_);
+    EXPECT_EQ(Lease::TYPE_NA, lease->type_);
+    EXPECT_EQ(7, lease->iaid_);
+    EXPECT_EQ(0, lease->prefixlen_);
+    EXPECT_TRUE(lease->fqdn_fwd_);
+    EXPECT_TRUE(lease->fqdn_rev_);
+    EXPECT_EQ("three.example.com", lease->hostname_);
+    ASSERT_TRUE(lease->hwaddr_);
+    EXPECT_EQ("0a:0b:0c:0d:0e", lease->hwaddr_->toText(false));
+    EXPECT_EQ(Lease::STATE_DECLINED, lease->state_);
+    ASSERT_TRUE(lease->getContext());
+    EXPECT_EQ("{ \"foobar\": true }", lease->getContext()->str());
     }
 
 }
@@ -412,10 +455,10 @@ TEST_F(CSVLeaseFile6Test, downGrade) {
               "lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,"
               "hwaddr,state,user_context,FUTURE_COL\n"
 
-              // schema 3.0 record - has hwaddr and state
+              // schema 3.1 record - has hwaddr, state and user context
               "2001:db8:1::3,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:03,"
-              "200,200,8,100,0,7,0,1,1,three.example.com,0a:0b:0c:0d:0e,1,,"
-              "BOGUS\n");
+              "200,200,8,100,0,7,0,1,1,three.example.com,0a:0b:0c:0d:0e,1,"
+              "{ \"foobar\": true },BOGUS\n");
 
     // Open should succeed in the event someone is downgrading.
     CSVLeaseFile6 lf(filename_);
@@ -448,6 +491,8 @@ TEST_F(CSVLeaseFile6Test, downGrade) {
     ASSERT_TRUE(lease->hwaddr_);
     EXPECT_EQ("0a:0b:0c:0d:0e", lease->hwaddr_->toText(false));
     EXPECT_EQ(Lease::STATE_DECLINED, lease->state_);
+    ASSERT_TRUE(lease->getContext());
+    EXPECT_EQ("{ \"foobar\": true }", lease->getContext()->str());
     }
 }
 
index ed1208fe2149d8a46b89612fe8541312e2fea353..62f5feb9e8a9745de2a981bb73b517f0b8ba6775 100644 (file)
@@ -22,6 +22,7 @@
 
 using namespace std;
 using namespace isc::asiolink;
+using namespace isc::data;
 
 namespace isc {
 namespace dhcp {
@@ -156,6 +157,8 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         lease->fqdn_rev_ = false;
         lease->fqdn_fwd_ = false;
         lease->hostname_ = "otherhost.example.com.";
+        lease->setContext(Element::fromJSON("{ \"foo\": true }"));
+
     } else if (address == straddress4_[6]) {
         lease->hwaddr_.reset(new HWAddr(vector<uint8_t>(6, 0x6e), HTYPE_ETHER));
         // Same ClientId as straddress4_1
@@ -177,6 +180,7 @@ GenericLeaseMgrTest::initializeLease4(std::string address) {
         lease->fqdn_rev_ = true;
         lease->fqdn_fwd_ = true;
         lease->hostname_ = "myhost.example.com.";
+        lease->setContext(Element::fromJSON("{ \"bar\": false }"));
 
     } else {
         // Unknown address, return an empty pointer.
@@ -288,6 +292,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         lease->fqdn_fwd_ = false;
         lease->fqdn_rev_ = true;
         lease->hostname_ = "hostname.example.com.";
+        lease->setContext(Element::fromJSON("{ \"foo\": true }"));
 
     } else if (address == straddress6_[6]) {
         // Same DUID as straddress6_1
@@ -317,6 +322,7 @@ GenericLeaseMgrTest::initializeLease6(std::string address) {
         lease->fqdn_fwd_ = false;
         lease->fqdn_rev_ = true;
         lease->hostname_ = "hostname.example.com.";
+        lease->setContext(Element::fromJSON("{ \"bar\": false }"));
 
     } else {
         // Unknown address, return an empty pointer.
@@ -533,6 +539,17 @@ GenericLeaseMgrTest::testGetLease4HWAddr2() {
     // Should be three leases, matching leases[1], [3] and [5].
     ASSERT_EQ(3, returned.size());
 
+    // Check the lease[5] (and only this one) has an user context.
+    size_t contexts = 0;
+    for (Lease4Collection::const_iterator i = returned.begin();
+         i != returned.end(); ++i) {
+        if ((*i)->getContext()) {
+            ++contexts;
+            EXPECT_EQ("{ \"foo\": true }", (*i)->getContext()->str());
+        }
+    }
+    EXPECT_EQ(1, contexts);
+
     // Easiest way to check is to look at the addresses.
     vector<string> addresses;
     for (Lease4Collection::const_iterator i = returned.begin();
@@ -708,6 +725,7 @@ void
 GenericLeaseMgrTest::testBasicLease4() {
     // Get the leases to be used for the test.
     vector<Lease4Ptr> leases = createLeases4();
+    leases[2]->setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
 
     // Start the tests.  Add three leases to the database, read them back and
     // check they are what we think they are.
@@ -785,6 +803,7 @@ void
 GenericLeaseMgrTest::testBasicLease6() {
     // Get the leases to be used for the test.
     vector<Lease6Ptr> leases = createLeases6();
+    leases[2]->setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
 
     // Start the tests.  Add three leases to the database, read them back and
     // check they are what we think they are.
@@ -1123,6 +1142,17 @@ GenericLeaseMgrTest::testGetLease4ClientId2() {
     // Should be four leases, matching leases[1], [4], [5] and [6].
     ASSERT_EQ(4, returned.size());
 
+    // Check the lease[5] (and only this one) has an user context.
+    size_t contexts = 0;
+    for (Lease4Collection::const_iterator i = returned.begin();
+         i != returned.end(); ++i) {
+        if ((*i)->getContext()) {
+            ++contexts;
+            EXPECT_EQ("{ \"foo\": true }", (*i)->getContext()->str());
+        }
+    }
+    EXPECT_EQ(1, contexts);
+
     // Easiest way to check is to look at the addresses.
     vector<string> addresses;
     for (Lease4Collection::const_iterator i = returned.begin();
@@ -1516,6 +1546,7 @@ GenericLeaseMgrTest::testUpdateLease4() {
     leases[1]->hostname_ = "modified.hostname.";
     leases[1]->fqdn_fwd_ = !leases[1]->fqdn_fwd_;
     leases[1]->fqdn_rev_ = !leases[1]->fqdn_rev_;;
+    leases[1]->setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
     lmptr_->updateLease4(leases[1]);
 
     // ... and check what is returned is what is expected.
@@ -1526,6 +1557,7 @@ GenericLeaseMgrTest::testUpdateLease4() {
     // Alter the lease again and check.
     ++leases[1]->subnet_id_;
     leases[1]->cltt_ += 6;
+    leases[1]->setContext(Element::fromJSON("{ \"foo\": \"bar\" }"));
     lmptr_->updateLease4(leases[1]);
 
     // Explicitly clear the returned pointer before getting new data to ensure
@@ -1572,6 +1604,7 @@ GenericLeaseMgrTest::testUpdateLease6() {
     leases[1]->hostname_ = "modified.hostname.v6.";
     leases[1]->fqdn_fwd_ = !leases[1]->fqdn_fwd_;
     leases[1]->fqdn_rev_ = !leases[1]->fqdn_rev_;;
+    leases[1]->setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
     lmptr_->updateLease6(leases[1]);
     lmptr_->commit();
 
@@ -1586,6 +1619,7 @@ GenericLeaseMgrTest::testUpdateLease6() {
     leases[1]->type_ = Lease::TYPE_TA;
     leases[1]->cltt_ += 6;
     leases[1]->prefixlen_ = 93;
+    leases[1]->setContext(Element::fromJSON("{ \"foo\": \"bar\" }"));
     lmptr_->updateLease6(leases[1]);
 
     l_returned.reset();
index 4ac5165df09171b6a5ce4e82911eec9d95621d40..1670f81087ee9eef2d48ac4b600820ae38f3b36f 100644 (file)
@@ -18,6 +18,7 @@
 
 using namespace isc;
 using namespace isc::asiolink;
+using namespace isc::data;
 using namespace isc::dhcp;
 using namespace isc::dhcp::test;
 
@@ -171,9 +172,11 @@ LeaseFileLoaderTest::absolutePath(const std::string& filename) {
 TEST_F(LeaseFileLoaderTest, loadWrite4) {
     std::string test_str;
     std::string a_1 = "192.0.2.1,06:07:08:09:0a:bc,,"
-                      "200,200,8,1,1,host.example.com,1,\n";
+                      "200,200,8,1,1,host.example.com,1,"
+                      "{ \"foobar\": true }\n";
     std::string a_2 = "192.0.2.1,06:07:08:09:0a:bc,,"
-                      "200,500,8,1,1,host.example.com,1,\n";
+                      "200,500,8,1,1,host.example.com,1,"
+                      "{ \"foobar\": true }\n";
 
     std::string b_1 = "192.0.3.15,dd:de:ba:0d:1b:2e:3e:4f,0a:00:01:04,"
                       "100,100,7,0,0,,1,\n";
@@ -212,6 +215,10 @@ TEST_F(LeaseFileLoaderTest, loadWrite4) {
     ASSERT_TRUE(lease);
     EXPECT_EQ(300, lease->cltt_);
 
+    // The lease for 192.0.2.1 should have user context.
+    ASSERT_TRUE(lease->getContext());
+    EXPECT_EQ("{ \"foobar\": true }", lease->getContext()->str());
+
     // The invalid entry should not be loaded.
     lease = getLease<Lease4Ptr>("192.0.2.3", storage);
     ASSERT_FALSE(lease);
@@ -222,6 +229,7 @@ TEST_F(LeaseFileLoaderTest, loadWrite4) {
     lease = getLease<Lease4Ptr>("192.0.3.15", storage);
     ASSERT_TRUE(lease);
     EXPECT_EQ(35, lease->cltt_);
+    EXPECT_FALSE(lease->getContext());
 
     test_str = v4_hdr_ + a_2 + b_2;
     writeLeases<Lease4, CSVLeaseFile4, Lease4Storage>(*lf, storage, test_str);
@@ -297,12 +305,14 @@ TEST_F(LeaseFileLoaderTest, loadWrite4LeaseRemove) {
 TEST_F(LeaseFileLoaderTest, loadWrite6) {
     std::string test_str;
     std::string a_1 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-                      "200,200,8,100,0,7,0,1,1,host.example.com,,1,\n";
+                      "200,200,8,100,0,7,0,1,1,host.example.com,,1,"
+                      "{ \"foobar\": true }\n";
     std::string a_2 = "2001:db8:1::1,,"
-                      "200,200,8,100,0,7,0,1,1,host.example.com,,1,\n";
+                      "200,200,8,100,0,7,0,1,1,host.example.com,,1,"
+                      "{ \"foobar\": true }\n";
     std::string a_3 = "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,"
-                      "200,400,8,100,0,7,0,1,1,host.example.com,,1,\n";
-
+                      "200,400,8,100,0,7,0,1,1,host.example.com,,1,"
+                      "{ \"foobar\": true }\n";
     std::string b_1 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
                       "300,300,6,150,0,8,0,0,0,,,1,\n";
     std::string b_2 = "2001:db8:2::10,01:01:01:01:0a:01:02:03:04:05,"
@@ -312,7 +322,6 @@ TEST_F(LeaseFileLoaderTest, loadWrite6) {
                       "100,200,8,0,2,16,64,0,0,,,1,\n";
 
 
-
     // Create a lease file with three valid leases: 2001:db8:1::1,
     // 3000:1:: and 2001:db8:2::10.
     test_str = v6_hdr_ + a_1 + a_2 + b_1 + c_1 + b_2 + a_3;
@@ -341,16 +350,22 @@ TEST_F(LeaseFileLoaderTest, loadWrite6) {
     ASSERT_TRUE(lease);
     EXPECT_EQ(200, lease->cltt_);
 
+    // The 2001:db8:1::1 should have user context.
+    ASSERT_TRUE(lease->getContext());
+    EXPECT_EQ("{ \"foobar\": true }", lease->getContext()->str());
+
     // The 3000:1:: lease should be present.
     lease = getLease<Lease6Ptr>("3000:1::", storage);
     ASSERT_TRUE(lease);
     EXPECT_EQ(100, lease->cltt_);
+    EXPECT_FALSE(lease->getContext());
 
     // The 2001:db8:2::10 should be present and the cltt should be
     // calculated according to the last entry in the lease file.
     lease = getLease<Lease6Ptr>("2001:db8:2::10", storage);
     ASSERT_TRUE(lease);
     EXPECT_EQ(500, lease->cltt_);
+    EXPECT_FALSE(lease->getContext());
 
     test_str = v6_hdr_ + a_3 + b_2 + c_1;
     writeLeases<Lease6, CSVLeaseFile6, Lease6Storage>(*lf, storage, test_str);
index a81719e50341419e2df092e7fbda3afd1d020484..8b3bac04f263a8f63bb8586e8df86051f5abfa55 100644 (file)
@@ -140,6 +140,7 @@ TEST_F(Lease4Test, constructor) {
         EXPECT_TRUE(lease.fqdn_fwd_);
         EXPECT_TRUE(lease.fqdn_rev_);
         EXPECT_EQ(Lease::STATE_DEFAULT, lease.state_);
+        EXPECT_FALSE(lease.getContext());
     }
 }
 
@@ -157,6 +158,9 @@ TEST_F(Lease4Test, copyConstructor) {
     // or the default state will be set for the copied lease.
     lease.state_ = Lease::STATE_DECLINED;
 
+    // Set an user context.
+    lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
+
     // Use copy constructor to copy the lease.
     Lease4 copied_lease(lease);
 
@@ -166,6 +170,11 @@ TEST_F(Lease4Test, copyConstructor) {
     // Client IDs are equal, but they should be in two distinct pointers.
     EXPECT_FALSE(lease.client_id_ == copied_lease.client_id_);
 
+    // User context are equal and point to the same object.
+    ASSERT_TRUE(copied_lease.getContext());
+    EXPECT_TRUE(lease.getContext() == copied_lease.getContext());
+    EXPECT_TRUE(*lease.getContext() == *copied_lease.getContext());
+
     // Hardware addresses are equal, but they should point to two objects,
     // each holding the same data. The content should be equal...
     EXPECT_TRUE(*lease.hwaddr_ == *copied_lease.hwaddr_);
@@ -194,6 +203,9 @@ TEST_F(Lease4Test, operatorAssign) {
     // or the default state will be set for the copied lease.
     lease.state_ = Lease::STATE_DECLINED;
 
+    // Set an user context.
+    lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
+
     // Create a default lease.
     Lease4 copied_lease;
     // Use assignment operator to assign new lease.
@@ -205,6 +217,11 @@ TEST_F(Lease4Test, operatorAssign) {
     // Client IDs are equal, but they should be in two distinct pointers.
     EXPECT_FALSE(lease.client_id_ == copied_lease.client_id_);
 
+    // User context are equal and point to the same object.
+    ASSERT_TRUE(copied_lease.getContext());
+    EXPECT_TRUE(lease.getContext() == copied_lease.getContext());
+    EXPECT_TRUE(*lease.getContext() == *copied_lease.getContext());
+
     // Hardware addresses are equal, but they should point to two objects,
     // each holding the same data. The content should be equal...
     EXPECT_TRUE(*lease.hwaddr_ == *copied_lease.hwaddr_);
@@ -294,6 +311,7 @@ TEST_F(Lease4Test, operatorEquals) {
     // Check when the leases are equal.
     Lease4 lease1(ADDRESS, hwaddr_, clientid_, VALID_LIFETIME, current_time, 0,
                   0, SUBNET_ID);
+    lease1.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
 
     // We need to make an explicit copy. Otherwise the second lease will just
     // store a pointer and we'll have two leases pointing to a single HWAddr
@@ -303,6 +321,7 @@ TEST_F(Lease4Test, operatorEquals) {
 
     Lease4 lease2(ADDRESS, hwcopy, clientid_copy, VALID_LIFETIME, current_time,
                   0, 0, SUBNET_ID);
+    lease2.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
     EXPECT_TRUE(lease1 == lease2);
     EXPECT_FALSE(lease1 != lease2);
 
@@ -394,6 +413,20 @@ TEST_F(Lease4Test, operatorEquals) {
     lease2.state_ += 1;
     EXPECT_TRUE(lease1 == lease2);  // Check that the reversion has made the
     EXPECT_FALSE(lease1 != lease2); // ... leases equal
+
+    lease1.setContext(Element::fromJSON("{ \"foobar\": 5678 }"));
+    EXPECT_FALSE(lease1 == lease2);
+    EXPECT_TRUE(lease1 != lease2);
+    lease1.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
+    EXPECT_TRUE(lease1 == lease2);  // Check that the reversion has made the
+    EXPECT_FALSE(lease1 != lease2); // ... leases equal
+
+    lease1.setContext(ConstElementPtr());
+    EXPECT_FALSE(lease1 == lease2);
+    EXPECT_TRUE(lease1 != lease2);
+    lease2.setContext(ConstElementPtr());
+    EXPECT_TRUE(lease1 == lease2);  // Check that no user context has mase the
+    EXPECT_FALSE(lease1 != lease2); // ... leases equal
 }
 
 // Verify that the client id can be returned as a vector object and if client
@@ -438,6 +471,7 @@ TEST_F(Lease4Test, toText) {
     const time_t current_time = 12345678;
     Lease4 lease(IOAddress("192.0.2.3"), hwaddr_, clientid_, 3600, 123,
                  456, current_time, 789);
+    lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
 
     std::stringstream expected;
     expected << "Address:       192.0.2.3\n"
@@ -448,13 +482,16 @@ TEST_F(Lease4Test, toText) {
              << "Hardware addr: " << hwaddr_->toText(false) << "\n"
              << "Client id:     " << clientid_->toText() << "\n"
              << "Subnet ID:     789\n"
-             << "State:         default\n";
+             << "State:         default\n"
+             << "User context:  { \"foobar\": 1234 }\n";
 
     EXPECT_EQ(expected.str(), lease.toText());
 
-    // Now let's try with a lease without hardware address and client identifier.
+    // Now let's try with a lease without hardware address, client identifier
+    // and user context.
     lease.hwaddr_.reset();
     lease.client_id_.reset();
+    lease.setContext(ConstElementPtr());
     expected.str("");
     expected << "Address:       192.0.2.3\n"
              << "Valid life:    3600\n"
@@ -474,6 +511,7 @@ TEST_F(Lease4Test, toElement) {
     const time_t current_time = 12345678;
     Lease4 lease(IOAddress("192.0.2.3"), hwaddr_, clientid_, 3600, 123,
                  456, current_time, 789, true, true, "urania.example.org");
+    lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
 
     std::string expected = "{"
         "\"client-id\": \"17:34:e2:ff:09:92:54\","
@@ -485,16 +523,36 @@ TEST_F(Lease4Test, toElement) {
         "\"ip-address\": \"192.0.2.3\","
         "\"state\": 0,"
         "\"subnet-id\": 789,"
+        "\"user-context\": { \"foobar\": 1234 },"
         "\"valid-lft\": 3600 "
         "}";
 
     runToElementTest<Lease4>(expected, lease);
 
-    // Now let's try with a lease without client-id.
+    // Now let's try with a lease without client-id and user context.
     lease.client_id_.reset();
+    lease.setContext(ConstElementPtr());
+
+    expected = "{"
+        "\"cltt\": 12345678,"
+        "\"fqdn-fwd\": true,"
+        "\"fqdn-rev\": true,"
+        "\"hostname\": \"urania.example.org\","
+        "\"hw-address\": \"08:00:2b:02:3f:4e\","
+        "\"ip-address\": \"192.0.2.3\","
+        "\"state\": 0,"
+        "\"subnet-id\": 789,"
+        "\"valid-lft\": 3600 "
+        "}";
+
+    runToElementTest<Lease4>(expected, lease);
+
+    // And to finish try with a comment.
+    lease.setContext(Element::fromJSON("{ \"comment\": \"a comment\" }"));
 
     expected = "{"
         "\"cltt\": 12345678,"
+        "\"comment\": \"a comment\","
         "\"fqdn-fwd\": true,"
         "\"fqdn-rev\": true,"
         "\"hostname\": \"urania.example.org\","
@@ -520,6 +578,7 @@ TEST_F(Lease4Test, fromElement) {
         "\"ip-address\": \"192.0.2.3\","
         "\"state\": 0,"
         "\"subnet-id\": 789,"
+        "\"user-context\": { \"foo\": \"bar\" },"
         "\"valid-lft\": 3600 "
         "}";
 
@@ -540,6 +599,8 @@ TEST_F(Lease4Test, fromElement) {
     EXPECT_TRUE(lease->fqdn_rev_);
     EXPECT_EQ("urania.example.org", lease->hostname_);
     EXPECT_EQ(Lease::STATE_DEFAULT, lease->state_);
+    ASSERT_TRUE(lease->getContext());
+    EXPECT_EQ("{ \"foo\": \"bar\" }", lease->getContext()->str());
 }
 
 // Test that specifying invalid values for a lease or not specifying
@@ -578,6 +639,10 @@ TEST_F(Lease4Test, fromElementInvalidValues) {
     testInvalidElement<Lease4>(json, "subnet-id", -5, false);
     testInvalidElement<Lease4>(json, "valid-lft", std::string("xyz"));
     testInvalidElement<Lease4>(json, "valid-lft", -3, false);
+    testInvalidElement<Lease4>(json, "user-context", "[ ]", false);
+    testInvalidElement<Lease4>(json, "user-context", 1234, false);
+    testInvalidElement<Lease4>(json, "user-context", false, false);
+    testInvalidElement<Lease4>(json, "user-context", "foo", false);
 }
 
 // Verify that decline() method properly clears up specific fields.
@@ -607,6 +672,7 @@ TEST_F(Lease4Test, decline) {
     EXPECT_FALSE(lease.fqdn_rev_);
     EXPECT_EQ(Lease::STATE_DECLINED, lease.state_);
     EXPECT_EQ(123, lease.valid_lft_);
+    EXPECT_FALSE(lease.getContext());
 }
 
 // Verify that the lease states are correctly returned in the textual format.
@@ -668,7 +734,7 @@ TEST(Lease6Test, Lease6ConstructorDefault) {
         EXPECT_FALSE(lease->fqdn_fwd_);
         EXPECT_FALSE(lease->fqdn_rev_);
         EXPECT_TRUE(lease->hostname_.empty());
-
+        EXPECT_FALSE(lease->getContext());
     }
 
     // Lease6 must be instantiated with a DUID, not with NULL pointer
@@ -745,6 +811,9 @@ TEST(Lease6Test, operatorEquals) {
     Lease6 lease2(Lease::TYPE_NA, addr, duid, iaid, 100, 200, 50, 80,
                                subnet_id);
 
+    lease1.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
+    lease2.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
+
     // cltt_ constructs with time(NULL), make sure they are always equal
     lease1.cltt_ = lease2.cltt_;
 
@@ -859,6 +928,20 @@ TEST(Lease6Test, operatorEquals) {
     lease2.state_ += 1;
     EXPECT_TRUE(lease1 == lease2);  // Check that the reversion has made the
     EXPECT_FALSE(lease1 != lease2); // ... leases equal
+
+    lease1.setContext(Element::fromJSON("{ \"foobar\": 5678 }"));
+    EXPECT_FALSE(lease1 == lease2);
+    EXPECT_TRUE(lease1 != lease2);
+    lease1.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
+    EXPECT_TRUE(lease1 == lease2);  // Check that the reversion has made the
+    EXPECT_FALSE(lease1 != lease2); // ... leases equal
+
+    lease1.setContext(ConstElementPtr());
+    EXPECT_FALSE(lease1 == lease2);
+    EXPECT_TRUE(lease1 != lease2);
+    lease2.setContext(ConstElementPtr());
+    EXPECT_TRUE(lease1 == lease2);  // Check that no user context has mase the
+    EXPECT_FALSE(lease1 != lease2); // ... leases equal
 }
 
 // Checks if lease expiration is calculated properly
@@ -941,6 +1024,7 @@ TEST(Lease6Test, decline) {
     EXPECT_FALSE(lease.fqdn_rev_);
     EXPECT_EQ(Lease::STATE_DECLINED, lease.state_);
     EXPECT_EQ(123, lease.valid_lft_);
+    EXPECT_FALSE(lease.getContext());
 }
 
 // Verify the behavior of the function which checks FQDN data for equality.
@@ -972,6 +1056,7 @@ TEST(Lease6Test, toText) {
                  400, 800, 100, 200, 5678, hwaddr, 128);
     lease.cltt_ = 12345678;
     lease.state_ = Lease::STATE_DECLINED;
+    lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
 
     std::stringstream expected;
     expected << "Type:          IA_NA(" << static_cast<int>(Lease::TYPE_NA) << ")\n"
@@ -984,12 +1069,14 @@ TEST(Lease6Test, toText) {
              << "DUID:          00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f\n"
              << "Hardware addr: " << hwaddr->toText(false) << "\n"
              << "Subnet ID:     5678\n"
-             << "State:         declined\n";
+             << "State:         declined\n"
+             << "User context:  { \"foobar\": 1234 }\n";
 
     EXPECT_EQ(expected.str(), lease.toText());
 
-    // Now let's try with a lease without hardware address.
+    // Now let's try with a lease without hardware address and user context.
     lease.hwaddr_.reset();
+    lease.setContext(ConstElementPtr());
     expected.str("");
     expected << "Type:          IA_NA(" << static_cast<int>(Lease::TYPE_NA) << ")\n"
              << "Address:       2001:db8::1\n"
@@ -1019,6 +1106,7 @@ TEST(Lease6Test, toElementAddress) {
     lease.cltt_ = 12345678;
     lease.state_ = Lease::STATE_DECLINED;
     lease.hostname_ = "urania.example.org";
+    lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
 
     std::string expected = "{"
         "\"cltt\": 12345678,"
@@ -1033,16 +1121,39 @@ TEST(Lease6Test, toElementAddress) {
         "\"state\": 1,"
         "\"subnet-id\": 5678,"
         "\"type\": \"IA_NA\","
+        "\"user-context\": { \"foobar\": 1234 },"
         "\"valid-lft\": 800"
         "}";
     
     runToElementTest<Lease6>(expected, lease);
 
-    // Now let's try with a lease without hardware address.
+    // Now let's try with a lease without hardware address and user context.
     lease.hwaddr_.reset();
+    lease.setContext(ConstElementPtr());
+
+    expected = "{"
+        "\"cltt\": 12345678,"
+        "\"duid\": \"00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f\","
+        "\"fqdn-fwd\": false,"
+        "\"fqdn-rev\": false,"
+        "\"hostname\": \"urania.example.org\","
+        "\"iaid\": 123456,"
+        "\"ip-address\": \"2001:db8::1\","
+        "\"preferred-lft\": 400,"
+        "\"state\": 1,"
+        "\"subnet-id\": 5678,"
+        "\"type\": \"IA_NA\","
+        "\"valid-lft\": 800"
+        "}";
+    
+    runToElementTest<Lease6>(expected, lease);
+
+    // And to finish try with a comment.
+    lease.setContext(Element::fromJSON("{ \"comment\": \"a comment\" }"));
 
     expected = "{"
         "\"cltt\": 12345678,"
+        "\"comment\": \"a comment\","
         "\"duid\": \"00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f\","
         "\"fqdn-fwd\": false,"
         "\"fqdn-rev\": false,"
@@ -1073,6 +1184,7 @@ TEST(Lease6Test, toElementPrefix) {
     lease.cltt_ = 12345678;
     lease.state_ = Lease::STATE_DEFAULT;
     lease.hostname_ = "urania.example.org";
+    lease.setContext(Element::fromJSON("{ \"foobar\": 1234 }"));
 
     ElementPtr l = lease.toElement();
 
@@ -1120,10 +1232,24 @@ TEST(Lease6Test, toElementPrefix) {
     ASSERT_TRUE(l->contains("hostname"));
     EXPECT_EQ("urania.example.org", l->get("hostname")->stringValue());
 
-    // Now let's try with a lease without hardware address.
+    ASSERT_TRUE(l->contains("user-context"));
+    EXPECT_EQ("{ \"foobar\": 1234 }", l->get("user-context")->str());
+
+    // Now let's try with a lease without hardware address or user context.
     lease.hwaddr_.reset();
+    lease.setContext(ConstElementPtr());
     l = lease.toElement();
     EXPECT_FALSE(l->contains("hw-address"));
+    EXPECT_FALSE(l->contains("user-context"));
+    EXPECT_FALSE(l->contains("comment"));
+
+    // And to finish try with a comment.
+    lease.setContext(Element::fromJSON("{ \"comment\": \"a comment\" }"));
+    l = lease.toElement();
+    EXPECT_FALSE(l->contains("hw-address"));
+    EXPECT_FALSE(l->contains("user-context"));
+    ASSERT_TRUE(l->contains("comment"));
+    EXPECT_EQ("a comment", l->get("comment")->stringValue());
 }
 
 // Verify that the IA_NA can be created from JSON.
@@ -1141,6 +1267,7 @@ TEST(Lease6Test, fromElementNA) {
         "\"state\": 1,"
         "\"subnet-id\": 5678,"
         "\"type\": \"IA_NA\","
+        "\"user-context\": { \"foobar\": 1234 },"
         "\"valid-lft\": 800"
         "}";
 
@@ -1159,6 +1286,8 @@ TEST(Lease6Test, fromElementNA) {
     EXPECT_FALSE(lease->fqdn_rev_);
     EXPECT_EQ("urania.example.org", lease->hostname_);
     EXPECT_EQ(Lease::STATE_DECLINED, lease->state_);
+    ASSERT_TRUE(lease->getContext());
+    EXPECT_EQ("{ \"foobar\": 1234 }", lease->getContext()->str());
 
     // IPv6 specific properties.
     EXPECT_EQ(Lease::TYPE_NA, lease->type_);
@@ -1169,7 +1298,7 @@ TEST(Lease6Test, fromElementNA) {
     EXPECT_EQ(400, lease->preferred_lft_);
 }
 
-// Verify that the IA_NA can be created from JSON.
+// Verify that the IA_PD can be created from JSON.
 TEST(Lease6Test, fromElementPD) {
     std::string json = "{"
         "\"cltt\": 12345678,"
@@ -1203,6 +1332,7 @@ TEST(Lease6Test, fromElementPD) {
     EXPECT_FALSE(lease->fqdn_rev_);
     EXPECT_EQ("urania.example.org", lease->hostname_);
     EXPECT_EQ(Lease::STATE_DEFAULT , lease->state_);
+    EXPECT_FALSE(lease->getContext());
 
     // IPv6 specific properties.
     EXPECT_EQ(Lease::TYPE_PD, lease->type_);
@@ -1262,6 +1392,10 @@ TEST(Lease6Test, fromElementInvalidValues) {
     testInvalidElement<Lease6>(json, "type", -3, false);
     testInvalidElement<Lease6>(json, "valid-lft", std::string("xyz"));
     testInvalidElement<Lease6>(json, "valid-lft", -3, false);
+    testInvalidElement<Lease6>(json, "user-context", "[ ]", false);
+    testInvalidElement<Lease6>(json, "user-context", 1234, false);
+    testInvalidElement<Lease6>(json, "user-context", false, false);
+    testInvalidElement<Lease6>(json, "user-context", "foo", false);
 }
 
 // Verify that the lease states are correctly returned in the textual format.
index 3b99cedbe472a6e7e3933f8de54aa02fc88fb42a..8d4a986ad65c89460e59e1d1f95847c53d8577f6 100644 (file)
@@ -504,14 +504,14 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup4) {
     // one lease, but two entries. One of the entries should be removed
     // as a result of lease file cleanup.
     std::string current_file_contents = new_file_contents +
-        "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1,\n"
+        "192.0.2.2,02:02:02:02:02:02,,200,200,8,1,1,,1,{ \"foo\": true }\n"
         "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,1,\n";
     LeaseFileIO current_file(getLeaseFilePath("leasefile4_0.csv"));
     current_file.writeFile(current_file_contents);
 
     std::string previous_file_contents = new_file_contents +
         "192.0.2.3,03:03:03:03:03:03,,200,200,8,1,1,,1,\n"
-        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1,\n";
+        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1,{ \"bar\": true }\n";
     LeaseFileIO previous_file(getLeaseFilePath("leasefile4_0.csv.2"));
     previous_file.writeFile(previous_file_contents);
 
@@ -556,7 +556,7 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup4) {
     // entry each.
     std::string result_file_contents = new_file_contents +
         "192.0.2.2,02:02:02:02:02:02,,200,800,8,1,1,,1,\n"
-        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1,\n";
+        "192.0.2.3,03:03:03:03:03:03,,200,800,8,1,1,,1,{ \"bar\": true }\n";
 
     // The LFC should have created a file with the two leases and moved it
     // to leasefile4_0.csv.2
@@ -584,13 +584,13 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup6) {
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,"
         "8,100,0,7,0,1,1,,,1,\n"
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
-        "8,100,0,7,0,1,1,,,1,\n";
+        "8,100,0,7,0,1,1,,,1,{ \"foo\": true }\n";
     LeaseFileIO current_file(getLeaseFilePath("leasefile6_0.csv"));
     current_file.writeFile(current_file_contents);
 
     std::string previous_file_contents = new_file_contents +
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,200,"
-        "8,100,0,7,0,1,1,,,1,\n"
+        "8,100,0,7,0,1,1,,,1,{ \"bar\": true }\n"
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
         "8,100,0,7,0,1,1,,,1,\n";
     LeaseFileIO previous_file(getLeaseFilePath("leasefile6_0.csv.2"));
@@ -639,7 +639,7 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCleanup6) {
     // entry each.
     std::string result_file_contents = new_file_contents +
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
-        "8,100,0,7,0,1,1,,,1,\n"
+        "8,100,0,7,0,1,1,,,1,{ \"foo\": true }\n"
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
         "8,100,0,7,0,1,1,,,1,\n";
 
@@ -771,7 +771,7 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCopy) {
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,200,"
         "8,100,0,7,0,1,1,,,1,\n"
         "2001:db8:1::1,00:01:02:03:04:05:06:0a:0b:0c:0d:0e:0f,200,800,"
-        "8,100,0,7,0,1,1,,,1,\n";
+        "8,100,0,7,0,1,1,,,1,{ \"foo\": true }\n";
     LeaseFileIO current_file(getLeaseFilePath("leasefile6_0.csv"));
     current_file.writeFile(current_file_contents);
 
@@ -781,7 +781,7 @@ TEST_F(MemfileLeaseMgrTest, leaseFileCopy) {
     // the same.
     std::string input_file_contents = new_file_contents +
         "2001:db8:1::2,01:01:01:01:01:01:01:01:01:01:01:01:01,200,800,"
-        "8,100,0,7,0,1,1,,,1,\n";
+        "8,100,0,7,0,1,1,,,1,{ \"foo\": true }\n";
     LeaseFileIO input_file(getLeaseFilePath("leasefile6_0.csv.1"));
     input_file.writeFile(input_file_contents);
 
index 0d7463280d59e5dd4c89a38986c1528edc6fc341..3634e4ceb63a0f1e0ac175485d9174526e801f3a 100644 (file)
@@ -54,6 +54,14 @@ detailCompareLease(const Lease4Ptr& first, const Lease4Ptr& second) {
     EXPECT_EQ(first->fqdn_fwd_, second->fqdn_fwd_);
     EXPECT_EQ(first->fqdn_rev_, second->fqdn_rev_);
     EXPECT_EQ(first->hostname_, second->hostname_);
+    if (first->getContext()) {
+        EXPECT_TRUE(second->getContext());
+        if (second->getContext()) {
+            EXPECT_EQ(first->getContext()->str(), second->getContext()->str());
+        }
+    } else {
+        EXPECT_FALSE(second->getContext());
+    }
 }
 
 void
@@ -77,6 +85,14 @@ detailCompareLease(const Lease6Ptr& first, const Lease6Ptr& second) {
     EXPECT_EQ(first->fqdn_fwd_, second->fqdn_fwd_);
     EXPECT_EQ(first->fqdn_rev_, second->fqdn_rev_);
     EXPECT_EQ(first->hostname_, second->hostname_);
+    if (first->getContext()) {
+        EXPECT_TRUE(second->getContext());
+        if (second->getContext()) {
+            EXPECT_EQ(first->getContext()->str(), second->getContext()->str());
+        }
+    } else {
+        EXPECT_FALSE(second->getContext());
+    }
 }
 
 int findLastSocketFd() {
index b52f1655805f253f247b3e2e9458ca03b4cc660f..96956adf6f8049fe73af589fb19df115d6bb3286 100644 (file)
@@ -24,7 +24,7 @@ ALTER TABLE lease4 ADD user_context text;
 ALTER TABLE lease6 ADD user_context text;
 
 -- -----------------------------------------------------
--- Table `logs`
+-- Table \`logs\`
 -- -----------------------------------------------------
 CREATE TABLE IF NOT EXISTS logs (
     timeuuid timeuuid,  -- creation timeuuid, use dateOf() to get timestamp
index f71f6160c8f5009409e527385503a4539a9da76c..022aadb48faab8740c8c1186715aa48b1a380669 100644 (file)
@@ -681,6 +681,77 @@ SET version = '6', minor = '0';
 ALTER TABLE lease4 ADD COLUMN user_context TEXT NULL;
 ALTER TABLE lease6 ADD COLUMN user_context TEXT NULL;
 
+DROP PROCEDURE IF EXISTS lease4DumpHeader;
+DELIMITER $$
+CREATE PROCEDURE lease4DumpHeader()
+BEGIN
+SELECT 'address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context';
+END  $$
+DELIMITER ;
+
+# FUNCTION that returns a result set containing the data for lease4 dumps
+DROP PROCEDURE IF EXISTS lease4DumpData;
+DELIMITER $$
+CREATE PROCEDURE lease4DumpData()
+BEGIN
+SELECT
+    INET_NTOA(l.address),
+    IFNULL(HEX(l.hwaddr), ''),
+    IFNULL(HEX(l.client_id), ''),
+    l.valid_lifetime,
+    l.expire,
+    l.subnet_id,
+    l.fqdn_fwd,
+    l.fqdn_rev,
+    l.hostname,
+    s.name,
+    IFNULL(l.user_context, '')
+FROM
+    lease4 l
+    LEFT OUTER JOIN lease_state s on (l.state = s.state)
+ORDER BY l.address;
+END $$
+DELIMITER ;
+
+DROP PROCEDURE IF EXISTS lease6DumpHeader;
+DELIMITER $$
+CREATE PROCEDURE lease6DumpHeader()
+BEGIN
+SELECT 'address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state,user_context';
+END  $$
+DELIMITER ;
+
+# FUNCTION that returns a result set containing the data for lease6 dumps
+DROP PROCEDURE IF EXISTS lease6DumpData;
+DELIMITER $$
+CREATE PROCEDURE lease6DumpData()
+BEGIN
+SELECT
+    l.address,
+    IFNULL(HEX(l.duid), ''),
+    l.valid_lifetime,
+    l.expire,
+    l.subnet_id,
+    l.pref_lifetime,
+    IFNULL(t.name, ''),
+    l.iaid,
+    l.prefix_len,
+    l.fqdn_fwd,
+    l.fqdn_rev,
+    l.hostname,
+    IFNULL(HEX(l.hwaddr), ''),
+    IFNULL(l.hwtype, ''),
+    IFNULL(h.name, ''),
+    IFNULL(s.name, ''),
+    IFNULL(l.user_context, '')
+FROM lease6 l
+    left outer join lease6_types t on (l.lease_type = t.lease_type)
+    left outer join lease_state s on (l.state = s.state)
+    left outer join lease_hwaddr_source h on (l.hwaddr_source = h.hwaddr_source)
+ORDER BY l.address;
+END $$
+DELIMITER ;
+
 # Create logs table
 CREATE TABLE logs (
     timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  # creation timestamp
index 8f1c0f94a51171a6d9e3ac51c25093ffa8d89703..fea2d8cb2798b4881aabf213b239fb97858be382 100644 (file)
@@ -21,6 +21,77 @@ mysql "$@" <<EOF
 ALTER TABLE lease4 ADD COLUMN user_context TEXT NULL;
 ALTER TABLE lease6 ADD COLUMN user_context TEXT NULL;
 
+DROP PROCEDURE IF EXISTS lease4DumpHeader;
+DELIMITER $$
+CREATE PROCEDURE lease4DumpHeader()
+BEGIN
+SELECT 'address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context';
+END  $$
+DELIMITER ;
+
+# FUNCTION that returns a result set containing the data for lease4 dumps
+DROP PROCEDURE IF EXISTS lease4DumpData;
+DELIMITER $$
+CREATE PROCEDURE lease4DumpData()
+BEGIN
+SELECT
+    INET_NTOA(l.address),
+    IFNULL(HEX(l.hwaddr), ''),
+    IFNULL(HEX(l.client_id), ''),
+    l.valid_lifetime,
+    l.expire,
+    l.subnet_id,
+    l.fqdn_fwd,
+    l.fqdn_rev,
+    l.hostname,
+    s.name,
+    IFNULL(l.user_context, '')
+FROM
+    lease4 l
+    LEFT OUTER JOIN lease_state s on (l.state = s.state)
+ORDER BY l.address;
+END $$
+DELIMITER ;
+
+DROP PROCEDURE IF EXISTS lease6DumpHeader;
+DELIMITER $$
+CREATE PROCEDURE lease6DumpHeader()
+BEGIN
+SELECT 'address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,hwaddr,hwtype,hwaddr_source,state,user_context';
+END  $$
+DELIMITER ;
+
+# FUNCTION that returns a result set containing the data for lease6 dumps
+DROP PROCEDURE IF EXISTS lease6DumpData;
+DELIMITER $$
+CREATE PROCEDURE lease6DumpData()
+BEGIN
+SELECT
+    l.address,
+    IFNULL(HEX(l.duid), ''),
+    l.valid_lifetime,
+    l.expire,
+    l.subnet_id,
+    l.pref_lifetime,
+    IFNULL(t.name, ''),
+    l.iaid,
+    l.prefix_len,
+    l.fqdn_fwd,
+    l.fqdn_rev,
+    l.hostname,
+    IFNULL(HEX(l.hwaddr), ''),
+    IFNULL(l.hwtype, ''),
+    IFNULL(h.name, ''),
+    IFNULL(s.name, ''),
+    IFNULL(l.user_context, '')
+FROM lease6 l
+    left outer join lease6_types t on (l.lease_type = t.lease_type)
+    left outer join lease_state s on (l.state = s.state)
+    left outer join lease_hwaddr_source h on (l.hwaddr_source = h.hwaddr_source)
+ORDER BY l.address;
+END $$
+DELIMITER ;
+
 # Create logs table
 CREATE TABLE logs (
     timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,  # creation timestamp
index 520ba434b621c42bcc756b845b15b9450fafda51..af5fb01511b1e096cf38d97824d16b69ff6e46b6 100644 (file)
@@ -760,6 +760,100 @@ UPDATE schema_version
 ALTER TABLE lease4 ADD COLUMN user_context TEXT;
 ALTER TABLE lease6 ADD COLUMN user_context TEXT;
 
+--
+DROP FUNCTION IF EXISTS lease4DumpHeader();
+CREATE FUNCTION lease4DumpHeader() RETURNS text AS  $$
+    select cast('address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context' as text) as result;
+$$ LANGUAGE SQL;
+--
+
+--
+DROP FUNCTION IF EXISTS lease4DumpData();
+CREATE FUNCTION lease4DumpData() RETURNS
+    table (address inet,
+           hwaddr text,
+           client_id text,
+           valid_lifetime bigint,
+           expire timestamp with time zone,
+           subnet_id bigint,
+           fqdn_fwd int,
+           fqdn_rev int,
+           hostname text,
+           state text,
+           user_context text
+    ) as $$
+    SELECT ('0.0.0.0'::inet + l.address),
+            encode(l.hwaddr,'hex'),
+            encode(l.client_id,'hex'),
+            l.valid_lifetime,
+            l.expire,
+            l.subnet_id,
+            l.fqdn_fwd::int,
+            l.fqdn_rev::int,
+            l.hostname,
+            s.name,
+            l.user_context
+    FROM lease4 l
+         left outer join lease_state s on (l.state = s.state)
+    ORDER BY l.address;
+$$ LANGUAGE SQL;
+--
+
+--
+DROP FUNCTION IF EXISTS lease6DumpHeader();
+CREATE FUNCTION lease6DumpHeader() RETURNS text AS  $$
+    select cast('address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,state,user_context,hwaddr,hwtype,hwaddr_source' as text) as result;
+$$ LANGUAGE SQL;
+--
+
+--
+DROP FUNCTION IF EXISTS lease6DumpData();
+CREATE FUNCTION lease6DumpData() RETURNS
+    TABLE (
+           address text,
+           duid text,
+           valid_lifetime bigint,
+           expire timestamp with time zone,
+           subnet_id bigint,
+           pref_lifetime bigint,
+           name text,
+           iaid integer,
+           prefix_len smallint,
+           fqdn_fwd int,
+           fqdn_rev int,
+           hostname text,
+           state text,
+           user_context text,
+           hwaddr text,
+           hwtype smallint,
+           hwaddr_source text
+    ) AS $$
+    SELECT (l.address,
+            encode(l.duid,'hex'),
+            l.valid_lifetime,
+            l.expire,
+            l.subnet_id,
+            l.pref_lifetime,
+            t.name,
+            l.iaid,
+            l.prefix_len,
+            l.fqdn_fwd::int,
+            l.fqdn_rev::int,
+            l.hostname,
+            s.name,
+            l.user_context,
+            encode(l.hwaddr,'hex'),
+            l.hwtype,
+            h.name
+     )
+     FROM lease6 l
+         left outer join lease6_types t on (l.lease_type = t.lease_type)
+         left outer join lease_state s on (l.state = s.state)
+         left outer join lease_hwaddr_source h on (l.hwaddr_source = h.hwaddr_source)
+     ORDER BY l.address;
+$$ LANGUAGE SQL;
+--
+
 -- Create logs table
 CREATE TABLE logs (
     timestamp TIMESTAMP WITH TIME ZONE
index 9a585813275bdfd9498bb6f2388d605173aa5d2f..6d0b2fbf35db8d8736ea525d11e851d04e7a2b8d 100644 (file)
@@ -23,6 +23,104 @@ START TRANSACTION;
 ALTER TABLE lease4 ADD COLUMN user_context TEXT;
 ALTER TABLE lease6 ADD COLUMN user_context TEXT;
 
+--
+--  FUNCTION that returns a result set containing the column names for lease4 dumps
+DROP FUNCTION IF EXISTS lease4DumpHeader();
+CREATE FUNCTION lease4DumpHeader() RETURNS text AS  \$\$
+    select cast('address,hwaddr,client_id,valid_lifetime,expire,subnet_id,fqdn_fwd,fqdn_rev,hostname,state,user_context' as text) as result;
+\$\$ LANGUAGE SQL;
+--
+
+--
+--  FUNCTION that returns a result set containing the data for lease4 dumps
+DROP FUNCTION IF EXISTS lease4DumpData();
+CREATE FUNCTION lease4DumpData() RETURNS
+    table (address inet,
+           hwaddr text,
+           client_id text,
+           valid_lifetime bigint,
+           expire timestamp with time zone,
+           subnet_id bigint,
+           fqdn_fwd int,
+           fqdn_rev int,
+           hostname text,
+           state text,
+           user_context text
+    ) as \$\$
+    SELECT ('0.0.0.0'::inet + l.address),
+            encode(l.hwaddr,'hex'),
+            encode(l.client_id,'hex'),
+            l.valid_lifetime,
+            l.expire,
+            l.subnet_id,
+            l.fqdn_fwd::int,
+            l.fqdn_rev::int,
+            l.hostname,
+            s.name,
+            l.user_context
+    FROM lease4 l
+         left outer join lease_state s on (l.state = s.state)
+    ORDER BY l.address;
+\$\$ LANGUAGE SQL;
+--
+
+--
+--  FUNCTION that returns a result set containing the column names for lease6 dumps
+DROP FUNCTION IF EXISTS lease6DumpHeader();
+CREATE FUNCTION lease6DumpHeader() RETURNS text AS  \$\$
+    select cast('address,duid,valid_lifetime,expire,subnet_id,pref_lifetime,lease_type,iaid,prefix_len,fqdn_fwd,fqdn_rev,hostname,state,user_context,hwaddr,hwtype,hwaddr_source' as text) as result;
+\$\$ LANGUAGE SQL;
+--
+
+--
+--  FUNCTION that returns a result set containing the data for lease6 dumps
+DROP FUNCTION IF EXISTS lease6DumpData();
+CREATE FUNCTION lease6DumpData() RETURNS
+    TABLE (
+           address text,
+           duid text,
+           valid_lifetime bigint,
+           expire timestamp with time zone,
+           subnet_id bigint,
+           pref_lifetime bigint,
+           name text,
+           iaid integer,
+           prefix_len smallint,
+           fqdn_fwd int,
+           fqdn_rev int,
+           hostname text,
+           state text,
+           user_context text,
+           hwaddr text,
+           hwtype smallint,
+           hwaddr_source text
+    ) AS \$\$
+    SELECT (l.address,
+            encode(l.duid,'hex'),
+            l.valid_lifetime,
+            l.expire,
+            l.subnet_id,
+            l.pref_lifetime,
+            t.name,
+            l.iaid,
+            l.prefix_len,
+            l.fqdn_fwd::int,
+            l.fqdn_rev::int,
+            l.hostname,
+            s.name,
+            l.user_context,
+            encode(l.hwaddr,'hex'),
+            l.hwtype,
+            h.name
+     )
+     FROM lease6 l
+         left outer join lease6_types t on (l.lease_type = t.lease_type)
+         left outer join lease_state s on (l.state = s.state)
+         left outer join lease_hwaddr_source h on (l.hwaddr_source = h.hwaddr_source)
+     ORDER BY l.address;
+\$\$ LANGUAGE SQL;
+--
+
 -- Create logs table
 CREATE TABLE logs (
     timestamp TIMESTAMP WITH TIME ZONE