mock.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package pricing
  2. import (
  3. "context"
  4. "embed"
  5. "encoding/json"
  6. "fmt"
  7. "path/filepath"
  8. "strings"
  9. "github.com/opencost/opencost/core/pkg/reader"
  10. "gopkg.in/yaml.v3"
  11. )
  12. type MockPricingRepository struct {
  13. NodePricing []*NodePricing
  14. VolumePricing []*VolumePricing
  15. }
  16. func NewMockPricingRepository() (*MockPricingRepository, error) {
  17. repo := &MockPricingRepository{
  18. NodePricing: []*NodePricing{},
  19. VolumePricing: []*VolumePricing{},
  20. }
  21. // Default
  22. defaultPricingSet, err := loadTestFile("default.yaml")
  23. if err != nil {
  24. return nil, fmt.Errorf("error loading test default pricing: %w", err)
  25. }
  26. repo.NodePricing = append(repo.NodePricing, defaultPricingSet.Nodes...)
  27. repo.VolumePricing = append(repo.VolumePricing, defaultPricingSet.Volumes...)
  28. // AWS
  29. awsPricingSet, err := loadTestFile("aws.yaml")
  30. if err != nil {
  31. return nil, fmt.Errorf("error loading test AWS pricing: %w", err)
  32. }
  33. repo.NodePricing = append(repo.NodePricing, awsPricingSet.Nodes...)
  34. repo.VolumePricing = append(repo.VolumePricing, awsPricingSet.Volumes...)
  35. // Azure
  36. azurePricingSet, err := loadTestFile("azure.yaml")
  37. if err != nil {
  38. return nil, fmt.Errorf("error loading test Azure pricing: %w", err)
  39. }
  40. repo.NodePricing = append(repo.NodePricing, azurePricingSet.Nodes...)
  41. repo.VolumePricing = append(repo.VolumePricing, azurePricingSet.Volumes...)
  42. // GCP
  43. gcpPricingSet, err := loadTestFile("gcp.yaml")
  44. if err != nil {
  45. return nil, fmt.Errorf("error loading test GCP pricing: %w", err)
  46. }
  47. repo.NodePricing = append(repo.NodePricing, gcpPricingSet.Nodes...)
  48. repo.VolumePricing = append(repo.VolumePricing, gcpPricingSet.Volumes...)
  49. return repo, nil
  50. }
  51. func (repo *MockPricingRepository) NewNodePricingReader(ctx context.Context) (reader.Reader[*NodePricing], error) {
  52. return reader.NewSliceReader(repo.NodePricing), nil
  53. }
  54. func (repo *MockPricingRepository) NewVolumePricingReader(ctx context.Context) (reader.Reader[*VolumePricing], error) {
  55. return reader.NewSliceReader(repo.VolumePricing), nil
  56. }
  57. //go:embed test/*
  58. var pricingTestFS embed.FS
  59. func loadTestFile(filename string) (*PricingSet, error) {
  60. path := filepath.Join("test", filename)
  61. bs, err := pricingTestFS.ReadFile(path)
  62. if err != nil {
  63. panic(fmt.Errorf("failed to read embedded pricing file: %w", err))
  64. }
  65. var set *PricingSet
  66. // Detect file format based on extension
  67. ext := strings.ToLower(filepath.Ext(filename))
  68. switch ext {
  69. case ".json":
  70. err = json.Unmarshal(bs, &set)
  71. if err != nil {
  72. return nil, fmt.Errorf("failed to parse json: %w", err)
  73. }
  74. case ".yaml", ".yml":
  75. err = yaml.Unmarshal(bs, &set)
  76. if err != nil {
  77. return nil, fmt.Errorf("failed to parse yaml: %w", err)
  78. }
  79. default:
  80. return nil, fmt.Errorf("unsupported file format: %s (expected .json, .yaml, or .yml)", ext)
  81. }
  82. return set, nil
  83. }