github.com/openshift/installer@v1.4.17/pkg/asset/store/assetcreate_test.go (about)

     1  package store
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"path/filepath"
     7  	"reflect"
     8  	"testing"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  
    12  	"github.com/openshift/installer/pkg/asset"
    13  	"github.com/openshift/installer/pkg/asset/targets"
    14  )
    15  
    16  const userProvidedAssets = `{
    17    "*installconfig.baseDomain": {
    18      "BaseDomain": "test-domain"
    19    },
    20    "*installconfig.clusterID": {
    21      "ClusterID": "test-cluster-id"
    22    },
    23    "*installconfig.clusterName": {
    24      "ClusterName": "test-cluster"
    25    },
    26    "*installconfig.platform": {
    27      "none": {}
    28    },
    29    "*installconfig.pullSecret": {
    30      "PullSecret": "{\"auths\": {\"example.com\": {\"auth\": \"test-auth\"}}}\n"
    31    },
    32    "*installconfig.sshPublicKey": {}
    33  }`
    34  
    35  const singleNodeBootstrapInPlaceInstallConfig = `
    36  apiVersion: v1
    37  baseDomain: test-domain
    38  metadata:
    39    name: test-cluster
    40  platform:
    41    none: {}
    42  controlPlane:
    43    replicas: 1
    44  bootstrapInPlace:
    45    installationDisk: /dev/sda
    46  pullSecret: |
    47    {
    48      "auths": {
    49        "example.com": {
    50          "auth": "test-auth"
    51         }
    52      }
    53    }
    54  `
    55  
    56  func TestCreatedAssetsAreNotDirty(t *testing.T) {
    57  	cases := []struct {
    58  		name    string
    59  		targets []asset.WritableAsset
    60  		files   map[string]string
    61  	}{
    62  		{
    63  			name:    "install config",
    64  			targets: targets.InstallConfig,
    65  			files:   map[string]string{stateFileName: userProvidedAssets},
    66  		},
    67  		{
    68  			name:    "manifest templates",
    69  			targets: targets.ManifestTemplates,
    70  			files:   map[string]string{stateFileName: userProvidedAssets},
    71  		},
    72  		{
    73  			name:    "manifests",
    74  			targets: targets.Manifests,
    75  			files:   map[string]string{stateFileName: userProvidedAssets},
    76  		},
    77  		{
    78  			name:    "ignition configs",
    79  			targets: targets.IgnitionConfigs,
    80  			files:   map[string]string{stateFileName: userProvidedAssets},
    81  		},
    82  		{
    83  			name:    "single node bootstrap-in-place ignition config",
    84  			targets: targets.SingleNodeIgnitionConfig,
    85  			files:   map[string]string{"install-config.yaml": singleNodeBootstrapInPlaceInstallConfig},
    86  		},
    87  	}
    88  	for _, tc := range cases {
    89  		t.Run(tc.name, func(t *testing.T) {
    90  			tempDir := t.TempDir()
    91  
    92  			for name, contents := range tc.files {
    93  				if err := os.WriteFile(filepath.Join(tempDir, name), []byte(contents), 0o666); err != nil { //nolint:gosec // no sensitive data
    94  					t.Fatalf("could not write the %s file: %v", name, err)
    95  				}
    96  			}
    97  
    98  			assetStore, err := newStore(tempDir)
    99  			if err != nil {
   100  				t.Fatalf("failed to create asset store: %v", err)
   101  			}
   102  
   103  			for _, a := range tc.targets {
   104  				if err := assetStore.Fetch(context.TODO(), a, tc.targets...); err != nil {
   105  					t.Fatalf("failed to fetch %q: %v", a.Name(), err)
   106  				}
   107  
   108  				if err := asset.PersistToFile(a, tempDir); err != nil {
   109  					t.Fatalf("failed to write asset %q to disk: %v", a.Name(), err)
   110  				}
   111  			}
   112  
   113  			newAssetStore, err := newStore(tempDir)
   114  			if err != nil {
   115  				t.Fatalf("failed to create new asset store: %v", err)
   116  			}
   117  
   118  			emptyAssets := map[string]bool{
   119  				"Master Machines":               true, // no files for the 'none' platform
   120  				"Worker Machines":               true, // no files for the 'none' platform
   121  				"Cluster API Manifests":         true, // no files for the 'none' platform and ClusterAPIInstall feature gate not set
   122  				"Cluster API Machine Manifests": true, // no files for the 'none' platform and ClusterAPIInstall feature gate not set
   123  				"Metadata":                      true, // read-only
   124  				"Kubeadmin Password":            true, // read-only
   125  			}
   126  			for _, a := range tc.targets {
   127  				name := a.Name()
   128  				newAsset := reflect.New(reflect.TypeOf(a).Elem()).Interface().(asset.WritableAsset)
   129  				if err := newAssetStore.Fetch(context.TODO(), newAsset, tc.targets...); err != nil {
   130  					t.Fatalf("failed to fetch %q in new store: %v", a.Name(), err)
   131  				}
   132  				assetState := newAssetStore.assets[reflect.TypeOf(a)]
   133  				if !emptyAssets[name] {
   134  					assert.Truef(t, assetState.presentOnDisk, "asset %q was not found on disk", a.Name())
   135  				}
   136  			}
   137  
   138  			assert.Equal(t, len(assetStore.assets), len(newAssetStore.assets), "new asset store does not have the same number of assets as original")
   139  
   140  			for _, a := range newAssetStore.assets {
   141  				if a.source == unfetched {
   142  					continue
   143  				}
   144  				if emptyAssets[a.asset.Name()] {
   145  					continue
   146  				}
   147  				originalAssetState, ok := assetStore.assets[reflect.TypeOf(a.asset)]
   148  				if !ok {
   149  					t.Fatalf("asset %q not found in original store", a.asset.Name())
   150  				}
   151  				assert.Equalf(t, originalAssetState.asset, a.asset, "fetched and generated asset %q are not equal", a.asset.Name())
   152  				assert.Equalf(t, stateFileSource, a.source, "asset %q was not fetched from the state file", a.asset.Name())
   153  			}
   154  		})
   155  	}
   156  }