@@ -80,6 +80,7 @@ import (
80
80
"k8s.io/kubernetes/test/integration/etcd"
81
81
"k8s.io/kubernetes/test/integration/framework"
82
82
"k8s.io/kubernetes/test/utils/ktesting"
83
+ "k8s.io/utils/ptr"
83
84
)
84
85
85
86
func setup (t * testing.T , groupVersions ... schema.GroupVersion ) (context.Context , clientset.Interface , * restclient.Config , framework.TearDownFunc ) {
@@ -1677,6 +1678,203 @@ func TestGetSubresourcesAsTables(t *testing.T) {
1677
1678
}
1678
1679
}
1679
1680
1681
+ func TestGetScaleSubresourceAsTableForAllBuiltins (t * testing.T ) {
1682
+ // KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE allows for APIs pending removal to not block tests
1683
+ t .Setenv ("KUBE_APISERVER_SERVE_REMOVED_APIS_FOR_ONE_RELEASE" , "true" )
1684
+
1685
+ // Enable all features for testing
1686
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , "AllAlpha" , true )
1687
+ featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , "AllBeta" , true )
1688
+
1689
+ testNamespace := "test-scale"
1690
+ server := kubeapiservertesting .StartTestServerOrDie (t , nil , framework .DefaultTestServerFlags (), framework .SharedEtcd ())
1691
+ defer server .TearDownFn ()
1692
+
1693
+ clientset := clientset .NewForConfigOrDie (server .ClientConfig )
1694
+
1695
+ ns := framework .CreateNamespaceOrDie (clientset , testNamespace , t )
1696
+ defer framework .DeleteNamespaceOrDie (clientset , ns , t )
1697
+
1698
+ scaleResources := map [string ]runtime.Object {
1699
+ "deployments.apps/v1" : & apps.Deployment {
1700
+ ObjectMeta : metav1.ObjectMeta {
1701
+ Name : "dummy" ,
1702
+ },
1703
+ Spec : apps.DeploymentSpec {
1704
+ Replicas : ptr.To [int32 ](1 ),
1705
+ Selector : & metav1.LabelSelector {
1706
+ MatchLabels : map [string ]string {
1707
+ "app" : "dummy" ,
1708
+ },
1709
+ },
1710
+ Template : v1.PodTemplateSpec {
1711
+ ObjectMeta : metav1.ObjectMeta {
1712
+ Labels : map [string ]string {
1713
+ "app" : "dummy" ,
1714
+ },
1715
+ },
1716
+ Spec : v1.PodSpec {
1717
+ Containers : []v1.Container {
1718
+ {
1719
+ Name : "dummy-container" ,
1720
+ Image : "nginx:latest" ,
1721
+ },
1722
+ },
1723
+ },
1724
+ },
1725
+ },
1726
+ },
1727
+ "replicasets.apps/v1" : & apps.ReplicaSet {
1728
+ ObjectMeta : metav1.ObjectMeta {
1729
+ Name : "dummy" ,
1730
+ },
1731
+ Spec : apps.ReplicaSetSpec {
1732
+ Replicas : ptr.To [int32 ](1 ),
1733
+ Selector : & metav1.LabelSelector {
1734
+ MatchLabels : map [string ]string {
1735
+ "app" : "dummy" ,
1736
+ },
1737
+ },
1738
+ Template : v1.PodTemplateSpec {
1739
+ ObjectMeta : metav1.ObjectMeta {
1740
+ Labels : map [string ]string {
1741
+ "app" : "dummy" ,
1742
+ },
1743
+ },
1744
+ Spec : v1.PodSpec {
1745
+ Containers : []v1.Container {
1746
+ {
1747
+ Name : "dummy-container" ,
1748
+ Image : "nginx:latest" ,
1749
+ },
1750
+ },
1751
+ },
1752
+ },
1753
+ },
1754
+ },
1755
+ "statefulsets.apps/v1" : & apps.StatefulSet {
1756
+ ObjectMeta : metav1.ObjectMeta {
1757
+ Name : "dummy" ,
1758
+ },
1759
+ Spec : apps.StatefulSetSpec {
1760
+ ServiceName : "dummy" ,
1761
+ Replicas : ptr.To [int32 ](1 ),
1762
+ Selector : & metav1.LabelSelector {
1763
+ MatchLabels : map [string ]string {
1764
+ "app" : "dummy" ,
1765
+ },
1766
+ },
1767
+ Template : v1.PodTemplateSpec {
1768
+ ObjectMeta : metav1.ObjectMeta {
1769
+ Labels : map [string ]string {
1770
+ "app" : "dummy" ,
1771
+ },
1772
+ },
1773
+ Spec : v1.PodSpec {
1774
+ Containers : []v1.Container {
1775
+ {
1776
+ Name : "dummy-container" ,
1777
+ Image : "nginx:latest" ,
1778
+ },
1779
+ },
1780
+ },
1781
+ },
1782
+ },
1783
+ },
1784
+ "replicationcontrollers.v1" : & v1.ReplicationController {
1785
+ ObjectMeta : metav1.ObjectMeta {
1786
+ Name : "dummy" ,
1787
+ },
1788
+ Spec : v1.ReplicationControllerSpec {
1789
+ Replicas : ptr.To [int32 ](1 ),
1790
+ Selector : map [string ]string {
1791
+ "app" : "dummy" ,
1792
+ },
1793
+ Template : & v1.PodTemplateSpec {
1794
+ ObjectMeta : metav1.ObjectMeta {
1795
+ Labels : map [string ]string {
1796
+ "app" : "dummy" ,
1797
+ },
1798
+ },
1799
+ Spec : v1.PodSpec {
1800
+ Containers : []v1.Container {
1801
+ {
1802
+ Name : "dummy-container" ,
1803
+ Image : "nginx:latest" ,
1804
+ },
1805
+ },
1806
+ },
1807
+ },
1808
+ },
1809
+ },
1810
+ }
1811
+
1812
+ _ , serverResources , err := clientset .Discovery ().ServerGroupsAndResources ()
1813
+ if err != nil {
1814
+ t .Fatal (err )
1815
+ }
1816
+
1817
+ for _ , resourceList := range serverResources {
1818
+ for _ , resource := range resourceList .APIResources {
1819
+ if ! strings .Contains (resource .Name , "/scale" ) {
1820
+ continue
1821
+ }
1822
+ resourceName := strings .Split (resource .Name , "/" )[0 ]
1823
+ // we can safely skip error here, since the group version is coming from the server
1824
+ groupVersion , _ := schema .ParseGroupVersion (resourceList .GroupVersion )
1825
+
1826
+ t .Run (resourceName , func (t * testing.T ) {
1827
+ _ , ctx := ktesting .NewTestContext (t )
1828
+ scaleResourceObjName := fmt .Sprintf ("%s.%s" , resourceName , resourceList .GroupVersion )
1829
+ obj , ok := scaleResources [scaleResourceObjName ]
1830
+ if ! ok {
1831
+ t .Fatalf ("sample resource for %s not found in scaleResources" , scaleResourceObjName )
1832
+ }
1833
+
1834
+ cfg := dynamic .ConfigFor (server .ClientConfig )
1835
+ if len (groupVersion .Group ) == 0 {
1836
+ cfg = dynamic .ConfigFor (server .ClientConfig )
1837
+ cfg .APIPath = "/api"
1838
+ } else {
1839
+ cfg .APIPath = "/apis"
1840
+ }
1841
+ cfg .GroupVersion = & groupVersion
1842
+ client , err := restclient .RESTClientFor (cfg )
1843
+ if err != nil {
1844
+ t .Fatalf ("failed to create RESTClient: %v" , err )
1845
+ }
1846
+
1847
+ err = client .Post ().
1848
+ NamespaceIfScoped (testNamespace , resource .Namespaced ).Resource (resourceName ).
1849
+ VersionedParams (& metav1.CreateOptions {}, metav1 .ParameterCodec ).
1850
+ Body (obj ).Do (ctx ).Error ()
1851
+ if err != nil {
1852
+ t .Fatalf ("failed to create object: %v" , err )
1853
+ }
1854
+
1855
+ metaAccessor , err := meta .Accessor (obj )
1856
+ if err != nil {
1857
+ t .Fatalf ("failed to get metadata accessor: %v" , err )
1858
+ }
1859
+ res := client .Get ().
1860
+ NamespaceIfScoped (testNamespace , resource .Namespaced ).Resource (resourceName ).
1861
+ SetHeader ("Accept" , "application/json;as=Table;g=meta.k8s.io;v=v1" ).
1862
+ Name (metaAccessor .GetName ()).
1863
+ SubResource ("scale" ).
1864
+ Do (ctx )
1865
+ resObj , err := res .Get ()
1866
+ if err != nil {
1867
+ t .Fatalf ("failed to retrieve object from response: %v" , err )
1868
+ }
1869
+ actualKind := resObj .GetObjectKind ().GroupVersionKind ().Kind
1870
+ if actualKind != "Table" {
1871
+ t .Fatalf ("Expected Kind 'Table', got '%v'" , actualKind )
1872
+ }
1873
+ })
1874
+ }
1875
+ }
1876
+ }
1877
+
1680
1878
func TestTransform (t * testing.T ) {
1681
1879
testNamespace := "test-transform"
1682
1880
tearDown , config , _ , err := fixtures .StartDefaultServer (t )
0 commit comments