github.com/hashicorp/packer@v1.14.3/internal/hcp/registry/hcl_test.go (about)

     1  package registry
     2  
     3  import (
     4  	"reflect"
     5  	"slices"
     6  	"strings"
     7  	"testing"
     8  
     9  	"github.com/hashicorp/packer/hcl2template"
    10  )
    11  
    12  func TestNewRegisterProperBuildName(t *testing.T) {
    13  	cases := map[string]struct {
    14  		expectedBuilds       []string
    15  		expectErr            bool
    16  		diagsSummaryContains string
    17  		builds               hcl2template.Builds
    18  	}{
    19  		"single build block with single source": {
    20  			expectErr:      false,
    21  			expectedBuilds: []string{"docker.ubuntu"},
    22  			builds: hcl2template.Builds{
    23  				&hcl2template.BuildBlock{
    24  					Sources: []hcl2template.SourceUseBlock{
    25  						{
    26  							SourceRef: hcl2template.SourceRef{
    27  								Type: "docker",
    28  								Name: "ubuntu",
    29  							},
    30  						},
    31  					},
    32  				},
    33  			},
    34  		},
    35  		"single build block with name and with single source": {
    36  			expectErr:      false,
    37  			expectedBuilds: []string{"docker.ubuntu"},
    38  			builds: hcl2template.Builds{
    39  				&hcl2template.BuildBlock{
    40  					Name: "my-build-block",
    41  					Sources: []hcl2template.SourceUseBlock{
    42  						{
    43  							SourceRef: hcl2template.SourceRef{
    44  								Type: "docker",
    45  								Name: "ubuntu",
    46  							},
    47  						},
    48  					},
    49  				},
    50  			},
    51  		},
    52  		"single build block with 2 sources": {
    53  			expectErr:      false,
    54  			expectedBuilds: []string{"docker.alpine", "docker.ubuntu"},
    55  			builds: hcl2template.Builds{
    56  				&hcl2template.BuildBlock{
    57  					Sources: []hcl2template.SourceUseBlock{
    58  						{
    59  							SourceRef: hcl2template.SourceRef{
    60  								Type: "docker",
    61  								Name: "ubuntu",
    62  							},
    63  						},
    64  						{
    65  							SourceRef: hcl2template.SourceRef{
    66  								Type: "docker",
    67  								Name: "alpine",
    68  							},
    69  						},
    70  					},
    71  				},
    72  			},
    73  		},
    74  		"single build block with 3 sources": {
    75  			expectErr:      false,
    76  			expectedBuilds: []string{"docker.alpine", "docker.ubuntu", "docker.arch"},
    77  			builds: hcl2template.Builds{
    78  				&hcl2template.BuildBlock{
    79  					Sources: []hcl2template.SourceUseBlock{
    80  						{
    81  							SourceRef: hcl2template.SourceRef{
    82  								Type: "docker",
    83  								Name: "ubuntu",
    84  							},
    85  						},
    86  						{
    87  							SourceRef: hcl2template.SourceRef{
    88  								Type: "docker",
    89  								Name: "alpine",
    90  							},
    91  						},
    92  						{
    93  							SourceRef: hcl2template.SourceRef{
    94  								Type: "docker",
    95  								Name: "arch",
    96  							},
    97  						},
    98  					},
    99  				},
   100  			},
   101  		},
   102  		"single build block with name and multiple sources": {
   103  			expectErr:      false,
   104  			expectedBuilds: []string{"docker.alpine", "docker.ubuntu"},
   105  			builds: hcl2template.Builds{
   106  				&hcl2template.BuildBlock{
   107  					Name: "my-build-block",
   108  					Sources: []hcl2template.SourceUseBlock{
   109  						{
   110  							SourceRef: hcl2template.SourceRef{
   111  								Type: "docker",
   112  								Name: "ubuntu",
   113  							},
   114  						},
   115  						{
   116  							SourceRef: hcl2template.SourceRef{
   117  								Type: "docker",
   118  								Name: "alpine",
   119  							},
   120  						},
   121  					},
   122  				},
   123  			},
   124  		},
   125  		"single build block with multiple identical sources create conflict": {
   126  			expectErr:            true,
   127  			diagsSummaryContains: "conflict",
   128  			builds: hcl2template.Builds{
   129  				&hcl2template.BuildBlock{
   130  					Sources: []hcl2template.SourceUseBlock{
   131  						{
   132  							SourceRef: hcl2template.SourceRef{
   133  								Type: "docker",
   134  								Name: "ubuntu",
   135  							},
   136  						},
   137  						{
   138  							SourceRef: hcl2template.SourceRef{
   139  								Type: "docker",
   140  								Name: "ubuntu",
   141  							},
   142  						},
   143  					},
   144  				},
   145  			},
   146  		},
   147  		"multiple build block with different source": {
   148  			expectErr:      false,
   149  			expectedBuilds: []string{"docker.alpine", "docker.ubuntu"},
   150  			builds: hcl2template.Builds{
   151  				&hcl2template.BuildBlock{
   152  					Sources: []hcl2template.SourceUseBlock{
   153  						{
   154  							SourceRef: hcl2template.SourceRef{
   155  								Type: "docker",
   156  								Name: "ubuntu",
   157  							},
   158  						},
   159  					},
   160  				},
   161  				&hcl2template.BuildBlock{
   162  					Sources: []hcl2template.SourceUseBlock{
   163  						{
   164  							SourceRef: hcl2template.SourceRef{
   165  								Type: "docker",
   166  								Name: "alpine",
   167  							},
   168  						},
   169  					},
   170  				},
   171  			},
   172  		},
   173  		"multiple build block with same source create conflict": {
   174  			expectErr:            true,
   175  			diagsSummaryContains: "conflict",
   176  			builds: hcl2template.Builds{
   177  				&hcl2template.BuildBlock{
   178  					Sources: []hcl2template.SourceUseBlock{
   179  						{
   180  							SourceRef: hcl2template.SourceRef{
   181  								Type: "docker",
   182  								Name: "ubuntu",
   183  							},
   184  						},
   185  						{
   186  							SourceRef: hcl2template.SourceRef{
   187  								Type: "docker",
   188  								Name: "alpine",
   189  							},
   190  						},
   191  					},
   192  				},
   193  				&hcl2template.BuildBlock{
   194  					Sources: []hcl2template.SourceUseBlock{
   195  						{
   196  							SourceRef: hcl2template.SourceRef{
   197  								Type: "docker",
   198  								Name: "ubuntu",
   199  							},
   200  						},
   201  						{
   202  							SourceRef: hcl2template.SourceRef{
   203  								Type: "docker",
   204  								Name: "alpine",
   205  							},
   206  						},
   207  					},
   208  				},
   209  			},
   210  		},
   211  		"multiple build block with same source but with different build name": {
   212  			expectErr:      false,
   213  			expectedBuilds: []string{"build1.docker.ubuntu", "build2.docker.ubuntu"},
   214  			builds: hcl2template.Builds{
   215  				&hcl2template.BuildBlock{
   216  					Name: "build1",
   217  					Sources: []hcl2template.SourceUseBlock{
   218  						{
   219  							SourceRef: hcl2template.SourceRef{
   220  								Type: "docker",
   221  								Name: "ubuntu",
   222  							},
   223  						},
   224  					},
   225  				},
   226  				&hcl2template.BuildBlock{
   227  					Name: "build2",
   228  					Sources: []hcl2template.SourceUseBlock{
   229  						{
   230  							SourceRef: hcl2template.SourceRef{
   231  								Type: "docker",
   232  								Name: "ubuntu",
   233  							},
   234  						},
   235  					},
   236  				},
   237  			},
   238  		},
   239  		"multiple build block with same source but with only one declared build name": {
   240  			expectErr:      false,
   241  			expectedBuilds: []string{"docker.ubuntu", "build.docker.ubuntu"},
   242  			builds: hcl2template.Builds{
   243  				&hcl2template.BuildBlock{
   244  					Name: "build",
   245  					Sources: []hcl2template.SourceUseBlock{
   246  						{
   247  							SourceRef: hcl2template.SourceRef{
   248  								Type: "docker",
   249  								Name: "ubuntu",
   250  							},
   251  						},
   252  					},
   253  				},
   254  				&hcl2template.BuildBlock{
   255  					Sources: []hcl2template.SourceUseBlock{
   256  						{
   257  							SourceRef: hcl2template.SourceRef{
   258  								Type: "docker",
   259  								Name: "ubuntu",
   260  							},
   261  						},
   262  					},
   263  				},
   264  			},
   265  		},
   266  	}
   267  
   268  	for desc, tc := range cases {
   269  		t.Run(desc, func(t *testing.T) {
   270  
   271  			config := &hcl2template.PackerConfig{
   272  				Builds: tc.builds,
   273  			}
   274  
   275  			registry := HCLRegistry{
   276  				configuration: config,
   277  				bucket: &Bucket{
   278  					Name:    "test-bucket-" + desc,
   279  					Version: &Version{},
   280  				},
   281  				buildNames: map[string]struct{}{},
   282  			}
   283  
   284  			diags := registry.registerAllComponents()
   285  			if tc.diagsSummaryContains != "" {
   286  
   287  				containsMsg := false
   288  				for _, diag := range diags {
   289  					if strings.Contains(diag.Summary, tc.diagsSummaryContains) {
   290  						containsMsg = true
   291  					}
   292  				}
   293  				if !containsMsg {
   294  					t.Fatalf("diagnostics should contains '%s' in summary", tc.diagsSummaryContains)
   295  				}
   296  			}
   297  			if !tc.expectErr {
   298  				if diags.HasErrors() {
   299  					t.Fatalf("should not report error diagnostic: %v", diags)
   300  				}
   301  			}
   302  			if tc.expectErr {
   303  				if !diags.HasErrors() {
   304  					t.Fatal("should report error in this case")
   305  				}
   306  				return
   307  			}
   308  
   309  			actualExpectedBuilds := registry.bucket.Version.expectedBuilds
   310  
   311  			slices.Sort(tc.expectedBuilds)
   312  			slices.Sort(actualExpectedBuilds)
   313  
   314  			if !reflect.DeepEqual(tc.expectedBuilds, actualExpectedBuilds) {
   315  				t.Fatalf("expectedBuilds registered: %v, got: %v", tc.expectedBuilds, actualExpectedBuilds)
   316  			}
   317  		})
   318  	}
   319  }