provider_test.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. package oracle
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. "testing"
  7. "github.com/opencost/opencost/core/pkg/clustercache"
  8. "github.com/stretchr/testify/assert"
  9. v1 "k8s.io/api/core/v1"
  10. "k8s.io/apimachinery/pkg/api/resource"
  11. )
  12. func TestGetKey(t *testing.T) {
  13. var testCases = map[string]struct {
  14. isVirtual bool
  15. gpus int
  16. }{
  17. "virtual-node": {
  18. true,
  19. 0,
  20. },
  21. "gpu": {
  22. false,
  23. 3,
  24. },
  25. "node": {
  26. false,
  27. 0,
  28. },
  29. }
  30. for instanceType, testCase := range testCases {
  31. t.Run(instanceType, func(t *testing.T) {
  32. labels := map[string]string{
  33. v1.LabelInstanceTypeStable: instanceType,
  34. }
  35. if testCase.isVirtual {
  36. labels[virtualNodeLabel] = ""
  37. }
  38. key := (&Oracle{}).GetKey(labels, testNode(testCase.gpus))
  39. assert.NotEmpty(t, key.ID())
  40. features := strings.Split(key.Features(), ",")
  41. assert.Len(t, features, 3)
  42. assert.Equal(t, instanceType, features[0])
  43. assert.Equal(t, strconv.FormatBool(testCase.isVirtual), features[1])
  44. assert.Equal(t, testCase.gpus, key.GPUCount())
  45. if testCase.gpus > 0 {
  46. assert.Equal(t, "nvidia.com/gpu", key.GPUType())
  47. } else {
  48. assert.Equal(t, "", key.GPUType())
  49. }
  50. })
  51. }
  52. }
  53. func TestGetKeyFallsBackToOCIInstanceShapeLabel(t *testing.T) {
  54. labels := map[string]string{
  55. ociInstanceShapeLabel: "VM.Standard.E3.Flex",
  56. }
  57. key := (&Oracle{}).GetKey(labels, testNode(0))
  58. features := strings.Split(key.Features(), ",")
  59. assert.Len(t, features, 3)
  60. assert.Equal(t, "VM.Standard.E3.Flex", features[0])
  61. }
  62. func TestGetKeyPrefersKubernetesInstanceTypeLabel(t *testing.T) {
  63. labels := map[string]string{
  64. v1.LabelInstanceTypeStable: "VM.Standard.E3.Flex.2o.32g.1_1b",
  65. ociInstanceShapeLabel: "VM.Standard.E3.Flex",
  66. }
  67. key := (&Oracle{}).GetKey(labels, testNode(0))
  68. features := strings.Split(key.Features(), ",")
  69. assert.Len(t, features, 3)
  70. assert.Equal(t, "VM.Standard.E3.Flex.2o.32g.1_1b", features[0])
  71. }
  72. func TestGetPVKey(t *testing.T) {
  73. storageClass := "xyz"
  74. providerID := "ocid.abc"
  75. pv := &clustercache.PersistentVolume{
  76. Spec: v1.PersistentVolumeSpec{
  77. StorageClassName: storageClass,
  78. PersistentVolumeSource: v1.PersistentVolumeSource{
  79. CSI: &v1.CSIPersistentVolumeSource{
  80. VolumeHandle: providerID,
  81. Driver: driverOCIBV,
  82. },
  83. },
  84. },
  85. }
  86. pvkey := (&Oracle{}).GetPVKey(pv, map[string]string{}, "")
  87. assert.Equal(t, blockVolumePartNumber, pvkey.Features())
  88. assert.Equal(t, storageClass, pvkey.GetStorageClass())
  89. assert.Equal(t, providerID, pvkey.ID())
  90. }
  91. func TestRegions(t *testing.T) {
  92. regions := (&Oracle{}).Regions()
  93. assert.Len(t, regions, 39)
  94. }
  95. func TestNodePricing_Preemptible(t *testing.T) {
  96. oracle := &Oracle{
  97. RateCardStore: NewRateCardStore("", "USD"),
  98. DefaultPricing: DefaultPricing{
  99. OCPU: "0.2",
  100. Memory: "0.1",
  101. GPU: "0.3",
  102. Storage: "0.25",
  103. },
  104. }
  105. testCases := []struct {
  106. name string
  107. labels map[string]string
  108. expectUsage string
  109. }{
  110. {
  111. name: "preemptible node",
  112. labels: map[string]string{
  113. v1.LabelInstanceTypeStable: "VM.Standard.E4.Flex",
  114. preemptibleLabel: "true",
  115. },
  116. expectUsage: "preemptible",
  117. },
  118. {
  119. name: "non-preemptible node",
  120. labels: map[string]string{
  121. v1.LabelInstanceTypeStable: "VM.Standard.E4.Flex",
  122. },
  123. expectUsage: "",
  124. },
  125. {
  126. name: "preemptible label false",
  127. labels: map[string]string{
  128. v1.LabelInstanceTypeStable: "VM.Standard.E4.Flex",
  129. preemptibleLabel: "false",
  130. },
  131. expectUsage: "",
  132. },
  133. }
  134. for _, tc := range testCases {
  135. t.Run(tc.name, func(t *testing.T) {
  136. key := &oracleKey{
  137. instanceType: "VM.Standard.E4.Flex",
  138. labels: tc.labels,
  139. providerID: "ocid.test",
  140. }
  141. node, _, err := oracle.NodePricing(key)
  142. assert.NoError(t, err)
  143. assert.NotNil(t, node)
  144. assert.Equal(t, tc.expectUsage, node.UsageType)
  145. })
  146. }
  147. }
  148. func testNode(gpus int) *clustercache.Node {
  149. capacity := map[v1.ResourceName]resource.Quantity{}
  150. if gpus > 0 {
  151. capacity["nvidia.com/gpu"] = resource.MustParse(fmt.Sprintf("%d", gpus))
  152. }
  153. return &clustercache.Node{
  154. SpecProviderID: "ocid.abc",
  155. Status: v1.NodeStatus{
  156. Capacity: capacity,
  157. },
  158. }
  159. }