sigs.k8s.io/external-dns@v0.14.1/provider/pdns/pdns_test.go (about)

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package pdns
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"net/http"
    23  	"regexp"
    24  	"strings"
    25  	"testing"
    26  
    27  	pgo "github.com/ffledgling/pdns-go"
    28  	"github.com/stretchr/testify/assert"
    29  	"github.com/stretchr/testify/suite"
    30  
    31  	"sigs.k8s.io/external-dns/endpoint"
    32  )
    33  
    34  // FIXME: What do we do about labels?
    35  
    36  var (
    37  	// Simple RRSets that contain 1 A record and 1 TXT record
    38  	RRSetSimpleARecord = pgo.RrSet{
    39  		Name:  "example.com.",
    40  		Type_: "A",
    41  		Ttl:   300,
    42  		Records: []pgo.Record{
    43  			{Content: "8.8.8.8", Disabled: false, SetPtr: false},
    44  		},
    45  	}
    46  	RRSetSimpleTXTRecord = pgo.RrSet{
    47  		Name:  "example.com.",
    48  		Type_: "TXT",
    49  		Ttl:   300,
    50  		Records: []pgo.Record{
    51  			{Content: "\"heritage=external-dns,external-dns/owner=tower-pdns\"", Disabled: false, SetPtr: false},
    52  		},
    53  	}
    54  	RRSetLongARecord = pgo.RrSet{
    55  		Name:  "a.very.long.domainname.example.com.",
    56  		Type_: "A",
    57  		Ttl:   300,
    58  		Records: []pgo.Record{
    59  			{Content: "8.8.8.8", Disabled: false, SetPtr: false},
    60  		},
    61  	}
    62  	RRSetLongTXTRecord = pgo.RrSet{
    63  		Name:  "a.very.long.domainname.example.com.",
    64  		Type_: "TXT",
    65  		Ttl:   300,
    66  		Records: []pgo.Record{
    67  			{Content: "\"heritage=external-dns,external-dns/owner=tower-pdns\"", Disabled: false, SetPtr: false},
    68  		},
    69  	}
    70  	// RRSet with one record disabled
    71  	RRSetDisabledRecord = pgo.RrSet{
    72  		Name:  "example.com.",
    73  		Type_: "A",
    74  		Ttl:   300,
    75  		Records: []pgo.Record{
    76  			{Content: "8.8.8.8", Disabled: false, SetPtr: false},
    77  			{Content: "8.8.4.4", Disabled: true, SetPtr: false},
    78  		},
    79  	}
    80  
    81  	RRSetCNAMERecord = pgo.RrSet{
    82  		Name:  "cname.example.com.",
    83  		Type_: "CNAME",
    84  		Ttl:   300,
    85  		Records: []pgo.Record{
    86  			{Content: "example.com.", Disabled: false, SetPtr: false},
    87  		},
    88  	}
    89  
    90  	RRSetALIASRecord = pgo.RrSet{
    91  		Name:  "alias.example.com.",
    92  		Type_: "ALIAS",
    93  		Ttl:   300,
    94  		Records: []pgo.Record{
    95  			{Content: "example.by.any.other.name.com.", Disabled: false, SetPtr: false},
    96  		},
    97  	}
    98  
    99  	RRSetTXTRecord = pgo.RrSet{
   100  		Name:  "example.com.",
   101  		Type_: "TXT",
   102  		Ttl:   300,
   103  		Records: []pgo.Record{
   104  			{Content: "'would smell as sweet'", Disabled: false, SetPtr: false},
   105  		},
   106  	}
   107  
   108  	// Multiple PDNS records in an RRSet of a single type
   109  	RRSetMultipleRecords = pgo.RrSet{
   110  		Name:  "example.com.",
   111  		Type_: "A",
   112  		Ttl:   300,
   113  		Records: []pgo.Record{
   114  			{Content: "8.8.8.8", Disabled: false, SetPtr: false},
   115  			{Content: "8.8.4.4", Disabled: false, SetPtr: false},
   116  			{Content: "4.4.4.4", Disabled: false, SetPtr: false},
   117  		},
   118  	}
   119  
   120  	endpointsDisabledRecord = []*endpoint.Endpoint{
   121  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8"),
   122  	}
   123  
   124  	endpointsSimpleRecord = []*endpoint.Endpoint{
   125  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8"),
   126  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   127  	}
   128  
   129  	endpointsLongRecord = []*endpoint.Endpoint{
   130  		endpoint.NewEndpointWithTTL("a.very.long.domainname.example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8"),
   131  		endpoint.NewEndpointWithTTL("a.very.long.domainname.example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   132  	}
   133  
   134  	endpointsNonexistantZone = []*endpoint.Endpoint{
   135  		endpoint.NewEndpointWithTTL("does.not.exist.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8"),
   136  		endpoint.NewEndpointWithTTL("does.not.exist.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   137  	}
   138  	endpointsMultipleRecords = []*endpoint.Endpoint{
   139  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8", "8.8.4.4", "4.4.4.4"),
   140  	}
   141  
   142  	endpointsMixedRecords = []*endpoint.Endpoint{
   143  		endpoint.NewEndpointWithTTL("cname.example.com", endpoint.RecordTypeCNAME, endpoint.TTL(300), "example.com"),
   144  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "'would smell as sweet'"),
   145  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8", "8.8.4.4", "4.4.4.4"),
   146  		endpoint.NewEndpointWithTTL("alias.example.com", endpoint.RecordTypeCNAME, endpoint.TTL(300), "example.by.any.other.name.com"),
   147  	}
   148  
   149  	endpointsMultipleZones = []*endpoint.Endpoint{
   150  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8"),
   151  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   152  		endpoint.NewEndpointWithTTL("mock.test", endpoint.RecordTypeA, endpoint.TTL(300), "9.9.9.9"),
   153  		endpoint.NewEndpointWithTTL("mock.test", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   154  	}
   155  
   156  	endpointsMultipleZones2 = []*endpoint.Endpoint{
   157  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8"),
   158  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   159  		endpoint.NewEndpointWithTTL("abcd.mock.test", endpoint.RecordTypeA, endpoint.TTL(300), "9.9.9.9"),
   160  		endpoint.NewEndpointWithTTL("abcd.mock.test", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   161  	}
   162  
   163  	endpointsMultipleZonesWithNoExist = []*endpoint.Endpoint{
   164  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8"),
   165  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   166  		endpoint.NewEndpointWithTTL("abcd.mock.noexist", endpoint.RecordTypeA, endpoint.TTL(300), "9.9.9.9"),
   167  		endpoint.NewEndpointWithTTL("abcd.mock.noexist", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   168  	}
   169  	endpointsMultipleZonesWithLongRecordNotInDomainFilter = []*endpoint.Endpoint{
   170  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8"),
   171  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   172  		endpoint.NewEndpointWithTTL("a.very.long.domainname.example.com", endpoint.RecordTypeA, endpoint.TTL(300), "9.9.9.9"),
   173  		endpoint.NewEndpointWithTTL("a.very.long.domainname.example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   174  	}
   175  	endpointsMultipleZonesWithSimilarRecordNotInDomainFilter = []*endpoint.Endpoint{
   176  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeA, endpoint.TTL(300), "8.8.8.8"),
   177  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   178  		endpoint.NewEndpointWithTTL("test.simexample.com", endpoint.RecordTypeA, endpoint.TTL(300), "9.9.9.9"),
   179  		endpoint.NewEndpointWithTTL("test.simexample.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   180  	}
   181  	endpointsApexRecords = []*endpoint.Endpoint{
   182  		endpoint.NewEndpointWithTTL("cname.example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   183  		endpoint.NewEndpointWithTTL("cname.example.com", endpoint.RecordTypeCNAME, endpoint.TTL(300), "example.by.any.other.name.com"),
   184  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeTXT, endpoint.TTL(300), "\"heritage=external-dns,external-dns/owner=tower-pdns\""),
   185  		endpoint.NewEndpointWithTTL("example.com", endpoint.RecordTypeCNAME, endpoint.TTL(300), "example.by.any.other.name.com"),
   186  	}
   187  
   188  	ZoneEmpty = pgo.Zone{
   189  		// Opaque zone id (string), assigned by the server, should not be interpreted by the application. Guaranteed to be safe for embedding in URLs.
   190  		Id: "example.com.",
   191  		// Name of the zone (e.g. “example.com.”) MUST have a trailing dot
   192  		Name: "example.com.",
   193  		// Set to “Zone”
   194  		Type_: "Zone",
   195  		// API endpoint for this zone
   196  		Url: "/api/v1/servers/localhost/zones/example.com.",
   197  		// Zone kind, one of “Native”, “Master”, “Slave”
   198  		Kind: "Native",
   199  		// RRSets in this zone
   200  		Rrsets: []pgo.RrSet{},
   201  	}
   202  
   203  	ZoneEmptySimilar = pgo.Zone{
   204  		Id:     "simexample.com.",
   205  		Name:   "simexample.com.",
   206  		Type_:  "Zone",
   207  		Url:    "/api/v1/servers/localhost/zones/simexample.com.",
   208  		Kind:   "Native",
   209  		Rrsets: []pgo.RrSet{},
   210  	}
   211  
   212  	ZoneEmptyLong = pgo.Zone{
   213  		Id:     "long.domainname.example.com.",
   214  		Name:   "long.domainname.example.com.",
   215  		Type_:  "Zone",
   216  		Url:    "/api/v1/servers/localhost/zones/long.domainname.example.com.",
   217  		Kind:   "Native",
   218  		Rrsets: []pgo.RrSet{},
   219  	}
   220  
   221  	ZoneEmpty2 = pgo.Zone{
   222  		Id:     "mock.test.",
   223  		Name:   "mock.test.",
   224  		Type_:  "Zone",
   225  		Url:    "/api/v1/servers/localhost/zones/mock.test.",
   226  		Kind:   "Native",
   227  		Rrsets: []pgo.RrSet{},
   228  	}
   229  
   230  	ZoneMixed = pgo.Zone{
   231  		Id:     "example.com.",
   232  		Name:   "example.com.",
   233  		Type_:  "Zone",
   234  		Url:    "/api/v1/servers/localhost/zones/example.com.",
   235  		Kind:   "Native",
   236  		Rrsets: []pgo.RrSet{RRSetCNAMERecord, RRSetTXTRecord, RRSetMultipleRecords, RRSetALIASRecord},
   237  	}
   238  
   239  	ZoneEmptyToSimplePatch = pgo.Zone{
   240  		Id:    "example.com.",
   241  		Name:  "example.com.",
   242  		Type_: "Zone",
   243  		Url:   "/api/v1/servers/localhost/zones/example.com.",
   244  		Kind:  "Native",
   245  		Rrsets: []pgo.RrSet{
   246  			{
   247  				Name:       "example.com.",
   248  				Type_:      "A",
   249  				Ttl:        300,
   250  				Changetype: "REPLACE",
   251  				Records: []pgo.Record{
   252  					{
   253  						Content:  "8.8.8.8",
   254  						Disabled: false,
   255  						SetPtr:   false,
   256  					},
   257  				},
   258  				Comments: []pgo.Comment(nil),
   259  			},
   260  			{
   261  				Name:       "example.com.",
   262  				Type_:      "TXT",
   263  				Ttl:        300,
   264  				Changetype: "REPLACE",
   265  				Records: []pgo.Record{
   266  					{
   267  						Content:  "\"heritage=external-dns,external-dns/owner=tower-pdns\"",
   268  						Disabled: false,
   269  						SetPtr:   false,
   270  					},
   271  				},
   272  				Comments: []pgo.Comment(nil),
   273  			},
   274  		},
   275  	}
   276  
   277  	ZoneEmptyToSimplePatchLongRecordIgnoredInDomainFilter = pgo.Zone{
   278  		Id:    "example.com.",
   279  		Name:  "example.com.",
   280  		Type_: "Zone",
   281  		Url:   "/api/v1/servers/localhost/zones/example.com.",
   282  		Kind:  "Native",
   283  		Rrsets: []pgo.RrSet{
   284  			{
   285  				Name:       "a.very.long.domainname.example.com.",
   286  				Type_:      "A",
   287  				Ttl:        300,
   288  				Changetype: "REPLACE",
   289  				Records: []pgo.Record{
   290  					{
   291  						Content:  "9.9.9.9",
   292  						Disabled: false,
   293  						SetPtr:   false,
   294  					},
   295  				},
   296  				Comments: []pgo.Comment(nil),
   297  			},
   298  			{
   299  				Name:       "a.very.long.domainname.example.com.",
   300  				Type_:      "TXT",
   301  				Ttl:        300,
   302  				Changetype: "REPLACE",
   303  				Records: []pgo.Record{
   304  					{
   305  						Content:  "\"heritage=external-dns,external-dns/owner=tower-pdns\"",
   306  						Disabled: false,
   307  						SetPtr:   false,
   308  					},
   309  				},
   310  				Comments: []pgo.Comment(nil),
   311  			},
   312  			{
   313  				Name:       "example.com.",
   314  				Type_:      "A",
   315  				Ttl:        300,
   316  				Changetype: "REPLACE",
   317  				Records: []pgo.Record{
   318  					{
   319  						Content:  "8.8.8.8",
   320  						Disabled: false,
   321  						SetPtr:   false,
   322  					},
   323  				},
   324  				Comments: []pgo.Comment(nil),
   325  			},
   326  			{
   327  				Name:       "example.com.",
   328  				Type_:      "TXT",
   329  				Ttl:        300,
   330  				Changetype: "REPLACE",
   331  				Records: []pgo.Record{
   332  					{
   333  						Content:  "\"heritage=external-dns,external-dns/owner=tower-pdns\"",
   334  						Disabled: false,
   335  						SetPtr:   false,
   336  					},
   337  				},
   338  				Comments: []pgo.Comment(nil),
   339  			},
   340  		},
   341  	}
   342  
   343  	ZoneEmptyToLongPatch = pgo.Zone{
   344  		Id:    "long.domainname.example.com.",
   345  		Name:  "long.domainname.example.com.",
   346  		Type_: "Zone",
   347  		Url:   "/api/v1/servers/localhost/zones/long.domainname.example.com.",
   348  		Kind:  "Native",
   349  		Rrsets: []pgo.RrSet{
   350  			{
   351  				Name:       "a.very.long.domainname.example.com.",
   352  				Type_:      "A",
   353  				Ttl:        300,
   354  				Changetype: "REPLACE",
   355  				Records: []pgo.Record{
   356  					{
   357  						Content:  "8.8.8.8",
   358  						Disabled: false,
   359  						SetPtr:   false,
   360  					},
   361  				},
   362  				Comments: []pgo.Comment(nil),
   363  			},
   364  			{
   365  				Name:       "a.very.long.domainname.example.com.",
   366  				Type_:      "TXT",
   367  				Ttl:        300,
   368  				Changetype: "REPLACE",
   369  				Records: []pgo.Record{
   370  					{
   371  						Content:  "\"heritage=external-dns,external-dns/owner=tower-pdns\"",
   372  						Disabled: false,
   373  						SetPtr:   false,
   374  					},
   375  				},
   376  				Comments: []pgo.Comment(nil),
   377  			},
   378  		},
   379  	}
   380  
   381  	ZoneEmptyToSimplePatch2 = pgo.Zone{
   382  		Id:    "mock.test.",
   383  		Name:  "mock.test.",
   384  		Type_: "Zone",
   385  		Url:   "/api/v1/servers/localhost/zones/mock.test.",
   386  		Kind:  "Native",
   387  		Rrsets: []pgo.RrSet{
   388  			{
   389  				Name:       "mock.test.",
   390  				Type_:      "A",
   391  				Ttl:        300,
   392  				Changetype: "REPLACE",
   393  				Records: []pgo.Record{
   394  					{
   395  						Content:  "9.9.9.9",
   396  						Disabled: false,
   397  						SetPtr:   false,
   398  					},
   399  				},
   400  				Comments: []pgo.Comment(nil),
   401  			},
   402  			{
   403  				Name:       "mock.test.",
   404  				Type_:      "TXT",
   405  				Ttl:        300,
   406  				Changetype: "REPLACE",
   407  				Records: []pgo.Record{
   408  					{
   409  						Content:  "\"heritage=external-dns,external-dns/owner=tower-pdns\"",
   410  						Disabled: false,
   411  						SetPtr:   false,
   412  					},
   413  				},
   414  				Comments: []pgo.Comment(nil),
   415  			},
   416  		},
   417  	}
   418  
   419  	ZoneEmptyToSimplePatch3 = pgo.Zone{
   420  		Id:    "mock.test.",
   421  		Name:  "mock.test.",
   422  		Type_: "Zone",
   423  		Url:   "/api/v1/servers/localhost/zones/mock.test.",
   424  		Kind:  "Native",
   425  		Rrsets: []pgo.RrSet{
   426  			{
   427  				Name:       "abcd.mock.test.",
   428  				Type_:      "A",
   429  				Ttl:        300,
   430  				Changetype: "REPLACE",
   431  				Records: []pgo.Record{
   432  					{
   433  						Content:  "9.9.9.9",
   434  						Disabled: false,
   435  						SetPtr:   false,
   436  					},
   437  				},
   438  				Comments: []pgo.Comment(nil),
   439  			},
   440  			{
   441  				Name:       "abcd.mock.test.",
   442  				Type_:      "TXT",
   443  				Ttl:        300,
   444  				Changetype: "REPLACE",
   445  				Records: []pgo.Record{
   446  					{
   447  						Content:  "\"heritage=external-dns,external-dns/owner=tower-pdns\"",
   448  						Disabled: false,
   449  						SetPtr:   false,
   450  					},
   451  				},
   452  				Comments: []pgo.Comment(nil),
   453  			},
   454  		},
   455  	}
   456  
   457  	ZoneEmptyToSimpleDelete = pgo.Zone{
   458  		Id:    "example.com.",
   459  		Name:  "example.com.",
   460  		Type_: "Zone",
   461  		Url:   "/api/v1/servers/localhost/zones/example.com.",
   462  		Kind:  "Native",
   463  		Rrsets: []pgo.RrSet{
   464  			{
   465  				Name:       "example.com.",
   466  				Type_:      "A",
   467  				Changetype: "DELETE",
   468  				Records: []pgo.Record{
   469  					{
   470  						Content:  "8.8.8.8",
   471  						Disabled: false,
   472  						SetPtr:   false,
   473  					},
   474  				},
   475  				Comments: []pgo.Comment(nil),
   476  			},
   477  			{
   478  				Name:       "example.com.",
   479  				Type_:      "TXT",
   480  				Changetype: "DELETE",
   481  				Records: []pgo.Record{
   482  					{
   483  						Content:  "\"heritage=external-dns,external-dns/owner=tower-pdns\"",
   484  						Disabled: false,
   485  						SetPtr:   false,
   486  					},
   487  				},
   488  				Comments: []pgo.Comment(nil),
   489  			},
   490  		},
   491  	}
   492  
   493  	ZoneEmptyToApexPatch = pgo.Zone{
   494  		Id:    "example.com.",
   495  		Name:  "example.com.",
   496  		Type_: "Zone",
   497  		Url:   "/api/v1/servers/localhost/zones/example.com.",
   498  		Kind:  "Native",
   499  		Rrsets: []pgo.RrSet{
   500  			{
   501  				Name:       "cname.example.com.",
   502  				Type_:      "CNAME",
   503  				Ttl:        300,
   504  				Changetype: "REPLACE",
   505  				Records: []pgo.Record{
   506  					{
   507  						Content:  "example.by.any.other.name.com.",
   508  						Disabled: false,
   509  						SetPtr:   false,
   510  					},
   511  				},
   512  				Comments: []pgo.Comment(nil),
   513  			},
   514  			{
   515  				Name:       "cname.example.com.",
   516  				Type_:      "TXT",
   517  				Ttl:        300,
   518  				Changetype: "REPLACE",
   519  				Records: []pgo.Record{
   520  					{
   521  						Content:  "\"heritage=external-dns,external-dns/owner=tower-pdns\"",
   522  						Disabled: false,
   523  						SetPtr:   false,
   524  					},
   525  				},
   526  				Comments: []pgo.Comment(nil),
   527  			},
   528  			{
   529  				Name:       "example.com.",
   530  				Type_:      "ALIAS",
   531  				Ttl:        300,
   532  				Changetype: "REPLACE",
   533  				Records: []pgo.Record{
   534  					{
   535  						Content:  "example.by.any.other.name.com.",
   536  						Disabled: false,
   537  						SetPtr:   false,
   538  					},
   539  				},
   540  				Comments: []pgo.Comment(nil),
   541  			},
   542  			{
   543  				Name:       "example.com.",
   544  				Type_:      "TXT",
   545  				Ttl:        300,
   546  				Changetype: "REPLACE",
   547  				Records: []pgo.Record{
   548  					{
   549  						Content:  "\"heritage=external-dns,external-dns/owner=tower-pdns\"",
   550  						Disabled: false,
   551  						SetPtr:   false,
   552  					},
   553  				},
   554  				Comments: []pgo.Comment(nil),
   555  			},
   556  		},
   557  	}
   558  
   559  	DomainFilterListSingle = endpoint.DomainFilter{
   560  		Filters: []string{
   561  			"example.com",
   562  		},
   563  	}
   564  
   565  	DomainFilterChildListSingle = endpoint.DomainFilter{
   566  		Filters: []string{
   567  			"a.example.com",
   568  		},
   569  	}
   570  
   571  	DomainFilterListMultiple = endpoint.DomainFilter{
   572  		Filters: []string{
   573  			"example.com",
   574  			"mock.com",
   575  		},
   576  	}
   577  
   578  	DomainFilterChildListMultiple = endpoint.DomainFilter{
   579  		Filters: []string{
   580  			"a.example.com",
   581  			"c.example.com",
   582  		},
   583  	}
   584  
   585  	DomainFilterListEmpty = endpoint.DomainFilter{
   586  		Filters: []string{},
   587  	}
   588  
   589  	RegexDomainFilter = endpoint.NewRegexDomainFilter(regexp.MustCompile("example.com"), nil)
   590  
   591  	DomainFilterEmptyClient = &PDNSAPIClient{
   592  		dryRun:       false,
   593  		authCtx:      context.WithValue(context.Background(), pgo.ContextAPIKey, pgo.APIKey{Key: "TEST-API-KEY"}),
   594  		client:       pgo.NewAPIClient(pgo.NewConfiguration()),
   595  		domainFilter: DomainFilterListEmpty,
   596  	}
   597  
   598  	DomainFilterSingleClient = &PDNSAPIClient{
   599  		dryRun:       false,
   600  		authCtx:      context.WithValue(context.Background(), pgo.ContextAPIKey, pgo.APIKey{Key: "TEST-API-KEY"}),
   601  		client:       pgo.NewAPIClient(pgo.NewConfiguration()),
   602  		domainFilter: DomainFilterListSingle,
   603  	}
   604  
   605  	DomainFilterChildSingleClient = &PDNSAPIClient{
   606  		dryRun:       false,
   607  		authCtx:      context.WithValue(context.Background(), pgo.ContextAPIKey, pgo.APIKey{Key: "TEST-API-KEY"}),
   608  		client:       pgo.NewAPIClient(pgo.NewConfiguration()),
   609  		domainFilter: DomainFilterChildListSingle,
   610  	}
   611  
   612  	DomainFilterMultipleClient = &PDNSAPIClient{
   613  		dryRun:       false,
   614  		authCtx:      context.WithValue(context.Background(), pgo.ContextAPIKey, pgo.APIKey{Key: "TEST-API-KEY"}),
   615  		client:       pgo.NewAPIClient(pgo.NewConfiguration()),
   616  		domainFilter: DomainFilterListMultiple,
   617  	}
   618  
   619  	DomainFilterChildMultipleClient = &PDNSAPIClient{
   620  		dryRun:       false,
   621  		authCtx:      context.WithValue(context.Background(), pgo.ContextAPIKey, pgo.APIKey{Key: "TEST-API-KEY"}),
   622  		client:       pgo.NewAPIClient(pgo.NewConfiguration()),
   623  		domainFilter: DomainFilterChildListMultiple,
   624  	}
   625  
   626  	RegexDomainFilterClient = &PDNSAPIClient{
   627  		dryRun:       false,
   628  		authCtx:      context.WithValue(context.Background(), pgo.ContextAPIKey, pgo.APIKey{Key: "TEST-API-KEY"}),
   629  		client:       pgo.NewAPIClient(pgo.NewConfiguration()),
   630  		domainFilter: RegexDomainFilter,
   631  	}
   632  )
   633  
   634  /******************************************************************************/
   635  // API that returns a zone with multiple record types
   636  type PDNSAPIClientStub struct{}
   637  
   638  func (c *PDNSAPIClientStub) ListZones() ([]pgo.Zone, *http.Response, error) {
   639  	return []pgo.Zone{ZoneMixed}, nil, nil
   640  }
   641  
   642  func (c *PDNSAPIClientStub) PartitionZones(zones []pgo.Zone) ([]pgo.Zone, []pgo.Zone) {
   643  	return zones, nil
   644  }
   645  
   646  func (c *PDNSAPIClientStub) ListZone(zoneID string) (pgo.Zone, *http.Response, error) {
   647  	return ZoneMixed, nil, nil
   648  }
   649  
   650  func (c *PDNSAPIClientStub) PatchZone(zoneID string, zoneStruct pgo.Zone) (*http.Response, error) {
   651  	return nil, nil
   652  }
   653  
   654  /******************************************************************************/
   655  // API that returns a zones with no records
   656  type PDNSAPIClientStubEmptyZones struct {
   657  	// Keep track of all zones we receive via PatchZone
   658  	patchedZones []pgo.Zone
   659  }
   660  
   661  func (c *PDNSAPIClientStubEmptyZones) ListZones() ([]pgo.Zone, *http.Response, error) {
   662  	return []pgo.Zone{ZoneEmpty, ZoneEmptyLong, ZoneEmpty2}, nil, nil
   663  }
   664  
   665  func (c *PDNSAPIClientStubEmptyZones) PartitionZones(zones []pgo.Zone) ([]pgo.Zone, []pgo.Zone) {
   666  	return zones, nil
   667  }
   668  
   669  func (c *PDNSAPIClientStubEmptyZones) ListZone(zoneID string) (pgo.Zone, *http.Response, error) {
   670  	if strings.Contains(zoneID, "example.com") {
   671  		return ZoneEmpty, nil, nil
   672  	} else if strings.Contains(zoneID, "mock.test") {
   673  		return ZoneEmpty2, nil, nil
   674  	} else if strings.Contains(zoneID, "long.domainname.example.com") {
   675  		return ZoneEmptyLong, nil, nil
   676  	}
   677  	return pgo.Zone{}, nil, nil
   678  }
   679  
   680  func (c *PDNSAPIClientStubEmptyZones) PatchZone(zoneID string, zoneStruct pgo.Zone) (*http.Response, error) {
   681  	c.patchedZones = append(c.patchedZones, zoneStruct)
   682  	return nil, nil
   683  }
   684  
   685  /******************************************************************************/
   686  // API that returns error on PatchZone()
   687  type PDNSAPIClientStubPatchZoneFailure struct {
   688  	// Anonymous struct for composition
   689  	PDNSAPIClientStubEmptyZones
   690  }
   691  
   692  // Just overwrite the PatchZone method to introduce a failure
   693  func (c *PDNSAPIClientStubPatchZoneFailure) PatchZone(zoneID string, zoneStruct pgo.Zone) (*http.Response, error) {
   694  	return nil, errors.New("Generic PDNS Error")
   695  }
   696  
   697  /******************************************************************************/
   698  // API that returns error on ListZone()
   699  type PDNSAPIClientStubListZoneFailure struct {
   700  	// Anonymous struct for composition
   701  	PDNSAPIClientStubEmptyZones
   702  }
   703  
   704  // Just overwrite the ListZone method to introduce a failure
   705  func (c *PDNSAPIClientStubListZoneFailure) ListZone(zoneID string) (pgo.Zone, *http.Response, error) {
   706  	return pgo.Zone{}, nil, errors.New("Generic PDNS Error")
   707  }
   708  
   709  /******************************************************************************/
   710  // API that returns error on ListZones() (Zones - plural)
   711  type PDNSAPIClientStubListZonesFailure struct {
   712  	// Anonymous struct for composition
   713  	PDNSAPIClientStubEmptyZones
   714  }
   715  
   716  // Just overwrite the ListZones method to introduce a failure
   717  func (c *PDNSAPIClientStubListZonesFailure) ListZones() ([]pgo.Zone, *http.Response, error) {
   718  	return []pgo.Zone{}, nil, errors.New("Generic PDNS Error")
   719  }
   720  
   721  /******************************************************************************/
   722  // API that returns zone partitions given DomainFilter(s)
   723  type PDNSAPIClientStubPartitionZones struct {
   724  	// Anonymous struct for composition
   725  	PDNSAPIClientStubEmptyZones
   726  }
   727  
   728  func (c *PDNSAPIClientStubPartitionZones) ListZones() ([]pgo.Zone, *http.Response, error) {
   729  	return []pgo.Zone{ZoneEmpty, ZoneEmptyLong, ZoneEmpty2, ZoneEmptySimilar}, nil, nil
   730  }
   731  
   732  func (c *PDNSAPIClientStubPartitionZones) ListZone(zoneID string) (pgo.Zone, *http.Response, error) {
   733  	if strings.Contains(zoneID, "example.com") {
   734  		return ZoneEmpty, nil, nil
   735  	} else if strings.Contains(zoneID, "mock.test") {
   736  		return ZoneEmpty2, nil, nil
   737  	} else if strings.Contains(zoneID, "long.domainname.example.com") {
   738  		return ZoneEmptyLong, nil, nil
   739  	} else if strings.Contains(zoneID, "simexample.com") {
   740  		return ZoneEmptySimilar, nil, nil
   741  	}
   742  	return pgo.Zone{}, nil, nil
   743  }
   744  
   745  // Just overwrite the ListZones method to introduce a failure
   746  func (c *PDNSAPIClientStubPartitionZones) PartitionZones(zones []pgo.Zone) ([]pgo.Zone, []pgo.Zone) {
   747  	return []pgo.Zone{ZoneEmpty}, []pgo.Zone{ZoneEmptyLong, ZoneEmpty2}
   748  }
   749  
   750  /******************************************************************************/
   751  
   752  type NewPDNSProviderTestSuite struct {
   753  	suite.Suite
   754  }
   755  
   756  func (suite *NewPDNSProviderTestSuite) TestPDNSProviderCreate() {
   757  	_, err := NewPDNSProvider(
   758  		context.Background(),
   759  		PDNSConfig{
   760  			Server:       "http://localhost:8081",
   761  			DomainFilter: endpoint.NewDomainFilter([]string{""}),
   762  		})
   763  	assert.Error(suite.T(), err, "--pdns-api-key should be specified")
   764  
   765  	_, err = NewPDNSProvider(
   766  		context.Background(),
   767  		PDNSConfig{
   768  			Server:       "http://localhost:8081",
   769  			APIKey:       "foo",
   770  			DomainFilter: endpoint.NewDomainFilter([]string{"example.com", "example.org"}),
   771  		})
   772  	assert.Nil(suite.T(), err, "--domain-filter should raise no error")
   773  
   774  	_, err = NewPDNSProvider(
   775  		context.Background(),
   776  		PDNSConfig{
   777  			Server:       "http://localhost:8081",
   778  			APIKey:       "foo",
   779  			DomainFilter: endpoint.NewDomainFilter([]string{""}),
   780  			DryRun:       true,
   781  		})
   782  	assert.Error(suite.T(), err, "--dry-run should raise an error")
   783  
   784  	// This is our "regular" code path, no error should be thrown
   785  	_, err = NewPDNSProvider(
   786  		context.Background(),
   787  		PDNSConfig{
   788  			Server:       "http://localhost:8081",
   789  			APIKey:       "foo",
   790  			DomainFilter: endpoint.NewDomainFilter([]string{""}),
   791  		})
   792  	assert.Nil(suite.T(), err, "Regular case should raise no error")
   793  }
   794  
   795  func (suite *NewPDNSProviderTestSuite) TestPDNSProviderCreateTLS() {
   796  	newProvider := func(TLSConfig TLSConfig) error {
   797  		_, err := NewPDNSProvider(
   798  			context.Background(),
   799  			PDNSConfig{APIKey: "foo", TLSConfig: TLSConfig})
   800  		return err
   801  	}
   802  
   803  	assert.Nil(suite.T(), newProvider(TLSConfig{SkipTLSVerify: true}), "Disabled TLS Config should raise no error")
   804  
   805  	assert.Nil(suite.T(), newProvider(TLSConfig{
   806  		SkipTLSVerify:         true,
   807  		CAFilePath:            "../../internal/testresources/ca.pem",
   808  		ClientCertFilePath:    "../../internal/testresources/client-cert.pem",
   809  		ClientCertKeyFilePath: "../../internal/testresources/client-cert-key.pem",
   810  	}), "Disabled TLS Config with additional flags should raise no error")
   811  
   812  	assert.Nil(suite.T(), newProvider(TLSConfig{}), "Enabled TLS Config without --tls-ca should raise no error")
   813  
   814  	assert.Nil(suite.T(), newProvider(TLSConfig{
   815  		CAFilePath: "../../internal/testresources/ca.pem",
   816  	}), "Enabled TLS Config with --tls-ca should raise no error")
   817  
   818  	assert.Error(suite.T(), newProvider(TLSConfig{
   819  		CAFilePath:         "../../internal/testresources/ca.pem",
   820  		ClientCertFilePath: "../../internal/testresources/client-cert.pem",
   821  	}), "Enabled TLS Config with --tls-client-cert only should raise an error")
   822  
   823  	assert.Error(suite.T(), newProvider(TLSConfig{
   824  		CAFilePath:            "../../internal/testresources/ca.pem",
   825  		ClientCertKeyFilePath: "../../internal/testresources/client-cert-key.pem",
   826  	}), "Enabled TLS Config with --tls-client-cert-key only should raise an error")
   827  
   828  	assert.Nil(suite.T(), newProvider(TLSConfig{
   829  		CAFilePath:            "../../internal/testresources/ca.pem",
   830  		ClientCertFilePath:    "../../internal/testresources/client-cert.pem",
   831  		ClientCertKeyFilePath: "../../internal/testresources/client-cert-key.pem",
   832  	}), "Enabled TLS Config with all flags should raise no error")
   833  }
   834  
   835  func (suite *NewPDNSProviderTestSuite) TestPDNSRRSetToEndpoints() {
   836  	// Function definition: convertRRSetToEndpoints(rr pgo.RrSet) (endpoints []*endpoint.Endpoint, _ error)
   837  
   838  	// Create a new provider to run tests against
   839  	p := &PDNSProvider{
   840  		client: &PDNSAPIClientStub{},
   841  	}
   842  
   843  	/* given an RRSet with three records, we test:
   844  	   - We correctly create corresponding endpoints
   845  	*/
   846  	eps, err := p.convertRRSetToEndpoints(RRSetMultipleRecords)
   847  	assert.Nil(suite.T(), err)
   848  	assert.Equal(suite.T(), endpointsMultipleRecords, eps)
   849  
   850  	/* Given an RRSet with two records, one of which is disabled, we test:
   851  	   - We can correctly convert the RRSet into a list of valid endpoints
   852  	   - We correctly discard/ignore the disabled record.
   853  	*/
   854  	eps, err = p.convertRRSetToEndpoints(RRSetDisabledRecord)
   855  	assert.Nil(suite.T(), err)
   856  	assert.Equal(suite.T(), endpointsDisabledRecord, eps)
   857  }
   858  
   859  func (suite *NewPDNSProviderTestSuite) TestPDNSRecords() {
   860  	// Function definition: Records() (endpoints []*endpoint.Endpoint, _ error)
   861  
   862  	// Create a new provider to run tests against
   863  	p := &PDNSProvider{
   864  		client: &PDNSAPIClientStub{},
   865  	}
   866  
   867  	ctx := context.Background()
   868  
   869  	/* We test that endpoints are returned correctly for a Zone when Records() is called
   870  	 */
   871  	eps, err := p.Records(ctx)
   872  	assert.Nil(suite.T(), err)
   873  	assert.Equal(suite.T(), endpointsMixedRecords, eps)
   874  
   875  	// Test failures are handled correctly
   876  	// Create a new provider to run tests against
   877  	p = &PDNSProvider{
   878  		client: &PDNSAPIClientStubListZoneFailure{},
   879  	}
   880  	_, err = p.Records(ctx)
   881  	assert.NotNil(suite.T(), err)
   882  
   883  	p = &PDNSProvider{
   884  		client: &PDNSAPIClientStubListZonesFailure{},
   885  	}
   886  	_, err = p.Records(ctx)
   887  	assert.NotNil(suite.T(), err)
   888  }
   889  
   890  func (suite *NewPDNSProviderTestSuite) TestPDNSConvertEndpointsToZones() {
   891  	// Function definition: ConvertEndpointsToZones(endpoints []*endpoint.Endpoint, changetype pdnsChangeType) (zonelist []pgo.Zone, _ error)
   892  
   893  	// Create a new provider to run tests against
   894  	p := &PDNSProvider{
   895  		client: &PDNSAPIClientStubEmptyZones{},
   896  	}
   897  
   898  	// Check inserting endpoints from a single zone
   899  	zlist, err := p.ConvertEndpointsToZones(endpointsSimpleRecord, PdnsReplace)
   900  	assert.Nil(suite.T(), err)
   901  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatch}, zlist)
   902  
   903  	// Check deleting endpoints from a single zone
   904  	zlist, err = p.ConvertEndpointsToZones(endpointsSimpleRecord, PdnsDelete)
   905  	assert.Nil(suite.T(), err)
   906  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimpleDelete}, zlist)
   907  
   908  	// Check endpoints from multiple zones #1
   909  	zlist, err = p.ConvertEndpointsToZones(endpointsMultipleZones, PdnsReplace)
   910  	assert.Nil(suite.T(), err)
   911  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatch, ZoneEmptyToSimplePatch2}, zlist)
   912  
   913  	// Check endpoints from multiple zones #2
   914  	zlist, err = p.ConvertEndpointsToZones(endpointsMultipleZones2, PdnsReplace)
   915  	assert.Nil(suite.T(), err)
   916  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatch, ZoneEmptyToSimplePatch3}, zlist)
   917  
   918  	// Check endpoints from multiple zones where some endpoints which don't exist
   919  	zlist, err = p.ConvertEndpointsToZones(endpointsMultipleZonesWithNoExist, PdnsReplace)
   920  	assert.Nil(suite.T(), err)
   921  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatch}, zlist)
   922  
   923  	// Check endpoints from a zone that does not exist
   924  	zlist, err = p.ConvertEndpointsToZones(endpointsNonexistantZone, PdnsReplace)
   925  	assert.Nil(suite.T(), err)
   926  	assert.Equal(suite.T(), []pgo.Zone{}, zlist)
   927  
   928  	// Check endpoints that match multiple zones (one longer than other), is assigned to the right zone
   929  	zlist, err = p.ConvertEndpointsToZones(endpointsLongRecord, PdnsReplace)
   930  	assert.Nil(suite.T(), err)
   931  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToLongPatch}, zlist)
   932  
   933  	// Check endpoints of type CNAME always have their target records end with a dot.
   934  	zlist, err = p.ConvertEndpointsToZones(endpointsMixedRecords, PdnsReplace)
   935  	assert.Nil(suite.T(), err)
   936  
   937  	for _, z := range zlist {
   938  		for _, rs := range z.Rrsets {
   939  			if rs.Type_ == "CNAME" {
   940  				for _, r := range rs.Records {
   941  					assert.Equal(suite.T(), uint8(0x2e), r.Content[len(r.Content)-1])
   942  				}
   943  			}
   944  		}
   945  	}
   946  
   947  	// Check endpoints of type CNAME are converted to ALIAS on the domain apex
   948  	zlist, err = p.ConvertEndpointsToZones(endpointsApexRecords, PdnsReplace)
   949  	assert.Nil(suite.T(), err)
   950  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToApexPatch}, zlist)
   951  }
   952  
   953  func (suite *NewPDNSProviderTestSuite) TestPDNSConvertEndpointsToZonesPartitionZones() {
   954  	// Test DomainFilters
   955  	p := &PDNSProvider{
   956  		client: &PDNSAPIClientStubPartitionZones{},
   957  	}
   958  
   959  	// Check inserting endpoints from a single zone which is specified in DomainFilter
   960  	zlist, err := p.ConvertEndpointsToZones(endpointsSimpleRecord, PdnsReplace)
   961  	assert.Nil(suite.T(), err)
   962  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatch}, zlist)
   963  
   964  	// Check deleting endpoints from a single zone which is specified in DomainFilter
   965  	zlist, err = p.ConvertEndpointsToZones(endpointsSimpleRecord, PdnsDelete)
   966  	assert.Nil(suite.T(), err)
   967  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimpleDelete}, zlist)
   968  
   969  	// Check endpoints from multiple zones # which one is specified in DomainFilter and one is not
   970  	zlist, err = p.ConvertEndpointsToZones(endpointsMultipleZones, PdnsReplace)
   971  	assert.Nil(suite.T(), err)
   972  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatch}, zlist)
   973  
   974  	// Check endpoints from multiple zones where some endpoints which don't exist and one that does
   975  	// and is part of DomainFilter
   976  	zlist, err = p.ConvertEndpointsToZones(endpointsMultipleZonesWithNoExist, PdnsReplace)
   977  	assert.Nil(suite.T(), err)
   978  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatch}, zlist)
   979  
   980  	// Check endpoints from a zone that does not exist
   981  	zlist, err = p.ConvertEndpointsToZones(endpointsNonexistantZone, PdnsReplace)
   982  	assert.Nil(suite.T(), err)
   983  	assert.Equal(suite.T(), []pgo.Zone{}, zlist)
   984  
   985  	// Check endpoints that match multiple zones (one longer than other), is assigned to the right zone when the longer
   986  	// zone is not part of the DomainFilter
   987  	zlist, err = p.ConvertEndpointsToZones(endpointsMultipleZonesWithLongRecordNotInDomainFilter, PdnsReplace)
   988  	assert.Nil(suite.T(), err)
   989  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatchLongRecordIgnoredInDomainFilter}, zlist)
   990  
   991  	// Check endpoints that match multiple zones (one longer than other and one is very similar)
   992  	// is assigned to the right zone when the similar zone is not part of the DomainFilter
   993  	zlist, err = p.ConvertEndpointsToZones(endpointsMultipleZonesWithSimilarRecordNotInDomainFilter, PdnsReplace)
   994  	assert.Nil(suite.T(), err)
   995  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatch}, zlist)
   996  }
   997  
   998  func (suite *NewPDNSProviderTestSuite) TestPDNSmutateRecords() {
   999  	// Function definition: mutateRecords(endpoints []*endpoint.Endpoint, changetype pdnsChangeType) error
  1000  
  1001  	// Create a new provider to run tests against
  1002  	c := &PDNSAPIClientStubEmptyZones{}
  1003  	p := &PDNSProvider{
  1004  		client: c,
  1005  	}
  1006  
  1007  	// Check inserting endpoints from a single zone
  1008  	err := p.mutateRecords(endpointsSimpleRecord, pdnsChangeType("REPLACE"))
  1009  	assert.Nil(suite.T(), err)
  1010  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimplePatch}, c.patchedZones)
  1011  
  1012  	// Reset the "patchedZones"
  1013  	c.patchedZones = []pgo.Zone{}
  1014  
  1015  	// Check deleting endpoints from a single zone
  1016  	err = p.mutateRecords(endpointsSimpleRecord, pdnsChangeType("DELETE"))
  1017  	assert.Nil(suite.T(), err)
  1018  	assert.Equal(suite.T(), []pgo.Zone{ZoneEmptyToSimpleDelete}, c.patchedZones)
  1019  
  1020  	// Check we fail correctly when patching fails for whatever reason
  1021  	p = &PDNSProvider{
  1022  		client: &PDNSAPIClientStubPatchZoneFailure{},
  1023  	}
  1024  	// Check inserting endpoints from a single zone
  1025  	err = p.mutateRecords(endpointsSimpleRecord, pdnsChangeType("REPLACE"))
  1026  	assert.NotNil(suite.T(), err)
  1027  }
  1028  
  1029  func (suite *NewPDNSProviderTestSuite) TestPDNSClientPartitionZones() {
  1030  	zoneList := []pgo.Zone{
  1031  		ZoneEmpty,
  1032  		ZoneEmpty2,
  1033  	}
  1034  
  1035  	partitionResultFilteredEmptyFilter := []pgo.Zone{
  1036  		ZoneEmpty,
  1037  		ZoneEmpty2,
  1038  	}
  1039  
  1040  	partitionResultResidualEmptyFilter := ([]pgo.Zone)(nil)
  1041  
  1042  	partitionResultFilteredSingleFilter := []pgo.Zone{
  1043  		ZoneEmpty,
  1044  	}
  1045  
  1046  	partitionResultResidualSingleFilter := []pgo.Zone{
  1047  		ZoneEmpty2,
  1048  	}
  1049  
  1050  	partitionResultFilteredMultipleFilter := []pgo.Zone{
  1051  		ZoneEmpty,
  1052  	}
  1053  
  1054  	partitionResultResidualMultipleFilter := []pgo.Zone{
  1055  		ZoneEmpty2,
  1056  	}
  1057  
  1058  	// Check filtered, residual zones when no domain filter specified
  1059  	filteredZones, residualZones := DomainFilterEmptyClient.PartitionZones(zoneList)
  1060  	assert.Equal(suite.T(), partitionResultFilteredEmptyFilter, filteredZones)
  1061  	assert.Equal(suite.T(), partitionResultResidualEmptyFilter, residualZones)
  1062  
  1063  	// Check filtered, residual zones when a single domain filter specified
  1064  	filteredZones, residualZones = DomainFilterSingleClient.PartitionZones(zoneList)
  1065  	assert.Equal(suite.T(), partitionResultFilteredSingleFilter, filteredZones)
  1066  	assert.Equal(suite.T(), partitionResultResidualSingleFilter, residualZones)
  1067  
  1068  	// Check filtered, residual zones when a multiple domain filter specified
  1069  	filteredZones, residualZones = DomainFilterMultipleClient.PartitionZones(zoneList)
  1070  	assert.Equal(suite.T(), partitionResultFilteredMultipleFilter, filteredZones)
  1071  	assert.Equal(suite.T(), partitionResultResidualMultipleFilter, residualZones)
  1072  
  1073  	filteredZones, residualZones = RegexDomainFilterClient.PartitionZones(zoneList)
  1074  	assert.Equal(suite.T(), partitionResultFilteredSingleFilter, filteredZones)
  1075  	assert.Equal(suite.T(), partitionResultResidualSingleFilter, residualZones)
  1076  }
  1077  
  1078  func TestNewPDNSProviderTestSuite(t *testing.T) {
  1079  	suite.Run(t, new(NewPDNSProviderTestSuite))
  1080  }