From 6471504555ba87e6e93cc015ba4bb4e4893fd20f Mon Sep 17 00:00:00 2001 From: Ainar Garipov Date: Tue, 9 Feb 2021 16:51:44 +0300 Subject: [PATCH] Pull request: home: imp upgrade test Merge in DNS/adguard-home from imp-upgrade-test to master Updates #2639. Updates #2646. Squashed commit of the following: commit f7bd8e020fa8fc285cdd6ecdf36711574f2e6e38 Author: Ainar Garipov Date: Tue Feb 9 16:38:40 2021 +0300 home: imp test more commit 5b64131e04d568871cf401fa3fc2c7980d69bee0 Author: Ainar Garipov Date: Tue Feb 9 16:09:22 2021 +0300 home: imp upgrade test --- internal/home/upgrade_test.go | 268 +++++++++++++--------------------- 1 file changed, 102 insertions(+), 166 deletions(-) diff --git a/internal/home/upgrade_test.go b/internal/home/upgrade_test.go index f884de0463d..4210305a8df 100644 --- a/internal/home/upgrade_test.go +++ b/internal/home/upgrade_test.go @@ -3,183 +3,108 @@ package home import ( "fmt" "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) -func TestUpgrade1to2(t *testing.T) { - // let's create test config for 1 schema version - diskConfig := createTestDiskConfig(1) +// any is a convenient alias for interface{}. +type any = interface{} - // update config - err := upgradeSchema1to2(&diskConfig) - if err != nil { - t.Fatalf("Can't upgrade schema version from 1 to 2") - } +// object is a convenient alias for map[string]interface{}. +type object = map[string]any - // ensure that schema version was bumped - compareSchemaVersion(t, diskConfig["schema_version"], 2) +func TestUpgradeSchema1to2(t *testing.T) { + diskConf := testDiskConf(1) - // old coredns entry should be removed - _, ok := diskConfig["coredns"] - if ok { - t.Fatalf("Core DNS config was not removed after upgrade schema version from 1 to 2") - } + err := upgradeSchema1to2(&diskConf) + require.Nil(t, err) - // pull out new dns config - dnsMap, ok := diskConfig["dns"] - if !ok { - t.Fatalf("No DNS config after upgrade schema version from 1 to 2") - } + require.Equal(t, diskConf["schema_version"], 2) - // cast dns configurations to maps and compare them - oldDNSConfig := castInterfaceToMap(t, createTestDNSConfig(1)) - newDNSConfig := castInterfaceToMap(t, dnsMap) - compareConfigs(t, &oldDNSConfig, &newDNSConfig) + _, ok := diskConf["coredns"] + require.False(t, ok) + + dnsMap, ok := diskConf["dns"] + require.True(t, ok) + + oldDNSConf := convertToObject(t, testDNSConf(1)) + newDNSConf := convertToObject(t, dnsMap) + assert.Equal(t, oldDNSConf, newDNSConf) - // exclude dns config and schema version from disk config comparison oldExcludedEntries := []string{"coredns", "schema_version"} newExcludedEntries := []string{"dns", "schema_version"} - oldDiskConfig := createTestDiskConfig(1) - compareConfigsWithoutEntries(t, &oldDiskConfig, &diskConfig, oldExcludedEntries, newExcludedEntries) + oldDiskConf := testDiskConf(1) + assertEqualExcept(t, oldDiskConf, diskConf, oldExcludedEntries, newExcludedEntries) } -func TestUpgrade2to3(t *testing.T) { - // let's create test config - diskConfig := createTestDiskConfig(2) +func TestUpgradeSchema2to3(t *testing.T) { + diskConf := testDiskConf(2) - // upgrade schema from 2 to 3 - err := upgradeSchema2to3(&diskConfig) - if err != nil { - t.Fatalf("Can't update schema version from 2 to 3: %s", err) - } + err := upgradeSchema2to3(&diskConf) + require.Nil(t, err) - // check new schema version - compareSchemaVersion(t, diskConfig["schema_version"], 3) + require.Equal(t, diskConf["schema_version"], 3) - // pull out new dns configuration - dnsMap, ok := diskConfig["dns"] - if !ok { - t.Fatalf("No dns config in new configuration") - } + dnsMap, ok := diskConf["dns"] + require.True(t, ok) - // cast dns configuration to map - newDNSConfig := castInterfaceToMap(t, dnsMap) - - // check if bootstrap DNS becomes an array - bootstrapDNS := newDNSConfig["bootstrap_dns"] + newDNSConf := convertToObject(t, dnsMap) + bootstrapDNS := newDNSConf["bootstrap_dns"] switch v := bootstrapDNS.(type) { case []string: - if len(v) != 1 { - t.Fatalf("Wrong count of bootsrap DNS servers: %d", len(v)) - } - - if v[0] != "8.8.8.8:53" { - t.Fatalf("Bootsrap DNS server is not 8.8.8.8:53 : %s", v[0]) - } + require.Len(t, v, 1) + require.Equal(t, "8.8.8.8:53", v[0]) default: - t.Fatalf("Wrong type for bootsrap DNS: %T", v) + t.Fatalf("wrong type for bootsrap dns: %T", v) } - // exclude bootstrap DNS from DNS configs comparison excludedEntries := []string{"bootstrap_dns"} - oldDNSConfig := castInterfaceToMap(t, createTestDNSConfig(2)) - compareConfigsWithoutEntries(t, &oldDNSConfig, &newDNSConfig, excludedEntries, excludedEntries) + oldDNSConf := convertToObject(t, testDNSConf(2)) + assertEqualExcept(t, oldDNSConf, newDNSConf, excludedEntries, excludedEntries) - // excluded dns config and schema version from disk config comparison excludedEntries = []string{"dns", "schema_version"} - oldDiskConfig := createTestDiskConfig(2) - compareConfigsWithoutEntries(t, &oldDiskConfig, &diskConfig, excludedEntries, excludedEntries) + oldDiskConf := testDiskConf(2) + assertEqualExcept(t, oldDiskConf, diskConf, excludedEntries, excludedEntries) } -func castInterfaceToMap(t *testing.T, oldConfig interface{}) (newConfig map[string]interface{}) { - newConfig = make(map[string]interface{}) - switch v := oldConfig.(type) { - case map[interface{}]interface{}: +func convertToObject(t *testing.T, oldConf any) (newConf object) { + t.Helper() + + switch v := oldConf.(type) { + case map[any]any: + newConf = make(object, len(v)) for key, value := range v { - newConfig[fmt.Sprint(key)] = value + newConf[fmt.Sprint(key)] = value } - case map[string]interface{}: + case object: + newConf = make(object, len(v)) for key, value := range v { - newConfig[key] = value + newConf[key] = value } default: - t.Fatalf("DNS configuration is not a map") + t.Fatalf("dns configuration is not a map, got %T", oldConf) } - return -} -// compareConfigsWithoutEntry removes entries from configs and returns result of compareConfigs -func compareConfigsWithoutEntries(t *testing.T, oldConfig, newConfig *map[string]interface{}, oldKey, newKey []string) { - for _, k := range oldKey { - delete(*oldConfig, k) - } - for _, k := range newKey { - delete(*newConfig, k) - } - compareConfigs(t, oldConfig, newConfig) + return newConf } -// compares configs before and after schema upgrade -func compareConfigs(t *testing.T, oldConfig, newConfig *map[string]interface{}) { - if len(*oldConfig) != len(*newConfig) { - t.Fatalf("wrong config entries count! Before upgrade: %d; After upgrade: %d", len(*oldConfig), len(*oldConfig)) - } +// assertEqualExcept removes entries from configs and compares them. +func assertEqualExcept(t *testing.T, oldConf, newConf object, oldKeys, newKeys []string) { + t.Helper() - // Check old and new entries - for k, v := range *newConfig { - switch value := v.(type) { - case string: - if value != (*oldConfig)[k] { - t.Fatalf("wrong value for string %s. Before update: %s; After update: %s", k, (*oldConfig)[k], value) - } - case int: - if value != (*oldConfig)[k] { - t.Fatalf("wrong value for int %s. Before update: %d; After update: %d", k, (*oldConfig)[k], value) - } - case []string: - for i, line := range value { - if len((*oldConfig)[k].([]string)) != len(value) { - t.Fatalf("wrong array length for %s. Before update: %d; After update: %d", k, len((*oldConfig)[k].([]string)), len(value)) - } - if (*oldConfig)[k].([]string)[i] != line { - t.Fatalf("wrong data for string array %s. Before update: %s; After update: %s", k, (*oldConfig)[k].([]string)[i], line) - } - } - case bool: - if v != (*oldConfig)[k].(bool) { - t.Fatalf("wrong boolean value for %s", k) - } - case []filter: - if len((*oldConfig)[k].([]filter)) != len(value) { - t.Fatalf("wrong filters count. Before update: %d; After update: %d", len((*oldConfig)[k].([]filter)), len(value)) - } - for i, newFilter := range value { - oldFilter := (*oldConfig)[k].([]filter)[i] - if oldFilter.Enabled != newFilter.Enabled || oldFilter.Name != newFilter.Name || oldFilter.RulesCount != newFilter.RulesCount { - t.Fatalf("old filter %s not equals new filter %s", oldFilter.Name, newFilter.Name) - } - } - default: - t.Fatalf("uknown data type for %s: %T", k, value) - } + for _, k := range oldKeys { + delete(oldConf, k) } -} - -// compareSchemaVersion check if newSchemaVersion equals schemaVersion -func compareSchemaVersion(t *testing.T, newSchemaVersion interface{}, schemaVersion int) { - switch v := newSchemaVersion.(type) { - case int: - if v != schemaVersion { - t.Fatalf("Wrong schema version in new config file") - } - default: - t.Fatalf("Schema version is not an integer after update") + for _, k := range newKeys { + delete(newConf, k) } + + assert.Equal(t, oldConf, newConf) } -func createTestDiskConfig(schemaVersion int) (diskConfig map[string]interface{}) { - diskConfig = make(map[string]interface{}) - diskConfig["language"] = "en" - diskConfig["filters"] = []filter{ +func testDiskConf(schemaVersion int) (diskConf object) { + filters := []filter{ { URL: "https://filters.adtidy.org/android/filters/111_optimized.txt", Name: "Latvian filter", @@ -191,40 +116,51 @@ func createTestDiskConfig(schemaVersion int) (diskConfig map[string]interface{}) RulesCount: 200, }, } - diskConfig["user_rules"] = []string{} - diskConfig["schema_version"] = schemaVersion - diskConfig["bind_host"] = "0.0.0.0" - diskConfig["bind_port"] = 80 - diskConfig["auth_name"] = "name" - diskConfig["auth_pass"] = "pass" - dnsConfig := createTestDNSConfig(schemaVersion) + diskConf = object{ + "language": "en", + "filters": filters, + "user_rules": []string{}, + "schema_version": schemaVersion, + "bind_host": "0.0.0.0", + "bind_port": 80, + "auth_name": "name", + "auth_pass": "pass", + } + + dnsConf := testDNSConf(schemaVersion) if schemaVersion > 1 { - diskConfig["dns"] = dnsConfig + diskConf["dns"] = dnsConf } else { - diskConfig["coredns"] = dnsConfig + diskConf["coredns"] = dnsConf } - return diskConfig + + return diskConf } -func createTestDNSConfig(schemaVersion int) map[interface{}]interface{} { - dnsConfig := make(map[interface{}]interface{}) - dnsConfig["port"] = 53 - dnsConfig["blocked_response_ttl"] = 10 - dnsConfig["querylog_enabled"] = true - dnsConfig["ratelimit"] = 20 - dnsConfig["bootstrap_dns"] = "8.8.8.8:53" +// testDNSConf creates a DNS config for test the way gopkg.in/yaml.v2 would +// unmarshal it. In YAML, keys aren't guaranteed to always only be strings. +func testDNSConf(schemaVersion int) (dnsConf map[any]any) { + dnsConf = map[any]any{ + "port": 53, + "blocked_response_ttl": 10, + "querylog_enabled": true, + "ratelimit": 20, + "bootstrap_dns": "8.8.8.8:53", + "parental_sensitivity": 13, + "ratelimit_whitelist": []string{}, + "upstream_dns": []string{"tls://1.1.1.1", "tls://1.0.0.1", "8.8.8.8"}, + "filtering_enabled": true, + "refuse_any": true, + "parental_enabled": true, + "bind_host": "0.0.0.0", + "protection_enabled": true, + "safesearch_enabled": true, + "safebrowsing_enabled": true, + } + if schemaVersion > 2 { - dnsConfig["bootstrap_dns"] = []string{"8.8.8.8:53"} + dnsConf["bootstrap_dns"] = []string{"8.8.8.8:53"} } - dnsConfig["parental_sensitivity"] = 13 - dnsConfig["ratelimit_whitelist"] = []string{} - dnsConfig["upstream_dns"] = []string{"tls://1.1.1.1", "tls://1.0.0.1", "8.8.8.8"} - dnsConfig["filtering_enabled"] = true - dnsConfig["refuse_any"] = true - dnsConfig["parental_enabled"] = true - dnsConfig["bind_host"] = "0.0.0.0" - dnsConfig["protection_enabled"] = true - dnsConfig["safesearch_enabled"] = true - dnsConfig["safebrowsing_enabled"] = true - return dnsConfig + + return dnsConf }