summary refs log tree commit diff
path: root/src/core/settings/plugins/keyfile/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/settings/plugins/keyfile/tests')
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT24
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain24
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Component15
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Main18
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Enum_Property8
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Flags_Property11
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection41
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection13
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID11
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID_211
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlist_SSID11
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_MAC_IB_Old_Format13
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_MAC_Old_Format10
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_ID_UUID9
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_Vlan_Flags15
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_Vlan_Setting11
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_New_Wired_Group_Name13
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_New_Wireless_Group_Names16
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID11
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_TC_Config11
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection72
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP620
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case32
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Blob22
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New22
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old22
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Path_Missing22
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection22
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_dcb_connection33
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_12
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_21
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_14
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_27
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_34
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_44
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem27
-rw-r--r--src/core/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem118
-rw-r--r--src/core/settings/plugins/keyfile/tests/meson.build15
-rw-r--r--src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c2923
39 files changed, 3668 insertions, 0 deletions
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT b/src/core/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT
new file mode 100644
index 00000000..162bf72e
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_BT
@@ -0,0 +1,24 @@
+
+[connection]
+id=AT&T Data Connect BT
+uuid=089130ab-ce28-46e4-ad77-d44869b03d19
+type=bluetooth
+autoconnect=false
+
+[ipv4]
+method=auto
+
+[gsm]
+number=*99#
+username=ISP@CINGULARGPRS.COM
+password=CINGULAR1
+apn=ISP.CINGULAR
+
+[serial]
+baud=115200
+parity=o
+
+[bluetooth]
+bdaddr=00:11:22:33:44:55
+type=dun
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain b/src/core/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain
new file mode 100644
index 00000000..11e1ec6f
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/ATT_Data_Connect_Plain
@@ -0,0 +1,24 @@
+
+[connection]
+id=AT&T Data Connect
+uuid=15d742f1-2b5a-421e-9f27-fcb1fc26d72c
+type=gsm
+autoconnect=false
+
+[ipv4]
+method=auto
+
+[gsm]
+number=*99#
+username=ISP@CINGULARGPRS.COM
+password=CINGULAR1
+apn=ISP.CINGULAR
+network-id=24005
+pin=2345
+device-id=da812de91eec16620b06cd0ca5cbc7ea25245222
+sim-id=89148000000060671234
+sim-operator-id=310260
+
+[serial]
+baud=115200
+parity=111
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Component b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Component
new file mode 100644
index 00000000..f5463ed0
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Component
@@ -0,0 +1,15 @@
+[connection]
+id=Test Bridge Component
+uuid=d7b4f96c-c45e-4298-bef8-f48574f8c1c0
+type=802-3-ethernet
+master=br0
+slave-type=bridge
+
+[802-3-ethernet]
+mac-address=00:22:15:59:62:97
+
+[bridge-port]
+priority=28
+hairpin-mode=true
+path-cost=100
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Main b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Main
new file mode 100644
index 00000000..fc9fd8f8
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Bridge_Main
@@ -0,0 +1,18 @@
+[connection]
+id=Test Bridge Main
+uuid=8f061643-fe41-4d4c-a8d9-097d26e2ad3a
+type=bridge
+
+[bridge]
+interface-name=br0
+stp=true
+forward-delay=2
+priority=32744
+hello-time=7
+max-age=39
+ageing-time=235352
+multicast-snooping=false
+
+[ipv4]
+method=auto
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Enum_Property b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Enum_Property
new file mode 100644
index 00000000..52b395b3
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Enum_Property
@@ -0,0 +1,8 @@
+[connection]
+id=Test Wired Connection IP6
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=802-3-ethernet
+
+[ipv6]
+method=auto
+ip6-privacy=2
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Flags_Property b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Flags_Property
new file mode 100644
index 00000000..3a46611d
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Flags_Property
@@ -0,0 +1,11 @@
+[connection]
+id=Test Flags Property
+uuid=05a5ec81-fa72-4b7c-9f85-4a0dfd36c84f
+type=gsm
+
+[gsm]
+number=*99#
+username=username
+password-flags=5
+apn=my.apn
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection
new file mode 100644
index 00000000..3d58fee0
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_GSM_Connection
@@ -0,0 +1,41 @@
+
+[serial]
+baud=115200
+bits=8
+parity=110
+stopbits=1
+send-delay=0
+
+[connection]
+id=Test GSM Connection
+uuid=05a5ec81-fa72-4b7c-9f85-4a0dfd36c84f
+type=gsm
+autoconnect=false
+timestamp=0
+
+[gsm]
+number=*99#
+username=username
+apn=my.apn
+network-type=0
+band=0
+
+[ppp]
+noauth=false
+refuse-eap=false
+refuse-pap=false
+refuse-chap=false
+refuse-mschap=false
+refuse-mschapv2=false
+nobsdcomp=false
+nodeflate=false
+no-vj-comp=false
+require-mppe=false
+require-mppe-128=false
+mppe-stateful=false
+crtscts=false
+baud=0
+mru=0
+mtu=0
+lcp-echo-failure=5
+lcp-echo-interval=30
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection
new file mode 100644
index 00000000..3a984b77
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_InfiniBand_Connection
@@ -0,0 +1,13 @@
+[connection]
+id=Test InfiniBand Connection
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=infiniband
+
+[infiniband]
+mac-address=00:11:22:33:44:55:66:77:88:99:01:12:23:34:45:56:67:78:89:90
+transport-mode=datagram
+mtu=1400
+
+[ipv4]
+method=auto
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID
new file mode 100644
index 00000000..2bacb725
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID
@@ -0,0 +1,11 @@
+[connection]
+id=Test 
+uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa
+type=802-11-wireless
+
+[802-11-wireless]
+ssid=101
+
+[ipv4]
+method=auto
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID_2 b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID_2
new file mode 100644
index 00000000..20240251
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlike_SSID_2
@@ -0,0 +1,11 @@
+[connection]
+id=Test SSID - escaping semicolon in string
+uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa
+type=802-11-wireless
+
+[802-11-wireless]
+ssid=11\\;12\\;13\\;
+
+[ipv4]
+method=auto
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlist_SSID b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlist_SSID
new file mode 100644
index 00000000..6d2bc0fa
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Intlist_SSID
@@ -0,0 +1,11 @@
+[connection]
+id=Test 
+uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa
+type=802-11-wireless
+
+[802-11-wireless]
+ssid=98;108;97;104;49;50;51;52;
+
+[ipv4]
+method=auto
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_MAC_IB_Old_Format b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_MAC_IB_Old_Format
new file mode 100644
index 00000000..b2bf9155
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_MAC_IB_Old_Format
@@ -0,0 +1,13 @@
+[connection]
+id=Test InfiniBand Connection
+uuid=5680a56d-c99f-45ad-a6dd-b44d5c398c12
+type=infiniband
+
+[infiniband]
+mac-address=0;17;34;51;68;85;102;119;136;153;1;18;35;52;69;86;103;120;137;144;
+transport-mode=datagram
+mtu=1400
+
+[ipv4]
+method=auto
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_MAC_Old_Format b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_MAC_Old_Format
new file mode 100644
index 00000000..9427b16c
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_MAC_Old_Format
@@ -0,0 +1,10 @@
+[connection]
+id=Test MAC Old Format
+uuid=8980a26d-c99f-4aad-a6bd-b439bc348ca4
+type=802-3-ethernet
+
+[802-3-ethernet]
+mac-address=00:11:aa:BB:CC:55
+cloned-mac-address=00;22;170;187;204;254;
+mtu=1400
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_ID_UUID b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_ID_UUID
new file mode 100644
index 00000000..138380d0
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_ID_UUID
@@ -0,0 +1,9 @@
+# id and uuid keys are missing
+# They will be auto-genetrated by NetworkManager
+
+[connection]
+type=ethernet
+autoconnect=true
+
+[802-3-ethernet]
+mac-address=00:11:22:33:44:55
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_Vlan_Flags b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_Vlan_Flags
new file mode 100644
index 00000000..330adda0
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_Vlan_Flags
@@ -0,0 +1,15 @@
+# VLAN setting with missing 'flags' key
+# vlan.flags will be set to 0 (even if the default 'flags' property value is 1)
+
+[connection]
+id=Test Missing Vlan Flags
+uuid=803ebe47-8c31-401d-b47b-03fc0d34eb11
+type=vlan
+autoconnect=true
+
+[802-3-ethernet]
+mac-address=00:11:22:33:44:55
+
+[vlan]
+id=444
+parent=em1
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_Vlan_Setting b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_Vlan_Setting
new file mode 100644
index 00000000..95d7b9a9
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Missing_Vlan_Setting
@@ -0,0 +1,11 @@
+# Settings with all default values are not written, including
+# VLAN settings with a VLAN ID of 0, which is the default value.
+
+[connection]
+id=Test Missing Vlan Setting
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=vlan
+autoconnect=true
+
+[802-3-ethernet]
+mac-address=00:11:22:33:44:55
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_New_Wired_Group_Name b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_New_Wired_Group_Name
new file mode 100644
index 00000000..f27cd4a3
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_New_Wired_Group_Name
@@ -0,0 +1,13 @@
+
+[connection]
+id=Test Wired Connection
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=ethernet
+
+[ethernet]
+mac-address=00:11:22:33:44:55
+mtu=1400
+
+[ipv4]
+method=auto
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_New_Wireless_Group_Names b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_New_Wireless_Group_Names
new file mode 100644
index 00000000..d9ac5864
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_New_Wireless_Group_Names
@@ -0,0 +1,16 @@
+[connection]
+id=Test New Wireless Group Names
+uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa
+type=wifi
+
+[wifi]
+ssid=foobar
+mode=infrastructure
+
+[wifi-security]
+key-mgmt=wpa-psk
+psk=s3cu4e passphrase
+
+[ipv4]
+method=auto
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID
new file mode 100644
index 00000000..4a3b56d2
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_String_SSID
@@ -0,0 +1,11 @@
+[connection]
+id=Test 
+uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa
+type=802-11-wireless
+
+[802-11-wireless]
+ssid=blah blah ssid 1234
+
+[ipv4]
+method=auto
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_TC_Config b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_TC_Config
new file mode 100644
index 00000000..14280eef
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_TC_Config
@@ -0,0 +1,11 @@
+
+[connection]
+id=Test TC Config
+uuid=32a51666-95ea-1337-b371-dcf5e54b1001
+type=802-3-ethernet
+
+[tc]
+qdisc.root=handle 1234 fq_codel
+qdisc.ffff:fff1=ingress
+tfilter.1234:=matchall action drop
+tfilter.ffff:=matchall action simple sdata Hello
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection
new file mode 100644
index 00000000..f9ccc003
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection
@@ -0,0 +1,72 @@
+
+[connection]
+id=Test Wired Connection
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=802-3-ethernet
+autoconnect=true
+timestamp=6654332
+
+[802-3-ethernet]
+mac-address=00:11:22:33:44:55
+speed=0
+duplex=full
+auto-negotiate=true
+mtu=1400
+
+[ipv4]
+method=manual
+dns=4.2.2.1;bogus;4.2.2.2;
+addresses1=192.168.0.5;24;192.168.0.1;
+addresses2=1.2.3.4;16;1.2.1.1;
+address=2.3.4.5/24,2.3.4.6
+address3=3.4.5.6/16
+address4=4.5.6.7/1.2.3.4
+address5=5.6.7.8
+routes1=1.2.3.0/24,2.3.4.8,99
+route=5.6.7.8/32
+routes2=1.1.1.2/12,
+routes3=1.1.1.3/13,,
+routes7=1.1.1.7/17,0.0.0.0
+routes4=1.1.1.4/14,2.2.2.4
+address30=1.2.3.130/24
+routes5=1.1.1.5/15,2.2.2.5,
+routes6=1.1.1.6/16,2.2.2.6,0
+routes8=1.1.1.8/18,0.0.0.0,
+routes9=1.1.1.9/19,0.0.0.0,0
+route10=1.1.1.10/21,,0
+routes10=1.1.1.10/20,,0
+routes11=1.1.1.11/21,,21
+routes11_options=cwnd=10,lock-cwnd=true,mtu=1430,src=7.7.7.7,type=unicast
+routes12=1.2.3.4/32
+routes12_options=type=local
+address30=1.2.3.30/24
+addresses30=1.2.3.30/25
+addresses31=1.2.3.31/25
+address31=1.2.3.31/24
+ignore-auto-routes=false
+ignore-auto-dns=false
+
+[ipv6]
+method=manual
+dns=1111:dddd::aaaa;1::cafe;
+dns-search=super-domain.com;redhat.com;gnu.org;
+addresses1=abcd:1234:ffff::cdde/64
+addresses2=1:2:3:4:5:6:7:8/96
+address=2:3:4:5:6:7:8:9/64,2:3:4:5:1:2:3:4
+address3=3:4:5:6:7:8:9:0/128
+address4=3:4:5:6:7:8:9:14
+address5=3:4:5:6:7:8:9:15,
+address6=3:4:5:6:7:8:9:16,66
+address7=3:4:5:6:7:8:9:17,67,
+address8=3:4:5:6:7:8:9:18,68,::
+address9=3:4:5:6:7:8:9:19,69,1::09
+routes1=a:b:c:d::/64;f:e:d:c:1:2:3:4;99;
+route=d:e:f:0:1:2:3:4/64,f:e:d:c:1:2:3:4
+route2=8:7:6:5:4:3:2:1/128
+route3=6:7:8:9:0:1:2:3/126,,1
+route4=7:8:9:0:1:2:3:4/125/::,5
+route5=8:9:0:1:2:3:4:5/124,6
+route6=8:9:0:1:2:3:4:6/123,,
+route6_options=from=abce::/63
+ignore-auto-routes=false
+ignore-auto-dns=false
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP6 b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP6
new file mode 100644
index 00000000..a42dd5d2
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_IP6
@@ -0,0 +1,20 @@
+
+[connection]
+id=Test Wired Connection IP6
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=802-3-ethernet
+autoconnect=true
+timestamp=6654332
+
+[802-3-ethernet]
+auto-negotiate=true
+mtu=1400
+
+[ipv4]
+method=disabled
+
+[ipv6]
+method=manual
+addresses1=abcd:1234:ffff::cdde/64,abcd:1234:ffff::cdd1
+dns=1111:dddd::aaaa;1::cafe;
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case
new file mode 100644
index 00000000..29aef494
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_Connection_MAC_Case
@@ -0,0 +1,32 @@
+
+[connection]
+id=Test Wired Connection MAC Case
+uuid=4e80a56d-c99f-4aad-a6dd-b449bc398c57
+type=802-3-ethernet
+autoconnect=true
+timestamp=6654332
+
+[802-3-ethernet]
+mac-address=00:11:aa:BB:CC:55
+speed=0
+duplex=full
+auto-negotiate=true
+mtu=1400
+
+[ipv4]
+method=manual
+dns=4.2.2.1;4.2.2.2;
+addresses1=192.168.0.5;24;192.168.0.1;
+addresses2=1.2.3.4;16;1.2.1.1;
+ignore-auto-routes=false
+ignore-auto-dns=false
+
+[ipv6]
+method=manual
+dns=1111:dddd::aaaa;1::cafe;
+dns-search=super-domain.com;redhat.com;gnu.org;
+addresses1=abcd:1234:ffff::cdde/64
+addresses2=1:2:3:4:5:6:7:8/96
+routes1=a:b:c:d::/64;f:e:d:c:1:2:3:4;99;
+ignore-auto-routes=false
+ignore-auto-dns=false
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Blob b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Blob
new file mode 100644
index 00000000..62e6ae31
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Blob
@@ -0,0 +1,22 @@
+
+[connection]
+id=Wired TLS
+uuid=5ee46013-9469-4c6a-a60a-0c7a1e1c7488
+type=802-3-ethernet
+
+[802-1x]
+eap=tls;
+identity=Bill Smith
+ca-cert=48;130;2;52;48;130;1;161;2;16;2;173;102;126;78;69;254;94;87;111;60;152;25;94;221;192;48;13;6;9;42;134;72;134;247;13;1;1;2;5;0;48;95;49;11;48;9;6;3;85;4;6;19;2;85;83;49;32;48;30;6;3;85;4;10;19;23;82;83;65;32;68;97;116;97;32;83;101;99;117;114;105;116;121;44;32;73;110;99;46;49;46;48;44;6;3;85;4;11;19;37;83;101;99;117;114;101;32;83;101;114;118;101;114;32;67;101;114;116;105;102;105;99;97;116;105;111;110;32;65;117;116;104;111;114;105;116;121;48;30;23;13;57;52;49;49;48;57;48;48;48;48;48;48;90;23;13;49;48;48;49;48;55;50;51;53;57;53;57;90;48;95;49;11;48;9;6;3;85;4;6;19;2;85;83;49;32;48;30;6;3;85;4;10;19;23;82;83;65;32;68;97;116;97;32;83;101;99;117;114;105;116;121;44;32;73;110;99;46;49;46;48;44;6;3;85;4;11;19;37;83;101;99;117;114;101;32;83;101;114;118;101;114;32;67;101;114;116;105;102;105;99;97;116;105;111;110;32;65;117;116;104;111;114;105;116;121;48;129;155;48;13;6;9;42;134;72;134;247;13;1;1;1;5;0;3;129;137;0;48;129;133;2;126;0;146;206;122;193;174;131;62;90;170;137;131;87;172;37;1;118;12;173;174;142;44;55;206;235;53;120;100;84;3;229;132;64;81;201;191;143;8;226;138;130;8;210;22;134;55;85;233;177;33;2;173;118;104;129;154;5;162;75;201;75;37;102;34;86;108;136;7;143;247;129;89;109;132;7;101;112;19;113;118;62;155;119;76;227;80;137;86;152;72;185;29;167;41;26;19;46;74;17;89;156;30;21;213;73;84;44;115;58;105;130;177;151;57;156;109;112;103;72;229;221;45;214;200;30;123;2;3;1;0;1;48;13;6;9;42;134;72;134;247;13;1;1;2;5;0;3;126;0;101;221;126;225;178;236;176;226;58;224;236;113;70;154;25;17;184;211;199;160;180;3;64;38;2;62;9;156;225;18;179;209;90;246;55;165;183;97;3;182;91;22;105;59;198;68;8;12;136;83;12;107;151;73;199;62;53;220;108;185;187;170;223;92;187;58;47;147;96;182;169;75;77;242;32;247;205;95;127;100;123;142;220;0;92;215;250;119;202;57;22;89;111;14;234;211;181;131;127;77;77;66;86;118;180;201;95;4;248;56;248;235;210;95;117;95;205;123;252;229;142;128;124;252;80;
+client-cert=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0;
+private-key=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0;
+private-key-password=12345testing
+
+[ipv4]
+method=auto
+
+[802-3-ethernet]
+duplex=full
+
+[ipv6]
+method=ignore
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New
new file mode 100644
index 00000000..4cd86686
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_New
@@ -0,0 +1,22 @@
+
+[connection]
+id=Wired TLS
+uuid=5ee46013-9469-4c6a-a60a-0c7a1e1c7488
+type=802-3-ethernet
+
+[802-1x]
+eap=tls;
+identity=Bill Smith
+ca-cert=test-ca-cert.pem
+client-cert=test-key-and-cert.pem
+private-key=test-key-and-cert.pem
+private-key-password=12345testing
+
+[ipv4]
+method=auto
+
+[802-3-ethernet]
+duplex=full
+
+[ipv6]
+method=ignore
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old
new file mode 100644
index 00000000..d3da598c
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Old
@@ -0,0 +1,22 @@
+
+[connection]
+id=Wired TLS
+uuid=5ee46013-9469-4c6a-a60a-0c7a1e1c7488
+type=802-3-ethernet
+
+[802-1x]
+eap=tls;
+identity=Bill Smith
+ca-cert=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;67;65;47;101;97;112;116;101;115;116;95;99;97;95;99;101;114;116;46;112;101;109;0;
+client-cert=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0;
+private-key=102;105;108;101;58;47;47;47;67;65;83;65;47;100;99;98;119;47;68;101;115;107;116;111;112;47;99;101;114;116;105;110;102;114;97;47;99;108;105;101;110;116;46;112;101;109;0;
+private-key-password=12345testing
+
+[ipv4]
+method=auto
+
+[802-3-ethernet]
+duplex=full
+
+[ipv6]
+method=ignore
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Path_Missing b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Path_Missing
new file mode 100644
index 00000000..2b39538e
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wired_TLS_Path_Missing
@@ -0,0 +1,22 @@
+
+[connection]
+id=Wired TLS
+uuid=5ee46013-9469-4c6a-a60a-0c7a1e1c7488
+type=802-3-ethernet
+
+[802-1x]
+eap=tls;
+identity=Bill Smith
+ca-cert=/some/random/cert/path.pem
+client-cert=test-key-and-cert.pem
+private-key=test-key-and-cert.pem
+private-key-password=12345testing
+
+[ipv4]
+method=auto
+
+[802-3-ethernet]
+duplex=full
+
+[ipv6]
+method=ignore
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection
new file mode 100644
index 00000000..b1949d0d
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_Wireless_Connection
@@ -0,0 +1,22 @@
+[connection]
+id=Test Wireless Connection
+uuid=2f962388-e5f3-45af-a62c-ac220b8f7baa
+type=802-11-wireless
+autoconnect=false
+timestamp=1226604314
+
+[802-11-wireless]
+ssid=110;109;45;116;101;115;116;45;97;112;
+mode=infrastructure
+channel=0
+rate=0
+tx-power=0
+mtu=0
+bssid=00:1a:33:44:99:82
+
+[ipv4]
+method=auto
+ignore-auto-routes=false
+ignore-auto-dns=false
+never-default=false
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_dcb_connection b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_dcb_connection
new file mode 100644
index 00000000..16d4b45e
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_dcb_connection
@@ -0,0 +1,33 @@
+[connection]
+id=dcb connection 1
+uuid=ac3c251e-260f-49b6-8ceb-12d37ea00751
+type=ethernet
+autoconnect=false
+permissions=
+secondaries=
+
+[ethernet]
+mac-address-blacklist=
+
+[dcb]
+app-fcoe-flags=1
+app-fip-flags=1
+app-iscsi-flags=1
+priority-bandwidth=0;0;0;0;0;0;0;0;
+priority-flow-control=0;0;0;0;0;0;0;0;
+priority-flow-control-flags=1
+priority-group-bandwidth=100;0;0;0;0;0;0;0;
+priority-group-flags=1
+priority-group-id=0;0;0;0;0;0;0;0;
+priority-strict-bandwidth=0;0;0;0;0;0;0;0;
+priority-traffic-class=0;0;0;0;0;0;0;0;
+
+[ipv4]
+dns-search=
+method=auto
+
+[ipv6]
+addr-gen-mode=stable-privacy
+dns-search=
+ip6-privacy=0
+method=auto
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_1 b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_1
new file mode 100644
index 00000000..cac135ad
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_1
@@ -0,0 +1,2 @@
+[connection]
+type=802-3-ethernet
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_2 b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_2
new file mode 100644
index 00000000..bbf2d8d6
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_2
@@ -0,0 +1 @@
+[802-3-ethernet]
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_1 b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_1
new file mode 100644
index 00000000..d3122d53
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_1
@@ -0,0 +1,4 @@
+[connection]
+type=802-3-ethernet
+master=br0
+slave-type=bridge
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_2 b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_2
new file mode 100644
index 00000000..eb1cdace
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_2
@@ -0,0 +1,7 @@
+[connection]
+master=br0
+
+[802-3-ethernet]
+
+[bridge-port]
+
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_3 b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_3
new file mode 100644
index 00000000..7419e97d
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_3
@@ -0,0 +1,4 @@
+[connection]
+master=br0
+slave-type=bridge
+[802-3-ethernet]
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_4 b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_4
new file mode 100644
index 00000000..626b6f68
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/Test_minimal_slave_4
@@ -0,0 +1,4 @@
+[connection]
+type=802-3-ethernet
+master=br0
+[bridge-port]
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem b/src/core/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem
new file mode 100644
index 00000000..ef1be20d
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/test-ca-cert.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEjzCCA3egAwIBAgIJAOvnZPt59yIZMA0GCSqGSIb3DQEBBQUAMIGLMQswCQYD
+VQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcw
+FQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UE
+AxMEdGVzdDEcMBoGCSqGSIb3DQEJARYNdGVzdEB0ZXN0LmNvbTAeFw0wOTAzMTAx
+NTEyMTRaFw0xOTAzMDgxNTEyMTRaMIGLMQswCQYDVQQGEwJVUzESMBAGA1UECBMJ
+QmVya3NoaXJlMRAwDgYDVQQHEwdOZXdidXJ5MRcwFQYDVQQKEw5NeSBDb21wYW55
+IEx0ZDEQMA4GA1UECxMHVGVzdGluZzENMAsGA1UEAxMEdGVzdDEcMBoGCSqGSIb3
+DQEJARYNdGVzdEB0ZXN0LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAKot9j+/+CX1/gZLgJHIXCRgCItKLGnf7qGbgqB9T2ACBqR0jllKWwDKrcWU
+xjXNIc+GF9Wnv+lX6G0Okn4Zt3/uRNobL+2b/yOF7M3Td3/9W873zdkQQX930YZc
+Rr8uxdRPP5bxiCgtcw632y21sSEbG9mjccAUnV/0jdvfmMNj0i8gN6E0fMBiJ9S3
+FkxX/KFvt9JWE9CtoyL7ki7UIDq+6vj7Gd5N0B3dOa1y+rRHZzKlJPcSXQSEYUS4
+HmKDwiKSVahft8c4tDn7KPi0vex91hlgZVd3usL2E/Vq7o5D9FAZ5kZY0AdFXwdm
+J4lO4Mj7ac7GE4vNERNcXVIX59sCAwEAAaOB8zCB8DAdBgNVHQ4EFgQUuDU3Mr7P
+T3n1e3Sy8hBauoDFahAwgcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDF
+ahChgZGkgY4wgYsxCzAJBgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAO
+BgNVBAcTB05ld2J1cnkxFzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQL
+EwdUZXN0aW5nMQ0wCwYDVQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRl
+c3QuY29tggkA6+dk+3n3IhkwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOC
+AQEAVRG4aALIvCXCiKfe7K+iJxjBVRDFPEf7JWA9LGgbFOn6pNvbxonrR+0BETdc
+JV1ET4ct2xsE7QNFIkp9GKRC+6J32zCo8qtLCD5+v436r8TUG2/t2JRMkb9I2XVT
+p7RJoot6M0Ltf8KNQUPYh756xmKZ4USfQUwc58MOSDGY8VWEXJOYij9Pf0e0c52t
+qiCEjXH7uXiS8Pgq9TYm7AkWSOrglYhSa83x0f8mtT8Q15nBESIHZ6o8FAS2bBgn
+B0BkrKRjtBUkuJG3vTox+bYINh2Gxi1JZHWSV1tN5z3hd4VFcKqanW5OgQwToBqp
+3nniskIjbH0xjgZf/nVMyLnjxg==
+-----END CERTIFICATE-----
diff --git a/src/core/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem b/src/core/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem
new file mode 100644
index 00000000..dec9aa1b
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/keyfiles/test-key-and-cert.pem
@@ -0,0 +1,118 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,4DE0615F23D82107
+
+QPNCO5Dobvz9dDhN32KkZRoEifW+HDm2PCbRQhKDiscGwB6LgypvVjHNsZiFKwzz
+L4R51UqgQeJx7GSGJqE626e9z9J+UNBhop02aOO2X0eSPdvBzr/uJ6Umiyr1xqD7
+zWf7u9l5kXElDJRhK+87GMBewp4Ie9NeXDjhF8hzC5Kiulen4AH3AYnfH3S7DimU
+h8GFMg8inrudrTbcjBhCdPeHG2jCygOxw3InRFz7uaN6LIhOaPQvmvpP4Cc1WRnW
+ZPq9o+eU3fPWPD5t+Op/VzYLvKwgBy/yK1rQXUm6ZMO7MhhRJ94ZCsJv+nVWpJlv
+QyBlxDKxwfkfYbDELdnnDQdHdMbKatLqa0KhSkgpp8LywBtanPz731tyT0r7b3na
+eLdra59lRU7ZQLPEdS3lPZd2O/KQvWf8wbg7MjXS9LxQ7R5HOPu6DNJlwXVZBmmo
+cAfu2q8ubU2IePvWLD1GOrBi6hE9TiGvFJkw+wBK+t72sz3njv9Xm/zlxruaEk5m
+RW/kybU3FP4PtjriBbskz3/VZaaxuRN7OoOYTkmyHmG1ADgcRUV6fea19qqsBlN8
+xb+SRtoH28oT/JVWU5neE2dbNzk5LeVO+w70NNdR5s5xqkBhbGGaJxvXwNP4ltFr
+T06SMh8znOLKwWB00aRtwfU7jOwR3mOleQO4ugIHmau3zp1TqzAHW8XtpuV7qVeI
+ESZOZuf0vW43BtNzgLXt1+r+bmsMsRwhnyomL9M0TUyyBdVYY9GkzTG9pOESheRo
+RSvAZ8qKGUliTpgBcbt2v1+NqkszcHa6FxuvS8YU4uo5/GqsgTxHTNIB232hIrrZ
+EIm6QL9TC5oFXMjy6UNqoCm5Nb8DBJ6aErt7pt7aoktqUW3O3QIzQT3IbZ4nAcTt
+lVF4d7j29I9t7bcC8GOVU1neilguZUss4ghJg9x4zI5UZdR7hZ8fbFT47TyxB+j5
+r0YdmjbjVTaSyaN2JGh1wvb4TzawGNVx/U2EJE16HigOtPfsfQRJ3x+FROKBdVa4
+aIFYXkRBeIPxX6n9pcw0lBCsnXo6/5iTjQSk2VqO3rHO/wyWiEjNczhL33dY2A8W
+GG5ECMO5SqXZHQQzpABqK94dxe3UC8aEESO5NhEqDuV7qQGol0qPKrUA3wb0jb2e
+DrejJ9HS2m1SUDmjpvvmEGy6GN7CRibbKt5rNZdJNNvWArOF5d0F6wkixQLl73oE
+lq5gLQQk9n7ClleKLhlQpBCorxilBbzmSUekkJLi0eaZiBBFWBX9udqnUZloXTgO
+8qwuO8K/GPR9Jy1/UH2Vh1H+wivaqKTVgEb0NotzgzECgTEFKJafl7rUNs1OZRZ3
+VBjevi6+iDpxVFgF71kXfdUC4ph0E1XDl0ja2rrKQGivMkUhWJ57+4EV5+hBkAnt
+G0RV45NwHXLrK2bd8F9PlRk2XHW6mIcFRXsW1DjeBhk/sQjvlO9R01GRSgcXtekJ
+tmX17FWrMrzXHpvy1IC3fk4RVnSjpzQ8O+17YE8/la9wVaeZZzHyYFmMT7VXjIhW
+QozJQ0vJ2jxJRh5GYn3tpJzdaeRfvTBik0pChNdUTnWP+BJ35xoCTs8iwJbmgVZ1
+-----END RSA PRIVATE KEY-----
+Certificate:
+    Data:
+        Version: 3 (0x2)
+        Serial Number: 1 (0x1)
+        Signature Algorithm: md5WithRSAEncryption
+        Issuer: C=US, ST=Berkshire, L=Newbury, O=My Company Ltd, OU=Testing, CN=test/emailAddress=test@test.com
+        Validity
+            Not Before: Mar 10 15:13:16 2009 GMT
+            Not After : Mar  8 15:13:16 2019 GMT
+        Subject: C=US, ST=Berkshire, O=My Company Ltd, OU=Testing, CN=test1/emailAddress=test@test.com
+        Subject Public Key Info:
+            Public Key Algorithm: rsaEncryption
+            RSA Public Key: (2048 bit)
+                Modulus (2048 bit):
+                    00:cd:34:b1:2e:b0:04:c6:f4:2b:a2:c0:a0:39:7a:
+                    82:ed:96:c4:f7:19:83:91:5c:b4:e7:9c:de:ec:48:
+                    ec:2d:e4:51:08:26:42:ac:d3:98:26:7a:72:f7:49:
+                    c2:9e:66:05:c6:47:29:fe:3b:ac:6b:af:6f:5e:a8:
+                    03:5a:73:33:ba:19:03:00:35:f5:00:bc:a8:be:14:
+                    ce:46:69:e3:6d:ed:34:37:85:55:87:62:b3:b7:c9:
+                    c0:cc:9a:aa:61:05:5b:cd:a2:17:42:d3:e5:6f:1c:
+                    60:8d:c2:15:41:46:f8:12:54:d0:38:57:e1:fd:8d:
+                    44:c8:fb:56:b3:b9:6c:e9:f8:9e:21:11:57:1b:8b:
+                    f9:cf:e3:17:e7:d8:fd:ac:d1:01:c6:92:30:f3:2d:
+                    c9:d6:c1:f0:3d:fd:ca:30:dd:75:74:e7:d1:6b:75:
+                    d8:c5:4d:43:61:fe:f6:ad:7e:4c:63:7c:03:17:a2:
+                    06:8f:d0:8b:69:d3:7a:07:0f:0b:a2:cf:0c:70:38:
+                    ba:cc:55:35:60:84:58:d8:d2:be:1f:ef:76:a9:ba:
+                    ae:6a:dc:08:97:80:de:42:00:b7:d4:ce:9a:b0:36:
+                    2a:c7:6f:45:04:7c:ea:41:19:d8:b9:19:04:1f:11:
+                    a9:22:80:bd:69:08:15:0d:3c:de:cd:7e:88:6c:0f:
+                    a3:43
+                Exponent: 65537 (0x10001)
+        X509v3 extensions:
+            X509v3 Basic Constraints: 
+                CA:FALSE
+            Netscape Comment: 
+                OpenSSL Generated Certificate
+            X509v3 Subject Key Identifier: 
+                CE:03:7E:EF:E7:DE:C9:87:BF:DE:56:F4:C8:A3:40:F6:C8:6F:05:8C
+            X509v3 Authority Key Identifier: 
+                keyid:B8:35:37:32:BE:CF:4F:79:F5:7B:74:B2:F2:10:5A:BA:80:C5:6A:10
+                DirName:/C=US/ST=Berkshire/L=Newbury/O=My Company Ltd/OU=Testing/CN=test/emailAddress=test@test.com
+                serial:EB:E7:64:FB:79:F7:22:19
+
+    Signature Algorithm: md5WithRSAEncryption
+        7a:20:93:63:40:73:7d:33:01:2e:c0:13:52:a4:a7:e1:4d:82:
+        f4:fb:b2:7b:d0:2b:5a:3f:0e:3c:28:61:71:ab:01:4d:fe:89:
+        b5:cd:2f:97:59:93:53:9d:51:86:48:dd:b9:e4:73:5e:22:0b:
+        12:0d:25:39:76:16:44:06:0c:40:45:21:6b:a6:b1:e0:bf:76:
+        1b:36:f3:1e:41:82:57:d9:59:b7:60:40:43:1c:1d:79:f6:48:
+        32:5c:4e:e2:06:89:96:41:d2:54:1f:4a:6f:f6:78:a5:3c:02:
+        85:21:e2:65:e1:8a:6d:24:19:95:f8:c0:35:ab:bd:ff:3d:f1:
+        fb:50:2d:30:1e:67:a6:7c:50:f9:d5:77:66:77:5a:14:0f:5c:
+        cd:21:09:9b:a3:92:57:19:dd:01:a4:18:c5:f9:70:e4:17:43:
+        8d:b1:e6:61:e9:50:89:83:4f:ce:a4:57:68:58:40:70:ae:71:
+        1c:47:66:d2:30:54:50:ea:3a:87:32:64:3b:18:42:fe:5a:19:
+        07:64:f7:f1:b1:10:07:fd:a7:d2:a7:a8:05:79:5b:25:ba:69:
+        7b:1a:3e:b1:3e:e4:17:17:01:ba:eb:54:ae:83:00:ed:66:62:
+        8d:c0:3e:8a:b4:27:5f:e9:01:ce:20:c3:34:a9:28:c0:6f:c7:
+        3b:65:fe:f9
+-----BEGIN CERTIFICATE-----
+MIIEojCCA4qgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBizELMAkGA1UEBhMCVVMx
+EjAQBgNVBAgTCUJlcmtzaGlyZTEQMA4GA1UEBxMHTmV3YnVyeTEXMBUGA1UEChMO
+TXkgQ29tcGFueSBMdGQxEDAOBgNVBAsTB1Rlc3RpbmcxDTALBgNVBAMTBHRlc3Qx
+HDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wHhcNMDkwMzEwMTUxMzE2WhcN
+MTkwMzA4MTUxMzE2WjB6MQswCQYDVQQGEwJVUzESMBAGA1UECBMJQmVya3NoaXJl
+MRcwFQYDVQQKEw5NeSBDb21wYW55IEx0ZDEQMA4GA1UECxMHVGVzdGluZzEOMAwG
+A1UEAxMFdGVzdDExHDAaBgkqhkiG9w0BCQEWDXRlc3RAdGVzdC5jb20wggEiMA0G
+CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDNNLEusATG9CuiwKA5eoLtlsT3GYOR
+XLTnnN7sSOwt5FEIJkKs05gmenL3ScKeZgXGRyn+O6xrr29eqANaczO6GQMANfUA
+vKi+FM5GaeNt7TQ3hVWHYrO3ycDMmqphBVvNohdC0+VvHGCNwhVBRvgSVNA4V+H9
+jUTI+1azuWzp+J4hEVcbi/nP4xfn2P2s0QHGkjDzLcnWwfA9/cow3XV059FrddjF
+TUNh/vatfkxjfAMXogaP0Itp03oHDwuizwxwOLrMVTVghFjY0r4f73apuq5q3AiX
+gN5CALfUzpqwNirHb0UEfOpBGdi5GQQfEakigL1pCBUNPN7NfohsD6NDAgMBAAGj
+ggEfMIIBGzAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVy
+YXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUzgN+7+feyYe/3lb0yKNA9shvBYww
+gcAGA1UdIwSBuDCBtYAUuDU3Mr7PT3n1e3Sy8hBauoDFahChgZGkgY4wgYsxCzAJ
+BgNVBAYTAlVTMRIwEAYDVQQIEwlCZXJrc2hpcmUxEDAOBgNVBAcTB05ld2J1cnkx
+FzAVBgNVBAoTDk15IENvbXBhbnkgTHRkMRAwDgYDVQQLEwdUZXN0aW5nMQ0wCwYD
+VQQDEwR0ZXN0MRwwGgYJKoZIhvcNAQkBFg10ZXN0QHRlc3QuY29tggkA6+dk+3n3
+IhkwDQYJKoZIhvcNAQEEBQADggEBAHogk2NAc30zAS7AE1Kkp+FNgvT7snvQK1o/
+DjwoYXGrAU3+ibXNL5dZk1OdUYZI3bnkc14iCxINJTl2FkQGDEBFIWumseC/dhs2
+8x5BglfZWbdgQEMcHXn2SDJcTuIGiZZB0lQfSm/2eKU8AoUh4mXhim0kGZX4wDWr
+vf898ftQLTAeZ6Z8UPnVd2Z3WhQPXM0hCZujklcZ3QGkGMX5cOQXQ42x5mHpUImD
+T86kV2hYQHCucRxHZtIwVFDqOocyZDsYQv5aGQdk9/GxEAf9p9KnqAV5WyW6aXsa
+PrE+5BcXAbrrVK6DAO1mYo3APoq0J1/pAc4gwzSpKMBvxztl/vk=
+-----END CERTIFICATE-----
diff --git a/src/core/settings/plugins/keyfile/tests/meson.build b/src/core/settings/plugins/keyfile/tests/meson.build
new file mode 100644
index 00000000..3c89bcf9
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/meson.build
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+exe = executable(
+  'test-keyfile-settings',
+  'test-keyfile-settings.c',
+  dependencies: libNetworkManagerTest_dep,
+  c_args: test_c_flags,
+)
+
+test(
+  'test-keyfile-settings',
+  test_script,
+  args: test_args + [exe.full_path()],
+  timeout: default_test_timeout,
+)
diff --git a/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c
new file mode 100644
index 00000000..348b0ed6
--- /dev/null
+++ b/src/core/settings/plugins/keyfile/tests/test-keyfile-settings.c
@@ -0,0 +1,2923 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Copyright (C) 2008 - 2017 Red Hat, Inc.
+ */
+
+#include "src/core/nm-default-daemon.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/socket.h>
+#include <linux/pkt_sched.h>
+#include <linux/if_ether.h>
+#include <linux/if_infiniband.h>
+
+#include "nm-core-internal.h"
+
+#include "settings/plugins/keyfile/nms-keyfile-reader.h"
+#include "settings/plugins/keyfile/nms-keyfile-writer.h"
+#include "settings/plugins/keyfile/nms-keyfile-utils.h"
+
+#include "nm-test-utils-core.h"
+
+#define TEST_KEYFILES_DIR NM_BUILD_SRCDIR "/src/core/settings/plugins/keyfile/tests/keyfiles"
+#define TEST_SCRATCH_DIR  NM_BUILD_BUILDDIR "/src/core/settings/plugins/keyfile/tests/keyfiles"
+
+/*****************************************************************************/
+
+static void
+check_ip_address(NMSettingIPConfig *config, int idx, const char *address, int plen)
+{
+    NMIPAddress *ip4 = nm_setting_ip_config_get_address(config, idx);
+
+    g_assert(ip4);
+    g_assert_cmpstr(nm_ip_address_get_address(ip4), ==, address);
+    g_assert_cmpint(nm_ip_address_get_prefix(ip4), ==, plen);
+}
+
+static void
+check_ip_route(NMSettingIPConfig *config,
+               int                idx,
+               const char *       destination,
+               int                plen,
+               const char *       next_hop,
+               gint64             metric)
+{
+    NMIPRoute *route = nm_setting_ip_config_get_route(config, idx);
+
+    g_assert(route);
+    g_assert_cmpstr(nm_ip_route_get_dest(route), ==, destination);
+    g_assert_cmpint(nm_ip_route_get_prefix(route), ==, plen);
+    g_assert_cmpstr(nm_ip_route_get_next_hop(route), ==, next_hop);
+    g_assert_cmpint(nm_ip_route_get_metric(route), ==, metric);
+}
+
+#define keyfile_read_connection_from_file(full_filename)                                  \
+    ({                                                                                    \
+        gs_free_error GError *_error = NULL;                                              \
+        NMConnection *        _connection;                                                \
+                                                                                          \
+        g_assert(full_filename &&full_filename[0] == '/');                                \
+                                                                                          \
+        _connection =                                                                     \
+            nms_keyfile_reader_from_file(full_filename,                                   \
+                                         NULL,                                            \
+                                         NULL,                                            \
+                                         NULL,                                            \
+                                         NULL,                                            \
+                                         NULL,                                            \
+                                         NULL,                                            \
+                                         NULL,                                            \
+                                         (nmtst_get_rand_uint32() % 2) ? &_error : NULL); \
+        nmtst_assert_success(_connection, _error);                                        \
+        nmtst_assert_connection_verifies_without_normalization(_connection);              \
+                                                                                          \
+        _connection;                                                                      \
+    })
+
+static void
+assert_reread(NMConnection *connection, gboolean normalize_connection, const char *testfile)
+{
+    gs_unref_object NMConnection *reread           = NULL;
+    gs_unref_object NMConnection *connection_clone = NULL;
+    NMSettingConnection *         s_con;
+
+    g_assert(NM_IS_CONNECTION(connection));
+
+    reread = keyfile_read_connection_from_file(testfile);
+
+    if (!normalize_connection && (s_con = nm_connection_get_setting_connection(connection))
+        && !nm_setting_connection_get_master(s_con)
+        && !nm_connection_get_setting_proxy(connection)) {
+        connection_clone = nmtst_clone_connection(connection);
+        connection       = connection_clone;
+        nm_connection_add_setting(connection, nm_setting_proxy_new());
+    }
+
+    nmtst_assert_connection_equals(connection, normalize_connection, reread, FALSE);
+}
+
+static void
+assert_reread_and_unlink(NMConnection *connection,
+                         gboolean      normalize_connection,
+                         const char *  testfile)
+{
+    assert_reread(connection, normalize_connection, testfile);
+    unlink(testfile);
+}
+
+static void
+assert_reread_same(NMConnection *connection, NMConnection *reread)
+{
+    nmtst_assert_connection_verifies_without_normalization(reread);
+    nmtst_assert_connection_equals(connection, TRUE, reread, FALSE);
+}
+
+static void
+write_test_connection_reread(NMConnection * connection,
+                             char **        testfile,
+                             NMConnection **out_reread,
+                             gboolean *     out_reread_same)
+{
+    uid_t           owner_uid;
+    gid_t           owner_grp;
+    gboolean        success;
+    GError *        error   = NULL;
+    GError **       p_error = (nmtst_get_rand_uint32() % 2) ? &error : NULL;
+    gs_unref_object NMConnection *connection_normalized = NULL;
+
+    g_assert(NM_IS_CONNECTION(connection));
+    g_assert(testfile && !*testfile);
+
+    owner_uid = geteuid();
+    owner_grp = getegid();
+
+    connection_normalized = nmtst_connection_duplicate_and_normalize(connection);
+
+    success = nms_keyfile_writer_test_connection(connection_normalized,
+                                                 TEST_SCRATCH_DIR,
+                                                 owner_uid,
+                                                 owner_grp,
+                                                 testfile,
+                                                 out_reread,
+                                                 out_reread_same,
+                                                 p_error);
+    g_assert_no_error(error);
+    g_assert(success);
+    g_assert(*testfile && (*testfile)[0]);
+}
+
+static void
+write_test_connection(NMConnection *connection, char **testfile)
+{
+    gs_unref_object NMConnection *reread      = NULL;
+    gboolean                      reread_same = FALSE;
+
+    write_test_connection_reread(connection, testfile, &reread, &reread_same);
+    assert_reread_same(connection, reread);
+    g_assert(reread_same);
+}
+
+static void
+write_test_connection_and_reread(NMConnection *connection, gboolean normalize_connection)
+{
+    gs_free char *testfile = NULL;
+
+    g_assert(NM_IS_CONNECTION(connection));
+
+    write_test_connection(connection, &testfile);
+    assert_reread_and_unlink(connection, normalize_connection, testfile);
+}
+
+static GKeyFile *
+keyfile_load_from_file(const char *testfile)
+{
+    GKeyFile *keyfile;
+    GError *  error = NULL;
+    gboolean  success;
+
+    g_assert(testfile && *testfile);
+
+    keyfile = g_key_file_new();
+    success = g_key_file_load_from_file(keyfile, testfile, G_KEY_FILE_NONE, &error);
+    g_assert_no_error(error);
+    g_assert(success);
+
+    return keyfile;
+}
+
+static void
+_setting_copy_property_gbytes(NMConnection *src,
+                              NMConnection *dst,
+                              const char *  setting_name,
+                              const char *  property_name)
+{
+    gs_unref_bytes GBytes *blob = NULL;
+    NMSetting *            s_src;
+    NMSetting *            s_dst;
+
+    g_assert(NM_IS_CONNECTION(src));
+    g_assert(NM_IS_CONNECTION(dst));
+    g_assert(setting_name);
+    g_assert(property_name);
+
+    s_src = nm_connection_get_setting_by_name(src, setting_name);
+    g_assert(NM_IS_SETTING(s_src));
+    s_dst = nm_connection_get_setting_by_name(dst, setting_name);
+    g_assert(NM_IS_SETTING(s_dst));
+
+    g_object_get(s_src, property_name, &blob, NULL);
+    g_object_set(s_dst, property_name, blob, NULL);
+}
+
+/*****************************************************************************/
+
+static void
+test_read_valid_wired_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWired *              s_wired;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingIPConfig *           s_ip6;
+    NMIPRoute *                   route;
+    const char *                  mac;
+    char expected_mac_address[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
+
+    NMTST_EXPECT_NM_INFO("*ipv4.addresses:*semicolon at the end*addresses1*");
+    NMTST_EXPECT_NM_INFO("*ipv4.addresses:*semicolon at the end*addresses2*");
+    NMTST_EXPECT_NM_WARN("*missing prefix length*address4*");
+    NMTST_EXPECT_NM_WARN("*missing prefix length*address5*");
+    NMTST_EXPECT_NM_WARN("*ipv4.dns: ignoring invalid DNS server IPv4 address 'bogus'*");
+    NMTST_EXPECT_NM_INFO("*ipv4.routes*semicolon at the end*routes2*");
+    NMTST_EXPECT_NM_INFO("*ipv4.routes*semicolon at the end*routes3*");
+    NMTST_EXPECT_NM_INFO("*ipv4.routes*semicolon at the end*routes5*");
+    NMTST_EXPECT_NM_INFO("*ipv4.routes*semicolon at the end*routes8*");
+    NMTST_EXPECT_NM_WARN("*missing prefix length*address4*");
+    NMTST_EXPECT_NM_INFO("*ipv6.address*semicolon at the end*address5*");
+    NMTST_EXPECT_NM_WARN("*missing prefix length*address5*");
+    NMTST_EXPECT_NM_INFO("*ipv6.address*semicolon at the end*address7*");
+    NMTST_EXPECT_NM_INFO("*ipv6.routes*semicolon at the end*routes1*");
+    NMTST_EXPECT_NM_INFO("*ipv6.route*semicolon at the end*route6*");
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_Connection");
+    g_test_assert_expected_messages();
+
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Test Wired Connection");
+    g_assert_cmpstr(nm_setting_connection_get_uuid(s_con),
+                    ==,
+                    "4e80a56d-c99f-4aad-a6dd-b449bc398c57");
+    g_assert_cmpuint(nm_setting_connection_get_timestamp(s_con), ==, 6654332);
+    g_assert(nm_setting_connection_get_autoconnect(s_con));
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired);
+
+    mac = nm_setting_wired_get_mac_address(s_wired);
+    g_assert(mac);
+    g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, sizeof(expected_mac_address)));
+    g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 1400);
+
+    s_ip4 = nm_connection_get_setting_ip4_config(connection);
+    g_assert(s_ip4);
+    g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4),
+                    ==,
+                    NM_SETTING_IP4_CONFIG_METHOD_MANUAL);
+    g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip4), ==, 2);
+    g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 0), ==, "4.2.2.1");
+    g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip4, 1), ==, "4.2.2.2");
+
+    /* IPv4 addresses */
+    g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 10);
+    check_ip_address(s_ip4, 0, "2.3.4.5", 24);
+    check_ip_address(s_ip4, 1, "192.168.0.5", 24);
+    check_ip_address(s_ip4, 2, "1.2.3.4", 16);
+    check_ip_address(s_ip4, 3, "3.4.5.6", 16);
+    check_ip_address(s_ip4, 4, "4.5.6.7", 24);
+    check_ip_address(s_ip4, 5, "5.6.7.8", 24);
+    check_ip_address(s_ip4, 6, "1.2.3.30", 24);
+    check_ip_address(s_ip4, 7, "1.2.3.30", 25);
+    check_ip_address(s_ip4, 8, "1.2.3.31", 24);
+    check_ip_address(s_ip4, 9, "1.2.3.31", 25);
+
+    /* IPv4 gateway */
+    g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip4), ==, "2.3.4.6");
+
+    /* IPv4 routes */
+    g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip4), ==, 14);
+    check_ip_route(s_ip4, 0, "5.6.7.8", 32, NULL, -1);
+    check_ip_route(s_ip4, 1, "1.2.3.0", 24, "2.3.4.8", 99);
+    check_ip_route(s_ip4, 2, "1.1.1.2", 12, NULL, -1);
+    check_ip_route(s_ip4, 3, "1.1.1.3", 13, NULL, -1);
+    check_ip_route(s_ip4, 4, "1.1.1.4", 14, "2.2.2.4", -1);
+    check_ip_route(s_ip4, 5, "1.1.1.5", 15, "2.2.2.5", -1);
+    check_ip_route(s_ip4, 6, "1.1.1.6", 16, "2.2.2.6", 0);
+    check_ip_route(s_ip4, 7, "1.1.1.7", 17, NULL, -1);
+    check_ip_route(s_ip4, 8, "1.1.1.8", 18, NULL, -1);
+    check_ip_route(s_ip4, 9, "1.1.1.9", 19, NULL, 0);
+    check_ip_route(s_ip4, 10, "1.1.1.10", 21, NULL, 0);
+    check_ip_route(s_ip4, 11, "1.1.1.10", 20, NULL, 0);
+    check_ip_route(s_ip4, 12, "1.1.1.11", 21, NULL, 21);
+    check_ip_route(s_ip4, 13, "1.2.3.4", 32, NULL, -1);
+
+    /* Route attributes */
+    route = nm_setting_ip_config_get_route(s_ip4, 12);
+    g_assert(route);
+
+    nmtst_assert_route_attribute_uint32(route, NM_IP_ROUTE_ATTRIBUTE_CWND, 10);
+    nmtst_assert_route_attribute_uint32(route, NM_IP_ROUTE_ATTRIBUTE_MTU, 1430);
+    nmtst_assert_route_attribute_boolean(route, NM_IP_ROUTE_ATTRIBUTE_LOCK_CWND, TRUE);
+    nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_SRC, "7.7.7.7");
+    nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "unicast");
+
+    route = nm_setting_ip_config_get_route(s_ip4, 13);
+    g_assert(route);
+
+    nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_TYPE, "local");
+
+    s_ip6 = nm_connection_get_setting_ip6_config(connection);
+    g_assert(s_ip6);
+
+    g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6),
+                    ==,
+                    NM_SETTING_IP6_CONFIG_METHOD_MANUAL);
+
+    g_assert_cmpint(nm_setting_ip_config_get_num_dns(s_ip6), ==, 2);
+    g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 0), ==, "1111:dddd::aaaa");
+    g_assert_cmpstr(nm_setting_ip_config_get_dns(s_ip6, 1), ==, "1::cafe");
+    g_assert_cmpint(nm_setting_ip_config_get_num_dns_searches(s_ip6), ==, 3);
+    g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 0), ==, "super-domain.com");
+    g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 1), ==, "redhat.com");
+    g_assert_cmpstr(nm_setting_ip_config_get_dns_search(s_ip6, 2), ==, "gnu.org");
+
+    /* IPv6 addresses */
+    g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 10);
+    check_ip_address(s_ip6, 0, "2:3:4:5:6:7:8:9", 64);
+    check_ip_address(s_ip6, 1, "abcd:1234:ffff::cdde", 64);
+    check_ip_address(s_ip6, 2, "1:2:3:4:5:6:7:8", 96);
+    check_ip_address(s_ip6, 3, "3:4:5:6:7:8:9:0", 128);
+    check_ip_address(s_ip6, 4, "3:4:5:6:7:8:9:14", 64);
+    check_ip_address(s_ip6, 5, "3:4:5:6:7:8:9:15", 64);
+    check_ip_address(s_ip6, 6, "3:4:5:6:7:8:9:16", 66);
+    check_ip_address(s_ip6, 7, "3:4:5:6:7:8:9:17", 67);
+    check_ip_address(s_ip6, 8, "3:4:5:6:7:8:9:18", 68);
+    check_ip_address(s_ip6, 9, "3:4:5:6:7:8:9:19", 69);
+
+    /* IPv6 gateway */
+    g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, "2:3:4:5:1:2:3:4");
+
+    /* Routes */
+    g_assert_cmpint(nm_setting_ip_config_get_num_routes(s_ip6), ==, 7);
+    check_ip_route(s_ip6, 0, "d:e:f:0:1:2:3:4", 64, "f:e:d:c:1:2:3:4", -1);
+    check_ip_route(s_ip6, 1, "a:b:c:d::", 64, "f:e:d:c:1:2:3:4", 99);
+    check_ip_route(s_ip6, 2, "8:7:6:5:4:3:2:1", 128, NULL, -1);
+    check_ip_route(s_ip6, 3, "6:7:8:9:0:1:2:3", 126, NULL, 1);
+    check_ip_route(s_ip6, 4, "7:8:9:0:1:2:3:4", 125, NULL, 5);
+    check_ip_route(s_ip6, 5, "8:9:0:1:2:3:4:5", 124, NULL, 6);
+    check_ip_route(s_ip6, 6, "8:9:0:1:2:3:4:6", 123, NULL, -1);
+
+    /* Route attributes */
+    route = nm_setting_ip_config_get_route(s_ip6, 6);
+    g_assert(route);
+    nmtst_assert_route_attribute_string(route, NM_IP_ROUTE_ATTRIBUTE_FROM, "abce::/63");
+}
+
+static void
+add_one_ip_address(NMSettingIPConfig *s_ip, const char *addr, guint32 prefix)
+{
+    NMIPAddress * ip_addr;
+    gs_free_error GError *error = NULL;
+
+    ip_addr = nm_ip_address_new(NM_IS_SETTING_IP4_CONFIG(s_ip) ? AF_INET : AF_INET6,
+                                addr,
+                                prefix,
+                                &error);
+    g_assert_no_error(error);
+    nm_setting_ip_config_add_address(s_ip, ip_addr);
+    nm_ip_address_unref(ip_addr);
+}
+
+static void
+add_one_ip_route(NMSettingIPConfig *s_ip,
+                 const char *       dest,
+                 const char *       nh,
+                 guint32            prefix,
+                 gint64             metric)
+{
+    NMIPRoute *   route;
+    gs_free_error GError *error = NULL;
+
+    g_assert(prefix > 0);
+    route = nm_ip_route_new(NM_IS_SETTING_IP4_CONFIG(s_ip) ? AF_INET : AF_INET6,
+                            dest,
+                            prefix,
+                            nh,
+                            metric,
+                            &error);
+    g_assert_no_error(error);
+    nm_setting_ip_config_add_route(s_ip, route);
+    nm_ip_route_unref(route);
+}
+
+static void
+test_write_wired_connection(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWired *              s_wired;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingIPConfig *           s_ip6;
+    NMIPRoute *                   rt;
+    const char *                  mac         = "99:88:77:66:55:44";
+    const char *                  dns1        = "4.2.2.1";
+    const char *                  dns2        = "4.2.2.2";
+    const char *                  address1    = "192.168.0.5";
+    const char *                  address2    = "1.2.3.4";
+    const char *                  gw          = "192.168.0.1";
+    const char *                  route1      = "10.10.10.2";
+    const char *                  route1_nh   = "10.10.10.1";
+    const char *                  route2      = "1.1.1.1";
+    const char *                  route2_nh   = "1.2.1.1";
+    const char *                  route3      = "2.2.2.2";
+    const char *                  route3_nh   = NULL;
+    const char *                  route4      = "3.3.3.3";
+    const char *                  route4_nh   = NULL;
+    const char *                  dns6_1      = "1::cafe";
+    const char *                  dns6_2      = "2::cafe";
+    const char *                  address6_1  = "abcd::beef";
+    const char *                  address6_2  = "dcba::beef";
+    const char *                  route6_1    = "1:2:3:4:5:6:7:8";
+    const char *                  route6_1_nh = "8:7:6:5:4:3:2:1";
+    const char *                  route6_2    = "2001::1000";
+    const char *                  route6_2_nh = "2001::1111";
+    const char *                  route6_3    = "4:5:6:7:8:9:0:1";
+    const char *                  route6_3_nh = "::";
+    const char *                  route6_4    = "5:6:7:8:9:0:1:2";
+    const char *                  route6_4_nh = "::";
+    guint64                       timestamp   = 0x12345678L;
+    GError *                      error       = NULL;
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Work Wired",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_AUTOCONNECT,
+                 FALSE,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRED_SETTING_NAME,
+                 NM_SETTING_CONNECTION_TIMESTAMP,
+                 timestamp,
+                 NULL);
+
+    /* Wired setting */
+
+    s_wired = NM_SETTING_WIRED(nm_setting_wired_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_wired));
+
+    g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, 900, NULL);
+
+    /* IP4 setting */
+
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+
+    g_object_set(s_ip4,
+                 NM_SETTING_IP_CONFIG_METHOD,
+                 NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+                 NM_SETTING_IP_CONFIG_GATEWAY,
+                 gw,
+                 NULL);
+
+    /* Addresses */
+    add_one_ip_address(s_ip4, address1, 24);
+    add_one_ip_address(s_ip4, address2, 8);
+
+    /* Routes */
+    add_one_ip_route(s_ip4, route1, route1_nh, 24, 3);
+    add_one_ip_route(s_ip4, route2, route2_nh, 8, 1);
+    add_one_ip_route(s_ip4, route3, route3_nh, 7, -1);
+
+    rt = nm_ip_route_new(AF_INET, route4, 6, route4_nh, 4, &error);
+    g_assert_no_error(error);
+    nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_CWND, g_variant_new_uint32(10));
+    nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_MTU, g_variant_new_uint32(1492));
+    nm_ip_route_set_attribute(rt, NM_IP_ROUTE_ATTRIBUTE_SRC, g_variant_new_string("1.2.3.4"));
+    g_assert(nm_setting_ip_config_add_route(s_ip4, rt));
+    nm_ip_route_unref(rt);
+
+    /* DNS servers */
+    nm_setting_ip_config_add_dns(s_ip4, dns1);
+    nm_setting_ip_config_add_dns(s_ip4, dns2);
+
+    /* IP6 setting */
+
+    s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip6));
+
+    g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_MANUAL, NULL);
+
+    /* Addresses */
+    add_one_ip_address(s_ip6, address6_1, 64);
+    add_one_ip_address(s_ip6, address6_2, 56);
+
+    /* Routes */
+    add_one_ip_route(s_ip6, route6_1, route6_1_nh, 64, 3);
+    add_one_ip_route(s_ip6, route6_2, route6_2_nh, 56, 1);
+    add_one_ip_route(s_ip6, route6_3, route6_3_nh, 63, 5);
+    add_one_ip_route(s_ip6, route6_4, route6_4_nh, 62, -1);
+
+    /* DNS servers */
+    nm_setting_ip_config_add_dns(s_ip6, dns6_1);
+    nm_setting_ip_config_add_dns(s_ip6, dns6_2);
+
+    /* DNS searches */
+    nm_setting_ip_config_add_dns_search(s_ip6, "wallaceandgromit.com");
+
+    write_test_connection_and_reread(connection, FALSE);
+}
+
+static void
+test_read_ip6_wired_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWired *              s_wired;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingIPConfig *           s_ip6;
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_Connection_IP6");
+
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Test Wired Connection IP6");
+    g_assert_cmpstr(nm_setting_connection_get_uuid(s_con),
+                    ==,
+                    "4e80a56d-c99f-4aad-a6dd-b449bc398c57");
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired);
+
+    s_ip4 = nm_connection_get_setting_ip4_config(connection);
+    g_assert(s_ip4);
+    g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4),
+                    ==,
+                    NM_SETTING_IP4_CONFIG_METHOD_DISABLED);
+    g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip4), ==, 0);
+
+    s_ip6 = nm_connection_get_setting_ip6_config(connection);
+    g_assert(s_ip6);
+    g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip6),
+                    ==,
+                    NM_SETTING_IP6_CONFIG_METHOD_MANUAL);
+    g_assert_cmpint(nm_setting_ip_config_get_num_addresses(s_ip6), ==, 1);
+    check_ip_address(s_ip6, 0, "abcd:1234:ffff::cdde", 64);
+    g_assert_cmpstr(nm_setting_ip_config_get_gateway(s_ip6), ==, "abcd:1234:ffff::cdd1");
+}
+
+static void
+test_write_ip6_wired_connection(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWired *              s_wired;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingIPConfig *           s_ip6;
+    const char *                  dns     = "1::cafe";
+    const char *                  address = "abcd::beef";
+    const char *                  gw      = "dcba::beef";
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Work Wired IP6",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_AUTOCONNECT,
+                 FALSE,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRED_SETTING_NAME,
+                 NULL);
+
+    /* Wired setting */
+
+    s_wired = NM_SETTING_WIRED(nm_setting_wired_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_wired));
+
+    /* IP4 setting */
+
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED, NULL);
+
+    /* IP6 setting */
+
+    s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip6));
+
+    g_object_set(s_ip6,
+                 NM_SETTING_IP_CONFIG_METHOD,
+                 NM_SETTING_IP6_CONFIG_METHOD_MANUAL,
+                 NM_SETTING_IP_CONFIG_GATEWAY,
+                 gw,
+                 NULL);
+
+    /* Addresses */
+    add_one_ip_address(s_ip6, address, 64);
+
+    /* DNS servers */
+    nm_setting_ip_config_add_dns(s_ip6, dns);
+
+    /* DNS searches */
+    nm_setting_ip_config_add_dns_search(s_ip6, "wallaceandgromit.com");
+
+    write_test_connection_and_reread(connection, FALSE);
+}
+
+static void
+test_read_wired_mac_case(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWired *              s_wired;
+    const char *                  mac;
+    char expected_mac_address[ETH_ALEN] = {0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55};
+
+    NMTST_EXPECT_NM_INFO("*ipv4.addresses*semicolon at the end*addresses1*");
+    NMTST_EXPECT_NM_INFO("*ipv4.addresses*semicolon at the end*addresses2*");
+    NMTST_EXPECT_NM_INFO("*ipv6.routes*semicolon at the end*routes1*");
+    connection =
+        keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_Connection_MAC_Case");
+    g_test_assert_expected_messages();
+
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Test Wired Connection MAC Case");
+    g_assert_cmpstr(nm_setting_connection_get_uuid(s_con),
+                    ==,
+                    "4e80a56d-c99f-4aad-a6dd-b449bc398c57");
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired);
+    mac = nm_setting_wired_get_mac_address(s_wired);
+    g_assert(mac);
+    g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac_address, sizeof(expected_mac_address)));
+}
+
+static void
+test_read_mac_old_format(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWired *              s_wired;
+    const char *                  mac;
+    char                          expected_mac[ETH_ALEN] = {0x00, 0x11, 0xaa, 0xbb, 0xcc, 0x55};
+    char expected_cloned_mac[ETH_ALEN]                   = {0x00, 0x16, 0xaa, 0xbb, 0xcc, 0xfe};
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_MAC_Old_Format");
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired);
+
+    mac = nm_setting_wired_get_mac_address(s_wired);
+    g_assert(mac);
+    g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, ETH_ALEN));
+
+    mac = nm_setting_wired_get_cloned_mac_address(s_wired);
+    g_assert(mac);
+    g_assert(nm_utils_hwaddr_matches(mac, -1, expected_cloned_mac, ETH_ALEN));
+}
+
+static void
+test_read_mac_ib_old_format(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingInfiniband *         s_ib;
+    const char *                  mac;
+    guint8 expected_mac[INFINIBAND_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
+                                            0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34,
+                                            0x45, 0x56, 0x67, 0x78, 0x89, 0x90};
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_MAC_IB_Old_Format");
+
+    s_ib = nm_connection_get_setting_infiniband(connection);
+    g_assert(s_ib);
+
+    /* MAC address */
+    mac = nm_setting_infiniband_get_mac_address(s_ib);
+    g_assert(mac);
+    g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, sizeof(expected_mac)));
+}
+
+static void
+test_read_valid_wireless_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWireless *           s_wireless;
+    NMSettingIPConfig *           s_ip4;
+    const char *                  bssid;
+    const guint8                  expected_bssid[ETH_ALEN] = {0x00, 0x1a, 0x33, 0x44, 0x99, 0x82};
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wireless_Connection");
+
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "Test Wireless Connection");
+    g_assert_cmpstr(nm_setting_connection_get_uuid(s_con),
+                    ==,
+                    "2f962388-e5f3-45af-a62c-ac220b8f7baa");
+    g_assert_cmpuint(nm_setting_connection_get_timestamp(s_con), ==, 1226604314);
+    g_assert(nm_setting_connection_get_autoconnect(s_con) == FALSE);
+
+    s_wireless = nm_connection_get_setting_wireless(connection);
+    g_assert(s_wireless);
+    bssid = nm_setting_wireless_get_bssid(s_wireless);
+    g_assert(bssid);
+    g_assert(nm_utils_hwaddr_matches(bssid, -1, expected_bssid, sizeof(expected_bssid)));
+
+    s_ip4 = nm_connection_get_setting_ip4_config(connection);
+    g_assert(s_ip4);
+    g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
+}
+
+static void
+test_write_wireless_connection(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWireless *           s_wireless;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingIPConfig *           s_ip6;
+    const char *                  bssid = "aa:b9:a1:74:55:44";
+    GBytes *                      ssid;
+    unsigned char                 tmpssid[] = {0x31, 0x33, 0x33, 0x37};
+    guint64                       timestamp = 0x12344433L;
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Work Wireless",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_AUTOCONNECT,
+                 FALSE,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRELESS_SETTING_NAME,
+                 NM_SETTING_CONNECTION_TIMESTAMP,
+                 timestamp,
+                 NULL);
+
+    /* Wireless setting */
+
+    s_wireless = NM_SETTING_WIRELESS(nm_setting_wireless_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_wireless));
+
+    ssid = g_bytes_new(tmpssid, sizeof(tmpssid));
+
+    g_object_set(s_wireless,
+                 NM_SETTING_WIRELESS_BSSID,
+                 bssid,
+                 NM_SETTING_WIRELESS_SSID,
+                 ssid,
+                 NM_SETTING_WIRED_MTU,
+                 1000,
+                 NULL);
+
+    g_bytes_unref(ssid);
+
+    /* IP4 setting */
+
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+    /* IP6 setting */
+
+    s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip6));
+
+    g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
+
+    write_test_connection_and_reread(connection, FALSE);
+}
+
+static void
+test_read_string_ssid(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWireless *           s_wireless;
+    GBytes *                      ssid;
+    const guint8 *                ssid_data;
+    gsize                         ssid_len;
+    const char *                  expected_ssid = "blah blah ssid 1234";
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_String_SSID");
+
+    s_wireless = nm_connection_get_setting_wireless(connection);
+    g_assert(s_wireless);
+
+    ssid = nm_setting_wireless_get_ssid(s_wireless);
+    g_assert(ssid);
+
+    ssid_data = g_bytes_get_data(ssid, &ssid_len);
+    g_assert_cmpmem(ssid_data, ssid_len, expected_ssid, strlen(expected_ssid));
+}
+
+static void
+test_write_string_ssid(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWireless *           s_wireless;
+    NMSettingIPConfig *           s_ip4;
+    char *                        tmp;
+    gs_free char *                testfile = NULL;
+    GBytes *                      ssid;
+    unsigned char                 tmpssid[] = {65, 49, 50, 51, 32, 46, 92, 46, 36, 37, 126, 93};
+    nm_auto_unref_keyfile GKeyFile *keyfile = NULL;
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "String SSID Test",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRELESS_SETTING_NAME,
+                 NULL);
+
+    /* Wireless setting */
+
+    s_wireless = NM_SETTING_WIRELESS(nm_setting_wireless_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_wireless));
+
+    ssid = g_bytes_new(tmpssid, sizeof(tmpssid));
+    g_object_set(s_wireless, NM_SETTING_WIRELESS_SSID, ssid, NULL);
+    g_bytes_unref(ssid);
+
+    /* IP4 setting */
+
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+    write_test_connection(connection, &testfile);
+
+    /* Ensure the SSID was written out as a string */
+    keyfile = keyfile_load_from_file(testfile);
+    tmp     = g_key_file_get_string(keyfile, "wifi", NM_SETTING_WIRELESS_SSID, NULL);
+    g_assert(tmp);
+    g_assert_cmpmem(tmp, strlen(tmp), tmpssid, sizeof(tmpssid));
+    g_free(tmp);
+
+    assert_reread_and_unlink(connection, TRUE, testfile);
+}
+
+static void
+test_read_intlist_ssid(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWireless *           s_wifi;
+    GBytes *                      ssid;
+    const guint8 *                ssid_data;
+    gsize                         ssid_len;
+    const char *                  expected_ssid = "blah1234";
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Intlist_SSID");
+
+    s_wifi = nm_connection_get_setting_wireless(connection);
+    g_assert(s_wifi);
+
+    ssid = nm_setting_wireless_get_ssid(s_wifi);
+    g_assert(ssid != NULL);
+    ssid_data = g_bytes_get_data(ssid, &ssid_len);
+    g_assert_cmpmem(ssid_data, ssid_len, expected_ssid, strlen(expected_ssid));
+}
+
+static void
+test_write_intlist_ssid(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWireless *           s_wifi;
+    NMSettingIPConfig *           s_ip4;
+    gs_free char *                testfile = NULL;
+    GBytes *                      ssid;
+    unsigned char                 tmpssid[] = {65, 49, 50, 51, 0, 50, 50};
+    gs_free_error GError *error             = NULL;
+    nm_auto_unref_keyfile GKeyFile *keyfile = NULL;
+    int *                           intlist;
+    gsize                           len = 0, i;
+
+    connection = nm_simple_connection_new();
+    g_assert(connection);
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    g_assert(s_con);
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Intlist SSID Test",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRELESS_SETTING_NAME,
+                 NULL);
+
+    /* Wireless setting */
+    s_wifi = NM_SETTING_WIRELESS(nm_setting_wireless_new());
+    g_assert(s_wifi);
+    nm_connection_add_setting(connection, NM_SETTING(s_wifi));
+
+    ssid = g_bytes_new(tmpssid, sizeof(tmpssid));
+    g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL);
+    g_bytes_unref(ssid);
+
+    /* IP4 setting */
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    g_assert(s_ip4);
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+    write_test_connection(connection, &testfile);
+
+    /* Ensure the SSID was written out as an int list */
+    keyfile = keyfile_load_from_file(testfile);
+
+    intlist = g_key_file_get_integer_list(keyfile, "wifi", NM_SETTING_WIRELESS_SSID, &len, &error);
+    g_assert_no_error(error);
+    g_assert(intlist);
+    g_assert_cmpint(len, ==, sizeof(tmpssid));
+
+    for (i = 0; i < len; i++)
+        g_assert_cmpint(intlist[i], ==, tmpssid[i]);
+    g_free(intlist);
+
+    assert_reread_and_unlink(connection, TRUE, testfile);
+}
+
+static void
+test_read_intlike_ssid(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWireless *           s_wifi;
+    GBytes *                      ssid;
+    const char *                  expected_ssid = "101";
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Intlike_SSID");
+
+    s_wifi = nm_connection_get_setting_wireless(connection);
+    g_assert(s_wifi);
+
+    ssid = nm_setting_wireless_get_ssid(s_wifi);
+    g_assert(ssid);
+    g_assert(nm_utils_gbytes_equal_mem(ssid, expected_ssid, strlen(expected_ssid)));
+}
+
+static void
+test_read_intlike_ssid_2(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWireless *           s_wifi;
+    GBytes *                      ssid;
+    const char *                  expected_ssid = "11;12;13;";
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Intlike_SSID_2");
+
+    s_wifi = nm_connection_get_setting_wireless(connection);
+    g_assert(s_wifi);
+
+    ssid = nm_setting_wireless_get_ssid(s_wifi);
+    g_assert(ssid);
+    g_assert(nm_utils_gbytes_equal_mem(ssid, expected_ssid, strlen(expected_ssid)));
+}
+
+static void
+test_write_intlike_ssid(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWireless *           s_wifi;
+    NMSettingIPConfig *           s_ip4;
+    gs_free char *                testfile = NULL;
+    GBytes *                      ssid;
+    unsigned char                 tmpssid[] = {49, 48, 49};
+    gs_free_error GError *error             = NULL;
+    nm_auto_unref_keyfile GKeyFile *keyfile = NULL;
+    char *                          tmp;
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    g_assert(s_con);
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Intlike SSID Test",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRELESS_SETTING_NAME,
+                 NULL);
+
+    /* Wireless setting */
+    s_wifi = NM_SETTING_WIRELESS(nm_setting_wireless_new());
+    g_assert(s_wifi);
+    nm_connection_add_setting(connection, NM_SETTING(s_wifi));
+
+    ssid = g_bytes_new(tmpssid, sizeof(tmpssid));
+    g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL);
+    g_bytes_unref(ssid);
+
+    /* IP4 setting */
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    g_assert(s_ip4);
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+    write_test_connection(connection, &testfile);
+
+    /* Ensure the SSID was written out as a plain "101" */
+    keyfile = keyfile_load_from_file(testfile);
+
+    tmp = g_key_file_get_string(keyfile, "wifi", NM_SETTING_WIRELESS_SSID, &error);
+    g_assert_no_error(error);
+    g_assert(tmp);
+    g_assert_cmpstr(tmp, ==, "101");
+    g_free(tmp);
+
+    assert_reread_and_unlink(connection, TRUE, testfile);
+}
+
+static void
+test_write_intlike_ssid_2(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWireless *           s_wifi;
+    NMSettingIPConfig *           s_ip4;
+    gs_free char *                testfile = NULL;
+    GBytes *                      ssid;
+    unsigned char                 tmpssid[] = {49, 49, 59, 49, 50, 59, 49, 51, 59};
+    gs_free_error GError *error             = NULL;
+    nm_auto_unref_keyfile GKeyFile *keyfile = NULL;
+    char *                          tmp;
+
+    connection = nm_simple_connection_new();
+    g_assert(connection);
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    g_assert(s_con);
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Intlike SSID Test 2",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRELESS_SETTING_NAME,
+                 NULL);
+
+    /* Wireless setting */
+    s_wifi = NM_SETTING_WIRELESS(nm_setting_wireless_new());
+    g_assert(s_wifi);
+    nm_connection_add_setting(connection, NM_SETTING(s_wifi));
+
+    ssid = g_bytes_new(tmpssid, sizeof(tmpssid));
+    g_object_set(s_wifi, NM_SETTING_WIRELESS_SSID, ssid, NULL);
+    g_bytes_unref(ssid);
+
+    /* IP4 setting */
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    g_assert(s_ip4);
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+    write_test_connection(connection, &testfile);
+
+    /* Ensure the SSID was written out as a plain "11;12;13;" */
+    keyfile = keyfile_load_from_file(testfile);
+
+    tmp = g_key_file_get_string(keyfile, "wifi", NM_SETTING_WIRELESS_SSID, &error);
+    g_assert_no_error(error);
+    g_assert(tmp);
+    g_assert_cmpstr(tmp, ==, "11\\;12\\;13\\;");
+    g_free(tmp);
+
+    assert_reread_and_unlink(connection, TRUE, testfile);
+}
+
+static void
+test_read_bt_dun_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingBluetooth *          s_bluetooth;
+    NMSettingSerial *             s_serial;
+    NMSettingGsm *                s_gsm;
+    const char *                  bdaddr;
+    const guint8                  expected_bdaddr[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/ATT_Data_Connect_BT");
+
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "AT&T Data Connect BT");
+    g_assert_cmpstr(nm_setting_connection_get_uuid(s_con),
+                    ==,
+                    "089130ab-ce28-46e4-ad77-d44869b03d19");
+
+    s_bluetooth = nm_connection_get_setting_bluetooth(connection);
+    g_assert(s_bluetooth);
+    bdaddr = nm_setting_bluetooth_get_bdaddr(s_bluetooth);
+    g_assert(bdaddr);
+    g_assert(nm_utils_hwaddr_matches(bdaddr, -1, expected_bdaddr, sizeof(expected_bdaddr)));
+    g_assert_cmpstr(nm_setting_bluetooth_get_connection_type(s_bluetooth),
+                    ==,
+                    NM_SETTING_BLUETOOTH_TYPE_DUN);
+
+    s_gsm = nm_connection_get_setting_gsm(connection);
+    g_assert(s_gsm);
+    g_assert_cmpstr(nm_setting_gsm_get_apn(s_gsm), ==, "ISP.CINGULAR");
+    g_assert_cmpstr(nm_setting_gsm_get_username(s_gsm), ==, "ISP@CINGULARGPRS.COM");
+    g_assert_cmpstr(nm_setting_gsm_get_password(s_gsm), ==, "CINGULAR1");
+
+    s_serial = nm_connection_get_setting_serial(connection);
+    g_assert(s_serial);
+    g_assert(nm_setting_serial_get_parity(s_serial) == NM_SETTING_SERIAL_PARITY_ODD);
+}
+
+static void
+test_write_bt_dun_connection(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingBluetooth *          s_bt;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingGsm *                s_gsm;
+    const char *                  bdaddr    = "aa:b9:a1:74:55:44";
+    guint64                       timestamp = 0x12344433L;
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "T-Mobile Funkadelic",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_AUTOCONNECT,
+                 FALSE,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_BLUETOOTH_SETTING_NAME,
+                 NM_SETTING_CONNECTION_TIMESTAMP,
+                 timestamp,
+                 NULL);
+
+    /* Bluetooth setting */
+
+    s_bt = NM_SETTING_BLUETOOTH(nm_setting_bluetooth_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_bt));
+
+    g_object_set(s_bt,
+                 NM_SETTING_BLUETOOTH_BDADDR,
+                 bdaddr,
+                 NM_SETTING_BLUETOOTH_TYPE,
+                 NM_SETTING_BLUETOOTH_TYPE_DUN,
+                 NULL);
+
+    /* IP4 setting */
+
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+    /* GSM setting */
+    s_gsm = NM_SETTING_GSM(nm_setting_gsm_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_gsm));
+
+    g_object_set(s_gsm,
+                 NM_SETTING_GSM_APN,
+                 "internet2.voicestream.com",
+                 NM_SETTING_GSM_USERNAME,
+                 "george.clinton",
+                 NM_SETTING_GSM_PASSWORD,
+                 "parliament",
+                 NULL);
+
+    write_test_connection_and_reread(connection, TRUE);
+}
+
+static void
+test_read_gsm_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingSerial *             s_serial;
+    NMSettingGsm *                s_gsm;
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/ATT_Data_Connect_Plain");
+
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, "AT&T Data Connect");
+    g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con),
+                    ==,
+                    NM_SETTING_GSM_SETTING_NAME);
+
+    /* Plain GSM, so no BT setting expected */
+    g_assert(nm_connection_get_setting_bluetooth(connection) == NULL);
+
+    s_gsm = nm_connection_get_setting_gsm(connection);
+    g_assert(s_gsm);
+    g_assert_cmpstr(nm_setting_gsm_get_apn(s_gsm), ==, "ISP.CINGULAR");
+    g_assert_cmpstr(nm_setting_gsm_get_username(s_gsm), ==, "ISP@CINGULARGPRS.COM");
+    g_assert_cmpstr(nm_setting_gsm_get_password(s_gsm), ==, "CINGULAR1");
+    g_assert_cmpstr(nm_setting_gsm_get_network_id(s_gsm), ==, "24005");
+    g_assert_cmpstr(nm_setting_gsm_get_pin(s_gsm), ==, "2345");
+    g_assert_cmpstr(nm_setting_gsm_get_device_id(s_gsm),
+                    ==,
+                    "da812de91eec16620b06cd0ca5cbc7ea25245222");
+    g_assert_cmpstr(nm_setting_gsm_get_sim_id(s_gsm), ==, "89148000000060671234");
+    g_assert_cmpstr(nm_setting_gsm_get_sim_operator_id(s_gsm), ==, "310260");
+
+    s_serial = nm_connection_get_setting_serial(connection);
+    g_assert(s_serial);
+    g_assert_cmpint(nm_setting_serial_get_parity(s_serial), ==, NM_SETTING_SERIAL_PARITY_ODD);
+}
+
+static void
+test_write_gsm_connection(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingGsm *                s_gsm;
+    guint64                       timestamp = 0x12344433L;
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "T-Mobile Funkadelic 2",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_AUTOCONNECT,
+                 FALSE,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_GSM_SETTING_NAME,
+                 NM_SETTING_CONNECTION_TIMESTAMP,
+                 timestamp,
+                 NULL);
+
+    /* IP4 setting */
+
+    s_ip4 = NM_SETTING_IP_CONFIG(nm_setting_ip4_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+    /* GSM setting */
+    s_gsm = NM_SETTING_GSM(nm_setting_gsm_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_gsm));
+
+    g_object_set(s_gsm,
+                 NM_SETTING_GSM_APN,
+                 "internet2.voicestream.com",
+                 NM_SETTING_GSM_USERNAME,
+                 "george.clinton.again",
+                 NM_SETTING_GSM_PASSWORD,
+                 "parliament2",
+                 NM_SETTING_GSM_PIN,
+                 "123456",
+                 NM_SETTING_GSM_NETWORK_ID,
+                 "254098",
+                 NM_SETTING_GSM_HOME_ONLY,
+                 TRUE,
+                 NM_SETTING_GSM_DEVICE_ID,
+                 "da812de91eec16620b06cd0ca5cbc7ea25245222",
+                 NM_SETTING_GSM_SIM_ID,
+                 "89148000000060671234",
+                 NM_SETTING_GSM_SIM_OPERATOR_ID,
+                 "310260",
+                 NULL);
+
+    write_test_connection_and_reread(connection, TRUE);
+}
+
+static void
+test_read_wired_8021x_tls_blob_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWired *              s_wired;
+    NMSetting8021x *              s_8021x;
+    const char *                  tmp;
+    GBytes *                      blob;
+
+    NMTST_EXPECT_NM_WARN("keyfile: 802-1x.client-cert: certificate or key file "
+                         "'/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*");
+    NMTST_EXPECT_NM_WARN("keyfile: 802-1x.private-key: certificate or key file "
+                         "'/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*");
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_TLS_Blob");
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired != NULL);
+
+    s_8021x = nm_connection_get_setting_802_1x(connection);
+    g_assert(s_8021x != NULL);
+
+    g_assert(nm_setting_802_1x_get_num_eap_methods(s_8021x) == 1);
+    tmp = nm_setting_802_1x_get_eap_method(s_8021x, 0);
+    g_assert(g_strcmp0(tmp, "tls") == 0);
+
+    tmp = nm_setting_802_1x_get_identity(s_8021x);
+    g_assert(g_strcmp0(tmp, "Bill Smith") == 0);
+
+    tmp = nm_setting_802_1x_get_private_key_password(s_8021x);
+    g_assert(g_strcmp0(tmp, "12345testing") == 0);
+
+    g_assert_cmpint(nm_setting_802_1x_get_ca_cert_scheme(s_8021x),
+                    ==,
+                    NM_SETTING_802_1X_CK_SCHEME_BLOB);
+
+    /* Make sure it's not a path, since it's a blob */
+    NMTST_EXPECT_LIBNM_CRITICAL(NMTST_G_RETURN_MSG(scheme == NM_SETTING_802_1X_CK_SCHEME_PATH));
+    tmp = nm_setting_802_1x_get_ca_cert_path(s_8021x);
+    g_test_assert_expected_messages();
+    g_assert(tmp == NULL);
+
+    /* Validate the path */
+    blob = nm_setting_802_1x_get_ca_cert_blob(s_8021x);
+    g_assert(blob != NULL);
+    g_assert_cmpint(g_bytes_get_size(blob), ==, 568);
+
+    tmp = nm_setting_802_1x_get_client_cert_path(s_8021x);
+    g_assert_cmpstr(tmp, ==, "/CASA/dcbw/Desktop/certinfra/client.pem");
+
+    tmp = nm_setting_802_1x_get_private_key_path(s_8021x);
+    g_assert_cmpstr(tmp, ==, "/CASA/dcbw/Desktop/certinfra/client.pem");
+}
+
+static void
+test_read_wired_8021x_tls_bad_path_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWired *              s_wired;
+    NMSetting8021x *              s_8021x;
+    const char *                  tmp;
+    char *                        tmp2;
+
+    NMTST_EXPECT_NM_WARN("*does not exist*");
+    connection =
+        keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_TLS_Path_Missing");
+    g_test_assert_expected_messages();
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired != NULL);
+
+    s_8021x = nm_connection_get_setting_802_1x(connection);
+    g_assert(s_8021x != NULL);
+
+    g_assert(nm_setting_802_1x_get_num_eap_methods(s_8021x) == 1);
+    tmp = nm_setting_802_1x_get_eap_method(s_8021x, 0);
+    g_assert(g_strcmp0(tmp, "tls") == 0);
+
+    tmp = nm_setting_802_1x_get_identity(s_8021x);
+    g_assert(g_strcmp0(tmp, "Bill Smith") == 0);
+
+    tmp = nm_setting_802_1x_get_private_key_password(s_8021x);
+    g_assert(g_strcmp0(tmp, "12345testing") == 0);
+
+    g_assert_cmpint(nm_setting_802_1x_get_ca_cert_scheme(s_8021x),
+                    ==,
+                    NM_SETTING_802_1X_CK_SCHEME_PATH);
+
+    tmp = nm_setting_802_1x_get_ca_cert_path(s_8021x);
+    g_assert_cmpstr(tmp, ==, "/some/random/cert/path.pem");
+
+    tmp2 = g_strdup_printf(TEST_KEYFILES_DIR "/test-key-and-cert.pem");
+
+    tmp = nm_setting_802_1x_get_client_cert_path(s_8021x);
+    g_assert_cmpstr(tmp, ==, tmp2);
+
+    tmp = nm_setting_802_1x_get_private_key_path(s_8021x);
+    g_assert_cmpstr(tmp, ==, tmp2);
+
+    g_free(tmp2);
+}
+
+static void
+test_read_wired_8021x_tls_old_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWired *              s_wired;
+    NMSetting8021x *              s_8021x;
+    const char *                  tmp;
+
+    NMTST_EXPECT_NM_WARN("keyfile: 802-1x.ca-cert: certificate or key file "
+                         "'/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem' does not exist*");
+    NMTST_EXPECT_NM_WARN("keyfile: 802-1x.client-cert: certificate or key file "
+                         "'/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*");
+    NMTST_EXPECT_NM_WARN("keyfile: 802-1x.private-key: certificate or key file "
+                         "'/CASA/dcbw/Desktop/certinfra/client.pem' does not exist*");
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_TLS_Old");
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired != NULL);
+
+    s_8021x = nm_connection_get_setting_802_1x(connection);
+    g_assert(s_8021x != NULL);
+
+    g_assert(nm_setting_802_1x_get_num_eap_methods(s_8021x) == 1);
+    tmp = nm_setting_802_1x_get_eap_method(s_8021x, 0);
+    g_assert(g_strcmp0(tmp, "tls") == 0);
+
+    tmp = nm_setting_802_1x_get_identity(s_8021x);
+    g_assert(g_strcmp0(tmp, "Bill Smith") == 0);
+
+    tmp = nm_setting_802_1x_get_private_key_password(s_8021x);
+    g_assert(g_strcmp0(tmp, "12345testing") == 0);
+
+    tmp = nm_setting_802_1x_get_ca_cert_path(s_8021x);
+    g_assert(g_strcmp0(tmp, "/CASA/dcbw/Desktop/certinfra/CA/eaptest_ca_cert.pem") == 0);
+
+    tmp = nm_setting_802_1x_get_client_cert_path(s_8021x);
+    g_assert(g_strcmp0(tmp, "/CASA/dcbw/Desktop/certinfra/client.pem") == 0);
+
+    tmp = nm_setting_802_1x_get_private_key_path(s_8021x);
+    g_assert(g_strcmp0(tmp, "/CASA/dcbw/Desktop/certinfra/client.pem") == 0);
+}
+
+static void
+test_read_wired_8021x_tls_new_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWired *              s_wired;
+    NMSetting8021x *              s_8021x;
+    const char *                  tmp;
+    char *                        tmp2;
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Wired_TLS_New");
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired != NULL);
+
+    s_8021x = nm_connection_get_setting_802_1x(connection);
+    g_assert(s_8021x != NULL);
+
+    g_assert(nm_setting_802_1x_get_num_eap_methods(s_8021x) == 1);
+    tmp = nm_setting_802_1x_get_eap_method(s_8021x, 0);
+    g_assert(g_strcmp0(tmp, "tls") == 0);
+
+    tmp = nm_setting_802_1x_get_identity(s_8021x);
+    g_assert(g_strcmp0(tmp, "Bill Smith") == 0);
+
+    tmp = nm_setting_802_1x_get_private_key_password(s_8021x);
+    g_assert(g_strcmp0(tmp, "12345testing") == 0);
+
+    tmp2 = g_strdup_printf(TEST_KEYFILES_DIR "/test-ca-cert.pem");
+    tmp  = nm_setting_802_1x_get_ca_cert_path(s_8021x);
+    g_assert_cmpstr(tmp, ==, tmp2);
+    g_free(tmp2);
+
+    tmp2 = g_strdup_printf(TEST_KEYFILES_DIR "/test-key-and-cert.pem");
+
+    tmp = nm_setting_802_1x_get_client_cert_path(s_8021x);
+    g_assert_cmpstr(tmp, ==, tmp2);
+
+    tmp = nm_setting_802_1x_get_private_key_path(s_8021x);
+    g_assert_cmpstr(tmp, ==, tmp2);
+
+    g_free(tmp2);
+}
+
+#define TEST_WIRED_TLS_CA_CERT     TEST_KEYFILES_DIR "/test-ca-cert.pem"
+#define TEST_WIRED_TLS_CLIENT_CERT TEST_KEYFILES_DIR "/test-key-and-cert.pem"
+#define TEST_WIRED_TLS_PRIVKEY     TEST_KEYFILES_DIR "/test-key-and-cert.pem"
+
+static NMConnection *
+create_wired_tls_connection(NMSetting8021xCKScheme scheme)
+{
+    NMTST_UUID_INIT(uuid);
+    NMConnection *       connection;
+    NMSettingConnection *s_con;
+    NMSettingIPConfig *  s_ip4;
+    NMSetting *          s_wired;
+    NMSetting8021x *     s_8021x;
+    gboolean             success;
+    gs_free_error GError *error = NULL;
+
+    connection = nm_simple_connection_new();
+    g_assert(connection != NULL);
+
+    /* Connection setting */
+    s_con = (NMSettingConnection *) nm_setting_connection_new();
+    g_assert(s_con);
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Wired Really Secure TLS",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRED_SETTING_NAME,
+                 NULL);
+
+    /* IP4 setting */
+    s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new();
+    g_assert(s_ip4);
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+
+    /* Wired setting */
+    s_wired = nm_setting_wired_new();
+    g_assert(s_wired);
+    nm_connection_add_setting(connection, s_wired);
+
+    /* 802.1x setting */
+    s_8021x = (NMSetting8021x *) nm_setting_802_1x_new();
+    g_assert(s_8021x);
+    nm_connection_add_setting(connection, NM_SETTING(s_8021x));
+
+    nm_setting_802_1x_add_eap_method(s_8021x, "tls");
+    g_object_set(s_8021x, NM_SETTING_802_1X_IDENTITY, "Bill Smith", NULL);
+
+    success = nm_setting_802_1x_set_ca_cert(s_8021x, TEST_WIRED_TLS_CA_CERT, scheme, NULL, &error);
+    g_assert_no_error(error);
+    g_assert(success);
+
+    success = nm_setting_802_1x_set_client_cert(s_8021x,
+                                                TEST_WIRED_TLS_CLIENT_CERT,
+                                                scheme,
+                                                NULL,
+                                                &error);
+    g_assert_no_error(error);
+    g_assert(success);
+
+    success = nm_setting_802_1x_set_private_key(s_8021x,
+                                                TEST_WIRED_TLS_PRIVKEY,
+                                                "test1",
+                                                scheme,
+                                                NULL,
+                                                &error);
+    g_assert_no_error(error);
+    g_assert(success);
+
+    return connection;
+}
+
+static char *
+get_path(const char *file, gboolean relative)
+{
+    return relative ? g_path_get_basename(file) : g_strdup(file);
+}
+
+static void
+test_write_wired_8021x_tls_connection_path(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    gs_unref_object NMConnection *reread     = NULL;
+    char *                        tmp, *tmp2;
+    gboolean                      success;
+    gs_free char *                testfile      = NULL;
+    nm_auto_unref_keyfile GKeyFile *keyfile     = NULL;
+    gboolean                        relative    = FALSE;
+    gboolean                        reread_same = FALSE;
+
+    connection = create_wired_tls_connection(NM_SETTING_802_1X_CK_SCHEME_PATH);
+    g_assert(connection != NULL);
+
+    write_test_connection_reread(connection, &testfile, &reread, &reread_same);
+    nmtst_assert_connection_verifies_without_normalization(reread);
+    _setting_copy_property_gbytes(connection,
+                                  reread,
+                                  NM_SETTING_802_1X_SETTING_NAME,
+                                  NM_SETTING_802_1X_CA_CERT);
+    _setting_copy_property_gbytes(connection,
+                                  reread,
+                                  NM_SETTING_802_1X_SETTING_NAME,
+                                  NM_SETTING_802_1X_CLIENT_CERT);
+    _setting_copy_property_gbytes(connection,
+                                  reread,
+                                  NM_SETTING_802_1X_SETTING_NAME,
+                                  NM_SETTING_802_1X_PRIVATE_KEY);
+    assert_reread_same(connection, reread);
+    g_clear_object(&reread);
+
+    /* Read the connection back in and compare it to the one we just wrote out */
+    reread = keyfile_read_connection_from_file(testfile);
+
+    success = nm_connection_compare(connection, reread, NM_SETTING_COMPARE_FLAG_EXACT);
+    if (!reread) {
+        g_warning("Written and re-read connection weren't the same");
+        g_assert(success);
+    }
+
+    /* Ensure the cert and key values are properly written out */
+    keyfile = keyfile_load_from_file(testfile);
+
+    /* Depending on whether this test is being run from 'make check' or
+     * 'make distcheck' we might be using relative paths (check) or
+     * absolute ones (distcheck).
+     */
+    tmp2 = g_path_get_dirname(testfile);
+    if (g_strcmp0(tmp2, TEST_KEYFILES_DIR) == 0)
+        relative = TRUE;
+    g_free(tmp2);
+
+    /* CA cert */
+    tmp  = g_key_file_get_string(keyfile,
+                                NM_SETTING_802_1X_SETTING_NAME,
+                                NM_SETTING_802_1X_CA_CERT,
+                                NULL);
+    tmp2 = get_path(TEST_WIRED_TLS_CA_CERT, relative);
+    g_assert_cmpstr(tmp, ==, tmp2);
+    g_free(tmp2);
+    g_free(tmp);
+
+    /* Client cert */
+    tmp  = g_key_file_get_string(keyfile,
+                                NM_SETTING_802_1X_SETTING_NAME,
+                                NM_SETTING_802_1X_CLIENT_CERT,
+                                NULL);
+    tmp2 = get_path(TEST_WIRED_TLS_CLIENT_CERT, relative);
+    g_assert_cmpstr(tmp, ==, tmp2);
+    g_free(tmp2);
+    g_free(tmp);
+
+    /* Private key */
+    tmp  = g_key_file_get_string(keyfile,
+                                NM_SETTING_802_1X_SETTING_NAME,
+                                NM_SETTING_802_1X_PRIVATE_KEY,
+                                NULL);
+    tmp2 = get_path(TEST_WIRED_TLS_PRIVKEY, relative);
+    g_assert_cmpstr(tmp, ==, tmp2);
+    g_free(tmp2);
+    g_free(tmp);
+
+    unlink(testfile);
+}
+
+static void
+test_write_wired_8021x_tls_connection_blob(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    gs_unref_object NMConnection *reread     = NULL;
+    NMSettingConnection *         s_con;
+    NMSetting8021x *              s_8021x;
+    gs_free char *                testfile = NULL;
+    char *                        new_ca_cert;
+    char *                        new_client_cert;
+    char *                        new_priv_key;
+    const char *                  uuid;
+    gboolean                      reread_same = FALSE;
+    GBytes *                      password_raw;
+
+#define PASSWORD_RAW "password-raw\0test"
+
+    connection = create_wired_tls_connection(NM_SETTING_802_1X_CK_SCHEME_BLOB);
+    g_assert(connection != NULL);
+
+    s_8021x = nm_connection_get_setting_802_1x(connection);
+    g_assert(s_8021x);
+
+    password_raw = g_bytes_new(PASSWORD_RAW, NM_STRLEN(PASSWORD_RAW));
+    g_object_set(s_8021x, NM_SETTING_802_1X_PASSWORD_RAW, password_raw, NULL);
+    g_bytes_unref(password_raw);
+
+    write_test_connection_reread(connection, &testfile, &reread, &reread_same);
+    nmtst_assert_connection_verifies_without_normalization(reread);
+    _setting_copy_property_gbytes(connection,
+                                  reread,
+                                  NM_SETTING_802_1X_SETTING_NAME,
+                                  NM_SETTING_802_1X_CA_CERT);
+    _setting_copy_property_gbytes(connection,
+                                  reread,
+                                  NM_SETTING_802_1X_SETTING_NAME,
+                                  NM_SETTING_802_1X_CLIENT_CERT);
+    _setting_copy_property_gbytes(connection,
+                                  reread,
+                                  NM_SETTING_802_1X_SETTING_NAME,
+                                  NM_SETTING_802_1X_PRIVATE_KEY);
+    assert_reread_same(connection, reread);
+    g_clear_object(&reread);
+
+    /* Check that the new certs got written out */
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    uuid = nm_setting_connection_get_uuid(s_con);
+    g_assert(uuid);
+
+    new_ca_cert = g_strdup_printf("%s/%s-ca-cert.pem", TEST_SCRATCH_DIR, uuid);
+    g_assert(new_ca_cert);
+    g_assert(g_file_test(new_ca_cert, G_FILE_TEST_EXISTS));
+
+    new_client_cert = g_strdup_printf("%s/%s-client-cert.pem", TEST_SCRATCH_DIR, uuid);
+    g_assert(new_client_cert);
+    g_assert(g_file_test(new_client_cert, G_FILE_TEST_EXISTS));
+
+    new_priv_key = g_strdup_printf("%s/%s-private-key.pem", TEST_SCRATCH_DIR, uuid);
+    g_assert(new_priv_key);
+    g_assert(g_file_test(new_priv_key, G_FILE_TEST_EXISTS));
+
+    /* Read the connection back in and compare it to the one we just wrote out */
+    reread = keyfile_read_connection_from_file(testfile);
+
+    /* Ensure the re-read connection's certificates use the path scheme */
+    s_8021x = nm_connection_get_setting_802_1x(reread);
+    g_assert(s_8021x);
+    g_assert(nm_setting_802_1x_get_ca_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
+    g_assert(nm_setting_802_1x_get_client_cert_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
+    g_assert(nm_setting_802_1x_get_private_key_scheme(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH);
+
+    password_raw = nm_setting_802_1x_get_password_raw(s_8021x);
+    g_assert(password_raw);
+    g_assert(nm_utils_gbytes_equal_mem(password_raw, PASSWORD_RAW, NM_STRLEN(PASSWORD_RAW)));
+
+    unlink(testfile);
+
+    /* Clean up written certs */
+    unlink(new_ca_cert);
+    g_free(new_ca_cert);
+
+    unlink(new_client_cert);
+    g_free(new_client_cert);
+
+    unlink(new_priv_key);
+    g_free(new_priv_key);
+}
+
+static void
+test_read_dcb_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_dcb_connection");
+}
+
+static void
+test_read_infiniband_connection(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingInfiniband *         s_ib;
+    const char *                  mac;
+    guint8      expected_mac[INFINIBAND_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
+                                            0x77, 0x88, 0x99, 0x01, 0x12, 0x23, 0x34,
+                                            0x45, 0x56, 0x67, 0x78, 0x89, 0x90};
+    const char *expected_id                   = "Test InfiniBand Connection";
+    const char *expected_uuid                 = "4e80a56d-c99f-4aad-a6dd-b449bc398c57";
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_InfiniBand_Connection");
+
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, expected_id);
+    g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), ==, expected_uuid);
+
+    s_ib = nm_connection_get_setting_infiniband(connection);
+    g_assert(s_ib);
+
+    mac = nm_setting_infiniband_get_mac_address(s_ib);
+    g_assert(mac);
+    g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, sizeof(expected_mac)));
+}
+
+static void
+test_write_infiniband_connection(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingInfiniband *         s_ib;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingIPConfig *           s_ip6;
+    const char *mac = "99:88:77:66:55:44:ab:bc:cd:de:ef:f0:0a:1b:2c:3d:4e:5f:6f:ba";
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = (NMSettingConnection *) nm_setting_connection_new();
+    g_assert(s_con);
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Work InfiniBand",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_AUTOCONNECT,
+                 FALSE,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_INFINIBAND_SETTING_NAME,
+                 NULL);
+
+    /* InfiniBand setting */
+    s_ib = (NMSettingInfiniband *) nm_setting_infiniband_new();
+    g_assert(s_ib);
+    nm_connection_add_setting(connection, NM_SETTING(s_ib));
+
+    g_object_set(s_ib,
+                 NM_SETTING_INFINIBAND_MAC_ADDRESS,
+                 mac,
+                 NM_SETTING_INFINIBAND_MTU,
+                 900,
+                 NM_SETTING_INFINIBAND_TRANSPORT_MODE,
+                 "datagram",
+                 NULL);
+
+    /* IP4 setting */
+    s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new();
+    g_assert(s_ip4);
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+    g_object_set(s_ip4, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_AUTO, NULL);
+
+    /* IP6 setting */
+    s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new();
+    g_assert(s_ip6);
+    nm_connection_add_setting(connection, NM_SETTING(s_ip6));
+    g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
+
+    write_test_connection_and_reread(connection, FALSE);
+}
+
+static void
+test_read_bridge_main(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingBridge *             s_bridge;
+    const char *                  expected_id   = "Test Bridge Main";
+    const char *                  expected_uuid = "8f061643-fe41-4d4c-a8d9-097d26e2ad3a";
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Bridge_Main");
+
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, expected_id);
+    g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), ==, expected_uuid);
+    g_assert_cmpstr(nm_setting_connection_get_interface_name(s_con), ==, "br0");
+
+    s_ip4 = nm_connection_get_setting_ip4_config(connection);
+    g_assert(s_ip4);
+    g_assert_cmpstr(nm_setting_ip_config_get_method(s_ip4), ==, NM_SETTING_IP4_CONFIG_METHOD_AUTO);
+
+    s_bridge = nm_connection_get_setting_bridge(connection);
+    g_assert(s_bridge);
+    g_assert_cmpuint(nm_setting_bridge_get_forward_delay(s_bridge), ==, 2);
+    g_assert_cmpuint(nm_setting_bridge_get_stp(s_bridge), ==, TRUE);
+    g_assert_cmpuint(nm_setting_bridge_get_priority(s_bridge), ==, 32744);
+    g_assert_cmpuint(nm_setting_bridge_get_hello_time(s_bridge), ==, 7);
+    g_assert_cmpuint(nm_setting_bridge_get_max_age(s_bridge), ==, 39);
+    g_assert_cmpuint(nm_setting_bridge_get_ageing_time(s_bridge), ==, 235352);
+    g_assert_cmpuint(nm_setting_bridge_get_multicast_snooping(s_bridge), ==, FALSE);
+}
+
+static void
+test_write_bridge_main(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingBridge *             s_bridge;
+    NMSettingIPConfig *           s_ip4;
+    NMSettingIPConfig *           s_ip6;
+
+    connection = nm_simple_connection_new();
+    g_assert(connection);
+
+    /* Connection setting */
+    s_con = (NMSettingConnection *) nm_setting_connection_new();
+    g_assert(s_con);
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Test Write Bridge Main",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_AUTOCONNECT,
+                 TRUE,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_BRIDGE_SETTING_NAME,
+                 NM_SETTING_CONNECTION_INTERFACE_NAME,
+                 "br0",
+                 NULL);
+
+    /* Bridge setting */
+    s_bridge = (NMSettingBridge *) nm_setting_bridge_new();
+    g_assert(s_bridge);
+    nm_connection_add_setting(connection, NM_SETTING(s_bridge));
+
+    /* IP4 setting */
+    s_ip4 = (NMSettingIPConfig *) nm_setting_ip4_config_new();
+    g_assert(s_ip4);
+    nm_connection_add_setting(connection, NM_SETTING(s_ip4));
+    g_object_set(s_ip4,
+                 NM_SETTING_IP_CONFIG_METHOD,
+                 NM_SETTING_IP4_CONFIG_METHOD_MANUAL,
+                 NM_SETTING_IP_CONFIG_MAY_FAIL,
+                 TRUE,
+                 NM_SETTING_IP_CONFIG_GATEWAY,
+                 "1.1.1.1",
+                 NULL);
+
+    add_one_ip_address(s_ip4, "1.2.3.4", 24);
+
+    /* IP6 setting */
+    s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new();
+    g_assert(s_ip6);
+    nm_connection_add_setting(connection, NM_SETTING(s_ip6));
+    g_object_set(s_ip6, NM_SETTING_IP_CONFIG_METHOD, NM_SETTING_IP6_CONFIG_METHOD_AUTO, NULL);
+
+    write_test_connection_and_reread(connection, FALSE);
+}
+
+static void
+test_read_bridge_component(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingBridgePort *         s_port;
+    NMSettingWired *              s_wired;
+    const char *                  mac;
+    guint8                        expected_mac[ETH_ALEN] = {0x00, 0x22, 0x15, 0x59, 0x62, 0x97};
+    const char *                  expected_id            = "Test Bridge Component";
+    const char *                  expected_uuid          = "d7b4f96c-c45e-4298-bef8-f48574f8c1c0";
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Bridge_Component");
+
+    s_con = nm_connection_get_setting_connection(connection);
+    g_assert(s_con);
+    g_assert_cmpstr(nm_setting_connection_get_id(s_con), ==, expected_id);
+    g_assert_cmpstr(nm_setting_connection_get_uuid(s_con), ==, expected_uuid);
+    g_assert_cmpstr(nm_setting_connection_get_master(s_con), ==, "br0");
+    g_assert(nm_setting_connection_is_slave_type(s_con, NM_SETTING_BRIDGE_SETTING_NAME));
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired);
+    mac = nm_setting_wired_get_mac_address(s_wired);
+    g_assert(mac);
+    g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, sizeof(expected_mac)));
+
+    s_port = nm_connection_get_setting_bridge_port(connection);
+    g_assert(s_port);
+    g_assert(nm_setting_bridge_port_get_hairpin_mode(s_port));
+    g_assert_cmpuint(nm_setting_bridge_port_get_priority(s_port), ==, 28);
+    g_assert_cmpuint(nm_setting_bridge_port_get_path_cost(s_port), ==, 100);
+}
+
+static void
+test_write_bridge_component(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingBridgePort *         s_port;
+    NMSettingWired *              s_wired;
+    const char *                  mac = "99:88:77:66:55:44";
+
+    connection = nm_simple_connection_new();
+    g_assert(connection);
+
+    /* Connection setting */
+    s_con = (NMSettingConnection *) nm_setting_connection_new();
+    g_assert(s_con);
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Test Write Bridge Component",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_AUTOCONNECT,
+                 TRUE,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRED_SETTING_NAME,
+                 NM_SETTING_CONNECTION_MASTER,
+                 "br0",
+                 NM_SETTING_CONNECTION_SLAVE_TYPE,
+                 NM_SETTING_BRIDGE_SETTING_NAME,
+                 NULL);
+
+    /* Wired setting */
+    s_wired = NM_SETTING_WIRED(nm_setting_wired_new());
+    g_assert(s_wired);
+    nm_connection_add_setting(connection, NM_SETTING(s_wired));
+
+    g_object_set(s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NM_SETTING_WIRED_MTU, 1300, NULL);
+
+    /* BridgePort setting */
+    s_port = (NMSettingBridgePort *) nm_setting_bridge_port_new();
+    g_assert(s_port);
+    nm_connection_add_setting(connection, NM_SETTING(s_port));
+
+    g_object_set(s_port,
+                 NM_SETTING_BRIDGE_PORT_PRIORITY,
+                 3,
+                 NM_SETTING_BRIDGE_PORT_PATH_COST,
+                 99,
+                 NULL);
+
+    write_test_connection_and_reread(connection, FALSE);
+}
+
+static void
+test_read_new_wired_group_name(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWired *              s_wired;
+    const char *                  mac;
+    guint8                        expected_mac[ETH_ALEN] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_New_Wired_Group_Name");
+
+    s_wired = nm_connection_get_setting_wired(connection);
+    g_assert(s_wired);
+    g_assert_cmpint(nm_setting_wired_get_mtu(s_wired), ==, 1400);
+
+    mac = nm_setting_wired_get_mac_address(s_wired);
+    g_assert(mac);
+    g_assert(nm_utils_hwaddr_matches(mac, -1, expected_mac, sizeof(expected_mac)));
+}
+
+static void
+test_write_new_wired_group_name(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    nm_auto_unref_keyfile GKeyFile *kf       = NULL;
+    NMSettingConnection *           s_con;
+    NMSettingWired *                s_wired;
+    gs_free char *                  testfile = NULL;
+    gs_free_error GError *error              = NULL;
+    char *                s;
+    int                   mtu;
+
+    connection = nm_simple_connection_new();
+    g_assert(connection);
+
+    /* Connection setting */
+    s_con = (NMSettingConnection *) nm_setting_connection_new();
+    g_assert(s_con);
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Test Write Wired New Group Name",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRED_SETTING_NAME,
+                 NULL);
+
+    /* Wired setting */
+    s_wired = (NMSettingWired *) nm_setting_wired_new();
+    g_assert(s_wired);
+    g_object_set(s_wired, NM_SETTING_WIRED_MTU, 1400, NULL);
+    nm_connection_add_setting(connection, NM_SETTING(s_wired));
+
+    write_test_connection(connection, &testfile);
+
+    assert_reread(connection, TRUE, testfile);
+
+    /* Look at the keyfile itself to ensure we wrote out the new group names and type */
+    kf = keyfile_load_from_file(testfile);
+
+    s = g_key_file_get_string(kf,
+                              NM_SETTING_CONNECTION_SETTING_NAME,
+                              NM_SETTING_CONNECTION_TYPE,
+                              &error);
+    g_assert_no_error(error);
+    g_assert_cmpstr(s, ==, "ethernet");
+    g_free(s);
+
+    mtu = g_key_file_get_integer(kf, "ethernet", NM_SETTING_WIRED_MTU, &error);
+    g_assert_no_error(error);
+    g_assert_cmpint(mtu, ==, 1400);
+
+    unlink(testfile);
+}
+
+static void
+test_read_new_wireless_group_names(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingWireless *           s_wifi;
+    NMSettingWirelessSecurity *   s_wsec;
+    GBytes *                      ssid;
+    const char *                  expected_ssid = "foobar";
+
+    connection =
+        keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_New_Wireless_Group_Names");
+
+    s_wifi = nm_connection_get_setting_wireless(connection);
+    g_assert(s_wifi);
+
+    ssid = nm_setting_wireless_get_ssid(s_wifi);
+    g_assert(ssid);
+    g_assert(nm_utils_gbytes_equal_mem(ssid, expected_ssid, strlen(expected_ssid)));
+
+    g_assert_cmpstr(nm_setting_wireless_get_mode(s_wifi), ==, NM_SETTING_WIRELESS_MODE_INFRA);
+
+    s_wsec = nm_connection_get_setting_wireless_security(connection);
+    g_assert(s_wsec);
+    g_assert_cmpstr(nm_setting_wireless_security_get_key_mgmt(s_wsec), ==, "wpa-psk");
+    g_assert_cmpstr(nm_setting_wireless_security_get_psk(s_wsec), ==, "s3cu4e passphrase");
+}
+
+static void
+test_write_new_wireless_group_names(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    nm_auto_unref_keyfile GKeyFile *kf       = NULL;
+    NMSettingConnection *           s_con;
+    NMSettingWireless *             s_wifi;
+    NMSettingWirelessSecurity *     s_wsec;
+    GBytes *                        ssid;
+    unsigned char                   tmpssid[]    = {0x31, 0x33, 0x33, 0x37};
+    const char *                    expected_psk = "asdfasdfasdfa12315";
+    gs_free char *                  testfile     = NULL;
+    gs_free_error GError *error                  = NULL;
+    char *                s;
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = (NMSettingConnection *) nm_setting_connection_new();
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Test Write New Wireless Group Names",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRELESS_SETTING_NAME,
+                 NULL);
+
+    /* Wi-Fi setting */
+    s_wifi = (NMSettingWireless *) nm_setting_wireless_new();
+    nm_connection_add_setting(connection, NM_SETTING(s_wifi));
+
+    ssid = g_bytes_new(tmpssid, sizeof(tmpssid));
+    g_object_set(s_wifi,
+                 NM_SETTING_WIRELESS_SSID,
+                 ssid,
+                 NM_SETTING_WIRELESS_MODE,
+                 NM_SETTING_WIRELESS_MODE_INFRA,
+                 NULL);
+    g_bytes_unref(ssid);
+
+    /* Wi-Fi security setting */
+    s_wsec = (NMSettingWirelessSecurity *) nm_setting_wireless_security_new();
+    nm_connection_add_setting(connection, NM_SETTING(s_wsec));
+    g_object_set(s_wsec,
+                 NM_SETTING_WIRELESS_SECURITY_KEY_MGMT,
+                 "wpa-psk",
+                 NM_SETTING_WIRELESS_SECURITY_PSK,
+                 expected_psk,
+                 NULL);
+
+    write_test_connection(connection, &testfile);
+
+    assert_reread(connection, TRUE, testfile);
+
+    /* Look at the keyfile itself to ensure we wrote out the new group names and type */
+    kf = keyfile_load_from_file(testfile);
+
+    s = g_key_file_get_string(kf,
+                              NM_SETTING_CONNECTION_SETTING_NAME,
+                              NM_SETTING_CONNECTION_TYPE,
+                              &error);
+    g_assert_no_error(error);
+    g_assert_cmpstr(s, ==, "wifi");
+    g_free(s);
+
+    s = g_key_file_get_string(kf, "wifi", NM_SETTING_WIRELESS_MODE, &error);
+    g_assert_no_error(error);
+    g_assert_cmpstr(s, ==, NM_SETTING_WIRELESS_MODE_INFRA);
+    g_free(s);
+
+    s = g_key_file_get_string(kf, "wifi-security", NM_SETTING_WIRELESS_SECURITY_PSK, &error);
+    g_assert_no_error(error);
+    g_assert_cmpstr(s, ==, expected_psk);
+    g_free(s);
+
+    unlink(testfile);
+}
+
+static void
+test_read_missing_vlan_setting(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingVlan *               s_vlan;
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Missing_Vlan_Setting");
+
+    s_vlan = nm_connection_get_setting_vlan(connection);
+    g_assert(s_vlan);
+    g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 0);
+    g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS);
+}
+
+static void
+test_read_missing_vlan_flags(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingVlan *               s_vlan;
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Missing_Vlan_Flags");
+
+    s_vlan = nm_connection_get_setting_vlan(connection);
+    g_assert(s_vlan);
+
+    g_assert_cmpint(nm_setting_vlan_get_id(s_vlan), ==, 444);
+    g_assert_cmpstr(nm_setting_vlan_get_parent(s_vlan), ==, "em1");
+    g_assert_cmpint(nm_setting_vlan_get_flags(s_vlan), ==, NM_VLAN_FLAG_REORDER_HEADERS);
+}
+
+static void
+test_read_missing_id_uuid(void)
+{
+    gs_unref_object NMConnection *connection    = NULL;
+    gs_free char *                expected_uuid = NULL;
+    const char *                  FILENAME      = TEST_KEYFILES_DIR "/Test_Missing_ID_UUID";
+
+    expected_uuid = _nm_utils_uuid_generate_from_strings("keyfile", FILENAME, NULL);
+
+    connection = keyfile_read_connection_from_file(FILENAME);
+
+    g_assert_cmpstr(nm_connection_get_id(connection), ==, "Test_Missing_ID_UUID");
+    g_assert_cmpstr(nm_connection_get_uuid(connection), ==, expected_uuid);
+}
+
+static void
+test_read_minimal(void)
+{
+    gs_unref_object NMConnection *connection    = NULL;
+    gs_unref_object NMConnection *con_archetype = NULL;
+    NMSettingConnection *         s_con;
+
+    con_archetype = nmtst_create_minimal_connection("Test_minimal_x",
+                                                    "a15bd68f-c32b-40b8-8d27-49e472a85919",
+                                                    NM_SETTING_WIRED_SETTING_NAME,
+                                                    &s_con);
+    nmtst_connection_normalize(con_archetype);
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_1");
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 nm_connection_get_id(connection),
+                 NM_SETTING_CONNECTION_UUID,
+                 nm_connection_get_uuid(connection),
+                 NULL);
+    nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE);
+    g_clear_object(&connection);
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_2");
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 nm_connection_get_id(connection),
+                 NM_SETTING_CONNECTION_UUID,
+                 nm_connection_get_uuid(connection),
+                 NULL);
+    nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE);
+    g_clear_object(&connection);
+}
+
+static void
+test_read_minimal_slave(void)
+{
+    gs_unref_object NMConnection *connection    = NULL;
+    gs_unref_object NMConnection *con_archetype = NULL;
+    NMSettingConnection *         s_con;
+
+    con_archetype = nmtst_create_minimal_connection("Test_minimal_slave_x",
+                                                    "a56b4ca5-7075-43d4-82c7-5d0cb15f7654",
+                                                    NM_SETTING_WIRED_SETTING_NAME,
+                                                    &s_con);
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_MASTER,
+                 "br0",
+                 NM_SETTING_CONNECTION_SLAVE_TYPE,
+                 "bridge",
+                 NULL);
+    nmtst_connection_normalize(con_archetype);
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_slave_1");
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 nm_connection_get_id(connection),
+                 NM_SETTING_CONNECTION_UUID,
+                 nm_connection_get_uuid(connection),
+                 NULL);
+    nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE);
+    g_clear_object(&connection);
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_slave_2");
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 nm_connection_get_id(connection),
+                 NM_SETTING_CONNECTION_UUID,
+                 nm_connection_get_uuid(connection),
+                 NULL);
+    nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE);
+    g_clear_object(&connection);
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_slave_3");
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 nm_connection_get_id(connection),
+                 NM_SETTING_CONNECTION_UUID,
+                 nm_connection_get_uuid(connection),
+                 NULL);
+    nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE);
+    g_clear_object(&connection);
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_minimal_slave_4");
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 nm_connection_get_id(connection),
+                 NM_SETTING_CONNECTION_UUID,
+                 nm_connection_get_uuid(connection),
+                 NULL);
+    nmtst_assert_connection_equals(con_archetype, FALSE, connection, FALSE);
+    g_clear_object(&connection);
+}
+
+static void
+test_read_enum_property(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingIPConfig *           s_ip6;
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Enum_Property");
+
+    s_ip6 = nm_connection_get_setting_ip6_config(connection);
+    g_assert(s_ip6);
+    g_assert_cmpint(nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip6)),
+                    ==,
+                    NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR);
+}
+
+static void
+test_write_enum_property(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSettingWired *              s_wired;
+    NMSettingIPConfig *           s_ip6;
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Test Write Enum Property",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_WIRED_SETTING_NAME,
+                 NULL);
+
+    /* Wired setting */
+    s_wired = NM_SETTING_WIRED(nm_setting_wired_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_wired));
+
+    /* IP6 setting */
+    s_ip6 = NM_SETTING_IP_CONFIG(nm_setting_ip6_config_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_ip6));
+    g_object_set(s_ip6,
+                 NM_SETTING_IP_CONFIG_METHOD,
+                 NM_SETTING_IP6_CONFIG_METHOD_AUTO,
+                 NM_SETTING_IP6_CONFIG_IP6_PRIVACY,
+                 NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR,
+                 NULL);
+
+    nmtst_connection_normalize(connection);
+
+    write_test_connection_and_reread(connection, FALSE);
+}
+
+static void
+test_read_flags_property(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingGsm *                s_gsm;
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_Flags_Property");
+
+    s_gsm = nm_connection_get_setting_gsm(connection);
+    g_assert(s_gsm);
+    g_assert_cmpint(nm_setting_gsm_get_password_flags(s_gsm),
+                    ==,
+                    NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED);
+}
+
+static void
+test_write_flags_property(void)
+{
+    NMTST_UUID_INIT(uuid);
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingConnection *         s_con;
+    NMSetting *                   s_gsm;
+
+    connection = nm_simple_connection_new();
+
+    /* Connection setting */
+
+    s_con = NM_SETTING_CONNECTION(nm_setting_connection_new());
+    nm_connection_add_setting(connection, NM_SETTING(s_con));
+
+    g_object_set(s_con,
+                 NM_SETTING_CONNECTION_ID,
+                 "Test Write Flags Property",
+                 NM_SETTING_CONNECTION_UUID,
+                 uuid,
+                 NM_SETTING_CONNECTION_TYPE,
+                 NM_SETTING_GSM_SETTING_NAME,
+                 NULL);
+
+    /* GSM setting */
+    s_gsm = nm_setting_gsm_new();
+    nm_connection_add_setting(connection, s_gsm);
+    g_object_set(s_gsm,
+                 NM_SETTING_GSM_APN,
+                 "myapn",
+                 NM_SETTING_GSM_USERNAME,
+                 "adfasdfasdf",
+                 NM_SETTING_GSM_PASSWORD_FLAGS,
+                 NM_SETTING_SECRET_FLAG_NOT_SAVED | NM_SETTING_SECRET_FLAG_NOT_REQUIRED,
+                 NULL);
+
+    nmtst_connection_normalize(connection);
+
+    write_test_connection_and_reread(connection, FALSE);
+}
+
+/*****************************************************************************/
+
+static void
+test_read_tc_config(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSettingTCConfig *           s_tc;
+    NMTCQdisc *                   qdisc1, *qdisc2;
+    NMTCAction *                  action1, *action2;
+    NMTCTfilter *                 tfilter1, *tfilter2;
+
+    connection = keyfile_read_connection_from_file(TEST_KEYFILES_DIR "/Test_TC_Config");
+
+    s_tc = nm_connection_get_setting_tc_config(connection);
+    g_assert(s_tc);
+
+    g_assert(nm_setting_tc_config_get_num_qdiscs(s_tc) == 2);
+
+    qdisc1 = nm_setting_tc_config_get_qdisc(s_tc, 0);
+    g_assert(qdisc1);
+    g_assert(g_strcmp0(nm_tc_qdisc_get_kind(qdisc1), "fq_codel") == 0);
+    g_assert(nm_tc_qdisc_get_handle(qdisc1) == TC_H_MAKE(0x1234 << 16, 0x0000));
+    g_assert(nm_tc_qdisc_get_parent(qdisc1) == TC_H_ROOT);
+
+    qdisc2 = nm_setting_tc_config_get_qdisc(s_tc, 1);
+    g_assert(qdisc2);
+    g_assert(g_strcmp0(nm_tc_qdisc_get_kind(qdisc2), "ingress") == 0);
+    g_assert(nm_tc_qdisc_get_handle(qdisc2) == TC_H_MAKE(TC_H_INGRESS, 0));
+    g_assert(nm_tc_qdisc_get_parent(qdisc2) == TC_H_INGRESS);
+
+    g_assert(nm_setting_tc_config_get_num_tfilters(s_tc) == 2);
+
+    tfilter1 = nm_setting_tc_config_get_tfilter(s_tc, 0);
+    g_assert(tfilter1);
+    g_assert(g_strcmp0(nm_tc_tfilter_get_kind(tfilter1), "matchall") == 0);
+    g_assert(nm_tc_tfilter_get_handle(tfilter1) == TC_H_UNSPEC);
+    g_assert(nm_tc_tfilter_get_parent(tfilter1) == TC_H_MAKE(0x1234 << 16, 0x0000));
+
+    action1 = nm_tc_tfilter_get_action(tfilter1);
+    g_assert(action1);
+    g_assert(g_strcmp0(nm_tc_action_get_kind(action1), "drop") == 0);
+
+    tfilter2 = nm_setting_tc_config_get_tfilter(s_tc, 1);
+    g_assert(tfilter2);
+    g_assert(g_strcmp0(nm_tc_tfilter_get_kind(tfilter2), "matchall") == 0);
+    g_assert(nm_tc_tfilter_get_handle(tfilter2) == TC_H_UNSPEC);
+    g_assert(nm_tc_tfilter_get_parent(tfilter2) == TC_H_MAKE(TC_H_INGRESS, 0));
+
+    action2 = nm_tc_tfilter_get_action(tfilter2);
+    g_assert(action2);
+    g_assert(g_strcmp0(nm_tc_action_get_kind(action2), "simple") == 0);
+    g_assert(
+        g_strcmp0(g_variant_get_bytestring(nm_tc_action_get_attribute(action2, "sdata")), "Hello")
+        == 0);
+}
+
+static void
+test_write_tc_config(void)
+{
+    gs_unref_object NMConnection *connection = NULL;
+    NMSetting *                   s_tc;
+    NMTCQdisc *                   qdisc1, *qdisc2;
+    NMTCTfilter *                 tfilter1, *tfilter2;
+    NMTCAction *                  action;
+    GError *                      error = NULL;
+
+    connection =
+        nmtst_create_minimal_connection("Test TC", NULL, NM_SETTING_WIRED_SETTING_NAME, NULL);
+    s_tc = nm_setting_tc_config_new();
+
+    qdisc1 = nm_tc_qdisc_new("fq_codel", TC_H_ROOT, &error);
+    nmtst_assert_success(qdisc1, error);
+    nm_tc_qdisc_set_handle(qdisc1, TC_H_MAKE(0x1234 << 16, 0x0000));
+    nm_setting_tc_config_add_qdisc(NM_SETTING_TC_CONFIG(s_tc), qdisc1);
+
+    qdisc2 = nm_tc_qdisc_new("ingress", TC_H_INGRESS, &error);
+    nmtst_assert_success(qdisc2, error);
+    nm_tc_qdisc_set_handle(qdisc2, TC_H_MAKE(TC_H_INGRESS, 0));
+    nm_setting_tc_config_add_qdisc(NM_SETTING_TC_CONFIG(s_tc), qdisc2);
+
+    tfilter1 = nm_tc_tfilter_new("matchall", TC_H_MAKE(0x1234 << 16, 0x0000), &error);
+    nmtst_assert_success(tfilter1, error);
+    action = nm_tc_action_new("drop", &error);
+    nmtst_assert_success(action, error);
+    nm_tc_tfilter_set_action(tfilter1, action);
+    nm_tc_action_unref(action);
+    nm_setting_tc_config_add_tfilter(NM_SETTING_TC_CONFIG(s_tc), tfilter1);
+    nm_tc_tfilter_unref(tfilter1);
+
+    tfilter2 = nm_tc_tfilter_new("matchall", TC_H_MAKE(TC_H_INGRESS, 0), &error);
+    nmtst_assert_success(tfilter2, error);
+    action = nm_tc_action_new("simple", &error);
+    nmtst_assert_success(action, error);
+    nm_tc_action_set_attribute(action, "sdata", g_variant_new_bytestring("Hello"));
+    nm_tc_tfilter_set_action(tfilter2, action);
+    nm_tc_action_unref(action);
+    nm_setting_tc_config_add_tfilter(NM_SETTING_TC_CONFIG(s_tc), tfilter2);
+    nm_tc_tfilter_unref(tfilter2);
+
+    nm_connection_add_setting(connection, s_tc);
+
+    nmtst_connection_normalize(connection);
+    write_test_connection_and_reread(connection, FALSE);
+
+    nm_tc_qdisc_unref(qdisc1);
+    nm_tc_qdisc_unref(qdisc2);
+}
+
+/*****************************************************************************/
+
+static void
+_escape_filename(gboolean with_extension, const char *filename, gboolean would_be_ignored)
+{
+    gs_free char *esc = NULL;
+
+    g_assert(filename && filename[0]);
+
+    if (!!would_be_ignored != !!nm_keyfile_utils_ignore_filename(filename, with_extension)) {
+        if (would_be_ignored)
+            g_error("We expect filename \"%s\" to be ignored, but it isn't", filename);
+        else
+            g_error("We expect filename \"%s\" not to be ignored, but it is", filename);
+    }
+
+    esc = nm_keyfile_utils_create_filename(filename, with_extension);
+    g_assert(esc && esc[0]);
+    g_assert(!strchr(esc, '/'));
+
+    if (nm_keyfile_utils_ignore_filename(esc, with_extension))
+        g_error("Escaping filename \"%s\" yielded \"%s\", but this is ignored", filename, esc);
+}
+
+static void
+test_nm_keyfile_plugin_utils_escape_filename(void)
+{
+    _escape_filename(FALSE, "ab", FALSE);
+    _escape_filename(FALSE, ".vim-file.swp", TRUE);
+    _escape_filename(FALSE, ".vim-file.Swp", TRUE);
+    _escape_filename(FALSE, ".vim-file.SWP", TRUE);
+    _escape_filename(FALSE, ".vim-file.swpx", TRUE);
+    _escape_filename(FALSE, ".vim-file.Swpx", TRUE);
+    _escape_filename(FALSE, ".vim-file.SWPX", TRUE);
+    _escape_filename(FALSE, ".pem-file.pem", TRUE);
+    _escape_filename(FALSE, ".pem-file.Pem", TRUE);
+    _escape_filename(FALSE, ".pem-file.PEM", TRUE);
+    _escape_filename(FALSE, ".pem-file.der", TRUE);
+    _escape_filename(FALSE, ".pem-file.Der", TRUE);
+    _escape_filename(FALSE, ".mkstemp.ABCEDF", TRUE);
+    _escape_filename(FALSE, ".mkstemp.abcdef", TRUE);
+    _escape_filename(FALSE, ".mkstemp.123456", TRUE);
+    _escape_filename(FALSE, ".mkstemp.A23456", TRUE);
+    _escape_filename(FALSE, ".#emacs-locking", TRUE);
+    _escape_filename(FALSE, "file-with-tilde~", TRUE);
+    _escape_filename(FALSE, ".file-with-dot", TRUE);
+    _escape_filename(FALSE, "/some/path/with/trailing/slash/", TRUE);
+    _escape_filename(FALSE, "/some/path/without/trailing/slash", FALSE);
+
+    _escape_filename(TRUE, "lala", TRUE);
+}
+
+/*****************************************************************************/
+
+static void
+_assert_keyfile_nmmeta(const char *dirname,
+                       const char *uuid,
+                       const char *loaded_path,
+                       gboolean    allow_relative,
+                       const char *exp_full_filename,
+                       const char *exp_uuid,
+                       const char *exp_symlink_target,
+                       const char *exp_loaded_path)
+{
+    gs_free char *full_filename  = NULL;
+    gs_free char *symlink_target = NULL;
+    gs_free char *uuid2          = NULL;
+    gs_free char *loaded_path2   = NULL;
+    gs_free char *dirname3       = NULL;
+    gs_free char *filename3      = NULL;
+    gs_free char *uuid3          = NULL;
+    gs_free char *loaded_path3   = NULL;
+    gboolean      success;
+    gs_free char *filename = NULL;
+
+    g_assert(dirname && dirname[0] == '/');
+    g_assert(exp_full_filename && exp_full_filename[0]);
+    g_assert(!exp_loaded_path || exp_loaded_path[0] == '/');
+
+    filename = g_path_get_basename(exp_full_filename);
+
+    full_filename = nms_keyfile_nmmeta_filename(dirname, uuid, FALSE);
+    g_assert_cmpstr(full_filename, ==, full_filename);
+    nm_clear_g_free(&full_filename);
+
+    g_assert_cmpint(
+        nms_keyfile_nmmeta_write(dirname, uuid, loaded_path, allow_relative, NULL, &full_filename),
+        ==,
+        0);
+    g_assert_cmpstr(full_filename, ==, exp_full_filename);
+    nm_clear_g_free(&full_filename);
+
+    if (exp_symlink_target)
+        g_assert(g_file_test(exp_full_filename, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_SYMLINK));
+    else
+        g_assert(!g_file_test(exp_full_filename, G_FILE_TEST_EXISTS));
+    symlink_target = g_file_read_link(exp_full_filename, NULL);
+    g_assert_cmpstr(symlink_target, ==, exp_symlink_target);
+
+    success = nms_keyfile_nmmeta_read(dirname,
+                                      filename,
+                                      &full_filename,
+                                      &uuid2,
+                                      &loaded_path2,
+                                      NULL,
+                                      NULL);
+    g_assert_cmpint(!!exp_uuid, ==, success);
+    if (success)
+        g_assert_cmpstr(full_filename, ==, exp_full_filename);
+    else
+        g_assert_cmpstr(full_filename, ==, NULL);
+    nm_clear_g_free(&full_filename);
+    g_assert_cmpstr(uuid2, ==, exp_uuid);
+    g_assert_cmpstr(loaded_path2, ==, exp_loaded_path);
+
+    success = nms_keyfile_nmmeta_read_from_file(exp_full_filename,
+                                                &dirname3,
+                                                &filename3,
+                                                &uuid3,
+                                                &loaded_path3,
+                                                NULL);
+    g_assert_cmpint(!!exp_uuid, ==, success);
+    if (success) {
+        g_assert_cmpstr(dirname3, ==, dirname);
+        g_assert_cmpstr(filename3, ==, filename);
+    } else {
+        g_assert_cmpstr(dirname3, ==, NULL);
+        g_assert_cmpstr(filename3, ==, NULL);
+    }
+    g_assert_cmpstr(uuid3, ==, exp_uuid);
+    g_assert_cmpstr(loaded_path3, ==, exp_loaded_path);
+}
+
+static void
+test_nmmeta(void)
+{
+    const char *  uuid          = "3c03fd17-ddc3-4100-a954-88b6fafff959";
+    gs_free char *filename      = g_strdup_printf("%s%s", uuid, NM_KEYFILE_PATH_SUFFIX_NMMETA);
+    gs_free char *full_filename = g_strdup_printf("%s/%s", TEST_SCRATCH_DIR, filename);
+    const char *  loaded_path0  = NM_KEYFILE_PATH_NMMETA_SYMLINK_NULL;
+    const char *  loaded_path1  = "/some/where/but/not/scratch/dir";
+    const char *  filename2     = "foo1";
+    gs_free char *loaded_path2  = g_strdup_printf("%s/%s", TEST_SCRATCH_DIR, filename2);
+
+    _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, uuid, NULL, FALSE, full_filename, NULL, NULL, NULL);
+    _assert_keyfile_nmmeta(TEST_SCRATCH_DIR, uuid, NULL, TRUE, full_filename, NULL, NULL, NULL);
+
+    _assert_keyfile_nmmeta(TEST_SCRATCH_DIR,
+                           uuid,
+                           loaded_path0,
+                           FALSE,
+                           full_filename,
+                           uuid,
+                           loaded_path0,
+                           loaded_path0);
+    _assert_keyfile_nmmeta(TEST_SCRATCH_DIR,
+                           uuid,
+                           loaded_path0,
+                           TRUE,
+                           full_filename,
+                           uuid,
+                           loaded_path0,
+                           loaded_path0);
+
+    _assert_keyfile_nmmeta(TEST_SCRATCH_DIR,
+                           uuid,
+                           loaded_path1,
+                           FALSE,
+                           full_filename,
+                           uuid,
+                           loaded_path1,
+                           loaded_path1);
+    _assert_keyfile_nmmeta(TEST_SCRATCH_DIR,
+                           uuid,
+                           loaded_path1,
+                           TRUE,
+                           full_filename,
+                           uuid,
+                           loaded_path1,
+                           loaded_path1);
+
+    _assert_keyfile_nmmeta(TEST_SCRATCH_DIR,
+                           uuid,
+                           loaded_path2,
+                           FALSE,
+                           full_filename,
+                           uuid,
+                           loaded_path2,
+                           loaded_path2);
+    _assert_keyfile_nmmeta(TEST_SCRATCH_DIR,
+                           uuid,
+                           loaded_path2,
+                           TRUE,
+                           full_filename,
+                           uuid,
+                           filename2,
+                           loaded_path2);
+
+    (void) unlink(full_filename);
+}
+
+/*****************************************************************************/
+
+NMTST_DEFINE();
+
+int
+main(int argc, char **argv)
+{
+    int errsv;
+
+    _nm_utils_set_testing(NM_UTILS_TEST_NO_KEYFILE_OWNER_CHECK);
+
+    nmtst_init_assert_logging(&argc, &argv, "INFO", "DEFAULT");
+
+    if (g_mkdir_with_parents(TEST_SCRATCH_DIR, 0755) != 0) {
+        errsv = errno;
+        g_error("failure to create test directory \"%s\": %s",
+                TEST_SCRATCH_DIR,
+                nm_strerror_native(errsv));
+    }
+
+    /* The tests */
+    g_test_add_func("/keyfile/test_read_valid_wired_connection", test_read_valid_wired_connection);
+    g_test_add_func("/keyfile/test_write_wired_connection", test_write_wired_connection);
+
+    g_test_add_func("/keyfile/test_read_ip6_wired_connection", test_read_ip6_wired_connection);
+    g_test_add_func("/keyfile/test_write_ip6_wired_connection", test_write_ip6_wired_connection);
+
+    g_test_add_func("/keyfile/test_read_wired_mac_case", test_read_wired_mac_case);
+    g_test_add_func("/keyfile/test_read_mac_old_format", test_read_mac_old_format);
+    g_test_add_func("/keyfile/test_read_mac_ib_old_format", test_read_mac_ib_old_format);
+
+    g_test_add_func("/keyfile/test_read_valid_wireless_connection",
+                    test_read_valid_wireless_connection);
+    g_test_add_func("/keyfile/test_write_wireless_connection", test_write_wireless_connection);
+
+    g_test_add_func("/keyfile/test_read_string_ssid", test_read_string_ssid);
+    g_test_add_func("/keyfile/test_write_string_ssid", test_write_string_ssid);
+
+    g_test_add_func("/keyfile/test_read_intlist_ssid", test_read_intlist_ssid);
+    g_test_add_func("/keyfile/test_write_intlist_ssid", test_write_intlist_ssid);
+
+    g_test_add_func("/keyfile/test_read_intlike_ssid", test_read_intlike_ssid);
+    g_test_add_func("/keyfile/test_write_intlike_ssid", test_write_intlike_ssid);
+
+    g_test_add_func("/keyfile/test_read_intlike_ssid_2", test_read_intlike_ssid_2);
+    g_test_add_func("/keyfile/test_write_intlike_ssid_2", test_write_intlike_ssid_2);
+
+    g_test_add_func("/keyfile/test_read_bt_dun_connection", test_read_bt_dun_connection);
+    g_test_add_func("/keyfile/test_write_bt_dun_connection", test_write_bt_dun_connection);
+
+    g_test_add_func("/keyfile/test_read_gsm_connection", test_read_gsm_connection);
+    g_test_add_func("/keyfile/test_write_gsm_connection", test_write_gsm_connection);
+
+    g_test_add_func("/keyfile/test_read_wired_8021x_tls_blob_connection",
+                    test_read_wired_8021x_tls_blob_connection);
+    g_test_add_func("/keyfile/test_read_wired_8021x_tls_bad_path_connection",
+                    test_read_wired_8021x_tls_bad_path_connection);
+
+    g_test_add_func("/keyfile/test_read_wired_8021x_tls_old_connection",
+                    test_read_wired_8021x_tls_old_connection);
+    g_test_add_func("/keyfile/test_read_wired_8021x_tls_new_connection",
+                    test_read_wired_8021x_tls_new_connection);
+    g_test_add_func("/keyfile/test_write_wired_8021x_tls_connection_path",
+                    test_write_wired_8021x_tls_connection_path);
+    g_test_add_func("/keyfile/test_write_wired_8021x_tls_connection_blob",
+                    test_write_wired_8021x_tls_connection_blob);
+
+    g_test_add_func("/keyfile/test_read_dcb_connection", test_read_dcb_connection);
+
+    g_test_add_func("/keyfile/test_read_infiniband_connection", test_read_infiniband_connection);
+    g_test_add_func("/keyfile/test_write_infiniband_connection", test_write_infiniband_connection);
+
+    g_test_add_func("/keyfile/test_read_bridge_main", test_read_bridge_main);
+    g_test_add_func("/keyfile/test_write_bridge_main", test_write_bridge_main);
+    g_test_add_func("/keyfile/test_read_bridge_component", test_read_bridge_component);
+    g_test_add_func("/keyfile/test_write_bridge_component", test_write_bridge_component);
+
+    g_test_add_func("/keyfile/test_read_new_wired_group_name", test_read_new_wired_group_name);
+    g_test_add_func("/keyfile/test_write_new_wired_group_name", test_write_new_wired_group_name);
+    g_test_add_func("/keyfile/test_read_new_wireless_group_names",
+                    test_read_new_wireless_group_names);
+    g_test_add_func("/keyfile/test_write_new_wireless_group_names",
+                    test_write_new_wireless_group_names);
+
+    g_test_add_func("/keyfile/test_read_missing_vlan_setting", test_read_missing_vlan_setting);
+    g_test_add_func("/keyfile/test_read_missing_vlan_flags", test_read_missing_vlan_flags);
+    g_test_add_func("/keyfile/test_read_missing_id_uuid", test_read_missing_id_uuid);
+
+    g_test_add_func("/keyfile/test_read_minimal", test_read_minimal);
+    g_test_add_func("/keyfile/test_read_minimal_slave", test_read_minimal_slave);
+
+    g_test_add_func("/keyfile/test_read_enum_property", test_read_enum_property);
+    g_test_add_func("/keyfile/test_write_enum_property", test_write_enum_property);
+    g_test_add_func("/keyfile/test_read_flags_property", test_read_flags_property);
+    g_test_add_func("/keyfile/test_write_flags_property", test_write_flags_property);
+
+    g_test_add_func("/keyfile/test_read_tc_config", test_read_tc_config);
+    g_test_add_func("/keyfile/test_write_tc_config", test_write_tc_config);
+
+    g_test_add_func("/keyfile/test_nm_keyfile_plugin_utils_escape_filename",
+                    test_nm_keyfile_plugin_utils_escape_filename);
+
+    g_test_add_func("/keyfile/test_nmmeta", test_nmmeta);
+
+    return g_test_run();
+}