github.com/opentofu/opentofu@v1.7.1/internal/moduledeps/module_test.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package moduledeps 7 8 import ( 9 "fmt" 10 "reflect" 11 "testing" 12 13 "github.com/opentofu/opentofu/internal/addrs" 14 "github.com/opentofu/opentofu/internal/plugin/discovery" 15 ) 16 17 func TestModuleWalkTree(t *testing.T) { 18 type walkStep struct { 19 Path []string 20 ParentName string 21 } 22 23 tests := []struct { 24 Root *Module 25 WalkOrder []walkStep 26 }{ 27 { 28 &Module{ 29 Name: "root", 30 Children: nil, 31 }, 32 []walkStep{ 33 { 34 Path: []string{"root"}, 35 ParentName: "", 36 }, 37 }, 38 }, 39 { 40 &Module{ 41 Name: "root", 42 Children: []*Module{ 43 { 44 Name: "child", 45 }, 46 }, 47 }, 48 []walkStep{ 49 { 50 Path: []string{"root"}, 51 ParentName: "", 52 }, 53 { 54 Path: []string{"root", "child"}, 55 ParentName: "root", 56 }, 57 }, 58 }, 59 { 60 &Module{ 61 Name: "root", 62 Children: []*Module{ 63 { 64 Name: "child", 65 Children: []*Module{ 66 { 67 Name: "grandchild", 68 }, 69 }, 70 }, 71 }, 72 }, 73 []walkStep{ 74 { 75 Path: []string{"root"}, 76 ParentName: "", 77 }, 78 { 79 Path: []string{"root", "child"}, 80 ParentName: "root", 81 }, 82 { 83 Path: []string{"root", "child", "grandchild"}, 84 ParentName: "child", 85 }, 86 }, 87 }, 88 { 89 &Module{ 90 Name: "root", 91 Children: []*Module{ 92 { 93 Name: "child1", 94 Children: []*Module{ 95 { 96 Name: "grandchild1", 97 }, 98 }, 99 }, 100 { 101 Name: "child2", 102 Children: []*Module{ 103 { 104 Name: "grandchild2", 105 }, 106 }, 107 }, 108 }, 109 }, 110 []walkStep{ 111 { 112 Path: []string{"root"}, 113 ParentName: "", 114 }, 115 { 116 Path: []string{"root", "child1"}, 117 ParentName: "root", 118 }, 119 { 120 Path: []string{"root", "child1", "grandchild1"}, 121 ParentName: "child1", 122 }, 123 { 124 Path: []string{"root", "child2"}, 125 ParentName: "root", 126 }, 127 { 128 Path: []string{"root", "child2", "grandchild2"}, 129 ParentName: "child2", 130 }, 131 }, 132 }, 133 } 134 135 for i, test := range tests { 136 t.Run(fmt.Sprintf("%02d", i), func(t *testing.T) { 137 wo := test.WalkOrder 138 test.Root.WalkTree(func(path []string, parent *Module, current *Module) error { 139 if len(wo) == 0 { 140 t.Fatalf("ran out of walk steps while expecting one for %#v", path) 141 } 142 step := wo[0] 143 wo = wo[1:] 144 if got, want := path, step.Path; !reflect.DeepEqual(got, want) { 145 t.Errorf("wrong path %#v; want %#v", got, want) 146 } 147 parentName := "" 148 if parent != nil { 149 parentName = parent.Name 150 } 151 if got, want := parentName, step.ParentName; got != want { 152 t.Errorf("wrong parent name %q; want %q", got, want) 153 } 154 155 if got, want := current.Name, path[len(path)-1]; got != want { 156 t.Errorf("mismatching current.Name %q and final path element %q", got, want) 157 } 158 return nil 159 }) 160 }) 161 } 162 } 163 164 func TestModuleSortChildren(t *testing.T) { 165 m := &Module{ 166 Name: "root", 167 Children: []*Module{ 168 { 169 Name: "apple", 170 }, 171 { 172 Name: "zebra", 173 }, 174 { 175 Name: "xylophone", 176 }, 177 { 178 Name: "pig", 179 }, 180 }, 181 } 182 183 m.SortChildren() 184 185 want := []string{"apple", "pig", "xylophone", "zebra"} 186 var got []string 187 for _, c := range m.Children { 188 got = append(got, c.Name) 189 } 190 191 if !reflect.DeepEqual(want, got) { 192 t.Errorf("wrong order %#v; want %#v", want, got) 193 } 194 } 195 196 func TestModuleProviderRequirements(t *testing.T) { 197 m := &Module{ 198 Name: "root", 199 Providers: Providers{ 200 addrs.NewDefaultProvider("foo"): ProviderDependency{ 201 Constraints: discovery.ConstraintStr(">=1.0.0").MustParse(), 202 }, 203 addrs.NewDefaultProvider("baz"): ProviderDependency{ 204 Constraints: discovery.ConstraintStr(">=3.0.0").MustParse(), 205 }, 206 }, 207 } 208 209 reqd := m.ProviderRequirements() 210 if len(reqd) != 2 { 211 t.Errorf("wrong number of elements in %#v; want 2", reqd) 212 } 213 if got, want := reqd["foo"].Versions.String(), ">=1.0.0"; got != want { 214 t.Errorf("wrong combination of versions for 'foo' %q; want %q", got, want) 215 } 216 if got, want := reqd["baz"].Versions.String(), ">=3.0.0"; got != want { 217 t.Errorf("wrong combination of versions for 'baz' %q; want %q", got, want) 218 } 219 }