@@ -1420,6 +1420,9 @@ func TestConfigEntry_ResolveServiceConfig_Blocking(t *testing.T) {
1420
1420
// of the blocking query does NOT bleed over into the next run. Concretely
1421
1421
// in this test the data present in the initial proxy-defaults should not
1422
1422
// be present when we are woken up due to proxy-defaults being deleted.
1423
+ //
1424
+ // This test does not pertain to upstreams, see:
1425
+ // TestConfigEntry_ResolveServiceConfig_Upstreams_Blocking
1423
1426
1424
1427
state := s1 .fsm .State ()
1425
1428
require .NoError (state .EnsureConfigEntry (1 , & structs.ProxyConfigEntry {
@@ -1571,6 +1574,205 @@ func TestConfigEntry_ResolveServiceConfig_Blocking(t *testing.T) {
1571
1574
}
1572
1575
}
1573
1576
1577
+ func TestConfigEntry_ResolveServiceConfig_Upstreams_Blocking (t * testing.T ) {
1578
+ if testing .Short () {
1579
+ t .Skip ("too slow for testing.Short" )
1580
+ }
1581
+
1582
+ t .Parallel ()
1583
+
1584
+ dir1 , s1 := testServer (t )
1585
+ defer os .RemoveAll (dir1 )
1586
+ defer s1 .Shutdown ()
1587
+ codec := rpcClient (t , s1 )
1588
+ defer codec .Close ()
1589
+
1590
+ // The main thing this should test is that information from one iteration
1591
+ // of the blocking query does NOT bleed over into the next run. Concretely
1592
+ // in this test the data present in the initial proxy-defaults should not
1593
+ // be present when we are woken up due to proxy-defaults being deleted.
1594
+ //
1595
+ // This test is about fields in upstreams, see:
1596
+ // TestConfigEntry_ResolveServiceConfig_Blocking
1597
+
1598
+ state := s1 .fsm .State ()
1599
+ require .NoError (t , state .EnsureConfigEntry (1 , & structs.ServiceConfigEntry {
1600
+ Kind : structs .ServiceDefaults ,
1601
+ Name : "foo" ,
1602
+ Protocol : "http" ,
1603
+ }))
1604
+ require .NoError (t , state .EnsureConfigEntry (2 , & structs.ServiceConfigEntry {
1605
+ Kind : structs .ServiceDefaults ,
1606
+ Name : "bar" ,
1607
+ Protocol : "http" ,
1608
+ }))
1609
+
1610
+ var index uint64
1611
+
1612
+ runStep (t , "foo and bar should be both http" , func (t * testing.T ) {
1613
+ // Verify that we get the results of service-defaults for 'foo' and 'bar'.
1614
+ var out structs.ServiceConfigResponse
1615
+ require .NoError (t , msgpackrpc .CallWithCodec (codec , "ConfigEntry.ResolveServiceConfig" ,
1616
+ & structs.ServiceConfigRequest {
1617
+ Name : "foo" ,
1618
+ Datacenter : "dc1" ,
1619
+ UpstreamIDs : []structs.ServiceID {
1620
+ structs .NewServiceID ("bar" , nil ),
1621
+ structs .NewServiceID ("other" , nil ),
1622
+ },
1623
+ },
1624
+ & out ,
1625
+ ))
1626
+
1627
+ expected := structs.ServiceConfigResponse {
1628
+ ProxyConfig : map [string ]interface {}{
1629
+ "protocol" : "http" ,
1630
+ },
1631
+ UpstreamIDConfigs : []structs.OpaqueUpstreamConfig {
1632
+ {
1633
+ Upstream : structs .NewServiceID ("bar" , nil ),
1634
+ Config : map [string ]interface {}{
1635
+ "protocol" : "http" ,
1636
+ },
1637
+ },
1638
+ },
1639
+ QueryMeta : out .QueryMeta , // don't care
1640
+ }
1641
+
1642
+ require .Equal (t , expected , out )
1643
+ index = out .Index
1644
+ })
1645
+
1646
+ runStep (t , "blocking query for foo wakes on bar entry delete" , func (t * testing.T ) {
1647
+ // Now setup a blocking query for 'foo' while we erase the
1648
+ // service-defaults for bar.
1649
+
1650
+ // Async cause a change
1651
+ start := time .Now ()
1652
+ go func () {
1653
+ time .Sleep (100 * time .Millisecond )
1654
+ err := state .DeleteConfigEntry (index + 1 ,
1655
+ structs .ServiceDefaults ,
1656
+ "bar" ,
1657
+ nil ,
1658
+ )
1659
+ if err != nil {
1660
+ t .Errorf ("delete config entry failed: %v" , err )
1661
+ }
1662
+ }()
1663
+
1664
+ // Re-run the query
1665
+ var out structs.ServiceConfigResponse
1666
+ require .NoError (t , msgpackrpc .CallWithCodec (codec , "ConfigEntry.ResolveServiceConfig" ,
1667
+ & structs.ServiceConfigRequest {
1668
+ Name : "foo" ,
1669
+ Datacenter : "dc1" ,
1670
+ UpstreamIDs : []structs.ServiceID {
1671
+ structs .NewServiceID ("bar" , nil ),
1672
+ structs .NewServiceID ("other" , nil ),
1673
+ },
1674
+ QueryOptions : structs.QueryOptions {
1675
+ MinQueryIndex : index ,
1676
+ MaxQueryTime : time .Second ,
1677
+ },
1678
+ },
1679
+ & out ,
1680
+ ))
1681
+
1682
+ // Should block at least 100ms
1683
+ require .True (t , time .Since (start ) >= 100 * time .Millisecond , "too fast" )
1684
+
1685
+ // Check the indexes
1686
+ require .Equal (t , out .Index , index + 1 )
1687
+
1688
+ expected := structs.ServiceConfigResponse {
1689
+ ProxyConfig : map [string ]interface {}{
1690
+ "protocol" : "http" ,
1691
+ },
1692
+ QueryMeta : out .QueryMeta , // don't care
1693
+ }
1694
+
1695
+ require .Equal (t , expected , out )
1696
+ index = out .Index
1697
+ })
1698
+
1699
+ runStep (t , "foo should be http and bar should be unset" , func (t * testing.T ) {
1700
+ // Verify that we get the results of service-defaults for just 'foo'.
1701
+ var out structs.ServiceConfigResponse
1702
+ require .NoError (t , msgpackrpc .CallWithCodec (codec , "ConfigEntry.ResolveServiceConfig" ,
1703
+ & structs.ServiceConfigRequest {
1704
+ Name : "foo" ,
1705
+ Datacenter : "dc1" ,
1706
+ UpstreamIDs : []structs.ServiceID {
1707
+ structs .NewServiceID ("bar" , nil ),
1708
+ structs .NewServiceID ("other" , nil ),
1709
+ },
1710
+ },
1711
+ & out ,
1712
+ ))
1713
+
1714
+ expected := structs.ServiceConfigResponse {
1715
+ ProxyConfig : map [string ]interface {}{
1716
+ "protocol" : "http" ,
1717
+ },
1718
+ QueryMeta : out .QueryMeta , // don't care
1719
+ }
1720
+
1721
+ require .Equal (t , expected , out )
1722
+ index = out .Index
1723
+ })
1724
+
1725
+ runStep (t , "blocking query for foo wakes on foo entry delete" , func (t * testing.T ) {
1726
+ // Now setup a blocking query for 'foo' while we erase the
1727
+ // service-defaults for foo.
1728
+
1729
+ // Async cause a change
1730
+ start := time .Now ()
1731
+ go func () {
1732
+ time .Sleep (100 * time .Millisecond )
1733
+ err := state .DeleteConfigEntry (index + 1 ,
1734
+ structs .ServiceDefaults ,
1735
+ "foo" ,
1736
+ nil ,
1737
+ )
1738
+ if err != nil {
1739
+ t .Errorf ("delete config entry failed: %v" , err )
1740
+ }
1741
+ }()
1742
+
1743
+ // Re-run the query
1744
+ var out structs.ServiceConfigResponse
1745
+ require .NoError (t , msgpackrpc .CallWithCodec (codec , "ConfigEntry.ResolveServiceConfig" ,
1746
+ & structs.ServiceConfigRequest {
1747
+ Name : "foo" ,
1748
+ Datacenter : "dc1" ,
1749
+ UpstreamIDs : []structs.ServiceID {
1750
+ structs .NewServiceID ("bar" , nil ),
1751
+ structs .NewServiceID ("other" , nil ),
1752
+ },
1753
+ QueryOptions : structs.QueryOptions {
1754
+ MinQueryIndex : index ,
1755
+ MaxQueryTime : time .Second ,
1756
+ },
1757
+ },
1758
+ & out ,
1759
+ ))
1760
+
1761
+ // Should block at least 100ms
1762
+ require .True (t , time .Since (start ) >= 100 * time .Millisecond , "too fast" )
1763
+
1764
+ // Check the indexes
1765
+ require .Equal (t , out .Index , index + 1 )
1766
+
1767
+ expected := structs.ServiceConfigResponse {
1768
+ QueryMeta : out .QueryMeta , // don't care
1769
+ }
1770
+
1771
+ require .Equal (t , expected , out )
1772
+ index = out .Index
1773
+ })
1774
+ }
1775
+
1574
1776
func TestConfigEntry_ResolveServiceConfig_UpstreamProxyDefaultsProtocol (t * testing.T ) {
1575
1777
if testing .Short () {
1576
1778
t .Skip ("too slow for testing.Short" )
@@ -1848,3 +2050,10 @@ func TestConfigEntry_ProxyDefaultsExposeConfig(t *testing.T) {
1848
2050
require .True (t , ok )
1849
2051
require .Equal (t , expose , proxyConf .Expose )
1850
2052
}
2053
+
2054
+ func runStep (t * testing.T , name string , fn func (t * testing.T )) {
2055
+ t .Helper ()
2056
+ if ! t .Run (name , fn ) {
2057
+ t .FailNow ()
2058
+ }
2059
+ }
0 commit comments