vmware_test.go 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. // +build amd64
  2. // Copyright 2015 CoreOS, Inc.
  3. //
  4. // Licensed under the Apache License, Version 2.0 (the "License");
  5. // you may not use this file except in compliance with the License.
  6. // You may obtain a copy of the License at
  7. //
  8. // http://www.apache.org/licenses/LICENSE-2.0
  9. //
  10. // Unless required by applicable law or agreed to in writing, software
  11. // distributed under the License is distributed on an "AS IS" BASIS,
  12. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. // See the License for the specific language governing permissions and
  14. // limitations under the License.
  15. package vmware
  16. import (
  17. "errors"
  18. "io/ioutil"
  19. "net"
  20. "os"
  21. "reflect"
  22. "testing"
  23. "github.com/rancher/os/config/cloudinit/datasource"
  24. )
  25. type MockHypervisor map[string]string
  26. func (h MockHypervisor) ReadConfig(key string) (string, error) {
  27. return h[key], nil
  28. }
  29. var fakeDownloader urlDownloadFunction = func(url string) ([]byte, error) {
  30. mapping := map[string]struct {
  31. data []byte
  32. err error
  33. }{
  34. "http://good.example.com": {[]byte("test config"), nil},
  35. "http://bad.example.com": {nil, errors.New("Not found")},
  36. }
  37. val := mapping[url]
  38. return val.data, val.err
  39. }
  40. func TestFetchMetadata(t *testing.T) {
  41. tests := []struct {
  42. variables MockHypervisor
  43. metadata datasource.Metadata
  44. err error
  45. }{
  46. {
  47. variables: map[string]string{
  48. "interface.0.mac": "test mac",
  49. "interface.0.dhcp": "yes",
  50. },
  51. metadata: datasource.Metadata{
  52. // NetworkConfig: map[string]string{
  53. // "interface.0.mac": "test mac",
  54. // "interface.0.dhcp": "yes",
  55. // },
  56. },
  57. },
  58. {
  59. variables: map[string]string{
  60. "interface.0.name": "test name",
  61. "interface.0.dhcp": "yes",
  62. },
  63. metadata: datasource.Metadata{
  64. // NetworkConfig: map[string]string{
  65. // "interface.0.name": "test name",
  66. // "interface.0.dhcp": "yes",
  67. // },
  68. },
  69. },
  70. {
  71. variables: map[string]string{
  72. "hostname": "test host",
  73. "interface.0.mac": "test mac",
  74. "interface.0.role": "private",
  75. "interface.0.ip.0.address": "fe00::100/64",
  76. "interface.0.route.0.gateway": "fe00::1",
  77. "interface.0.route.0.destination": "::",
  78. },
  79. metadata: datasource.Metadata{
  80. Hostname: "test host",
  81. PrivateIPv6: net.ParseIP("fe00::100"),
  82. // NetworkConfig: map[string]string{
  83. // "interface.0.mac": "test mac",
  84. // "interface.0.ip.0.address": "fe00::100/64",
  85. // "interface.0.route.0.gateway": "fe00::1",
  86. // "interface.0.route.0.destination": "::",
  87. // },
  88. },
  89. },
  90. {
  91. variables: map[string]string{
  92. "hostname": "test host",
  93. "interface.0.name": "test name",
  94. "interface.0.role": "public",
  95. "interface.0.ip.0.address": "10.0.0.100/24",
  96. "interface.0.ip.1.address": "10.0.0.101/24",
  97. "interface.0.route.0.gateway": "10.0.0.1",
  98. "interface.0.route.0.destination": "0.0.0.0",
  99. "interface.1.mac": "test mac",
  100. "interface.1.role": "private",
  101. "interface.1.route.0.gateway": "10.0.0.2",
  102. "interface.1.route.0.destination": "0.0.0.0",
  103. "interface.1.ip.0.address": "10.0.0.102/24",
  104. },
  105. metadata: datasource.Metadata{
  106. Hostname: "test host",
  107. PublicIPv4: net.ParseIP("10.0.0.101"),
  108. PrivateIPv4: net.ParseIP("10.0.0.102"),
  109. // NetworkConfig: map[string]string{
  110. // "interface.0.name": "test name",
  111. // "interface.0.ip.0.address": "10.0.0.100/24",
  112. // "interface.0.ip.1.address": "10.0.0.101/24",
  113. // "interface.0.route.0.gateway": "10.0.0.1",
  114. // "interface.0.route.0.destination": "0.0.0.0",
  115. // "interface.1.mac": "test mac",
  116. // "interface.1.route.0.gateway": "10.0.0.2",
  117. // "interface.1.route.0.destination": "0.0.0.0",
  118. // "interface.1.ip.0.address": "10.0.0.102/24",
  119. // },
  120. },
  121. },
  122. }
  123. for i, tt := range tests {
  124. v := VMWare{readConfig: tt.variables.ReadConfig}
  125. metadata, err := v.FetchMetadata()
  126. if !reflect.DeepEqual(tt.err, err) {
  127. t.Errorf("bad error (#%d): want %v, got %v", i, tt.err, err)
  128. }
  129. if !reflect.DeepEqual(tt.metadata, metadata) {
  130. t.Errorf("bad metadata (#%d): want %#v, got %#v", i, tt.metadata, metadata)
  131. }
  132. }
  133. }
  134. func TestFetchUserdata(t *testing.T) {
  135. tests := []struct {
  136. variables MockHypervisor
  137. userdata string
  138. err error
  139. }{
  140. {},
  141. {
  142. variables: map[string]string{"coreos.config.data": "test config"},
  143. userdata: "test config",
  144. },
  145. {
  146. variables: map[string]string{
  147. "coreos.config.data.encoding": "",
  148. "coreos.config.data": "test config",
  149. },
  150. userdata: "test config",
  151. },
  152. {
  153. variables: map[string]string{
  154. "coreos.config.data.encoding": "base64",
  155. "coreos.config.data": "dGVzdCBjb25maWc=",
  156. },
  157. userdata: "test config",
  158. },
  159. {
  160. variables: map[string]string{
  161. "coreos.config.data.encoding": "gzip+base64",
  162. "coreos.config.data": "H4sIABaoWlUAAytJLS5RSM7PS8tMBwCQiHNZCwAAAA==",
  163. },
  164. userdata: "test config",
  165. },
  166. {
  167. variables: map[string]string{
  168. "coreos.config.data.encoding": "test encoding",
  169. },
  170. err: errors.New(`Unsupported encoding "test encoding"`),
  171. },
  172. {
  173. variables: map[string]string{
  174. "coreos.config.url": "http://good.example.com",
  175. },
  176. userdata: "test config",
  177. },
  178. {
  179. variables: map[string]string{
  180. "coreos.config.url": "http://bad.example.com",
  181. },
  182. err: errors.New("Not found"),
  183. },
  184. }
  185. for i, tt := range tests {
  186. v := VMWare{
  187. readConfig: tt.variables.ReadConfig,
  188. urlDownload: fakeDownloader,
  189. }
  190. userdata, err := v.FetchUserdata()
  191. if !reflect.DeepEqual(tt.err, err) {
  192. t.Errorf("bad error (#%d): want %v, got %v", i, tt.err, err)
  193. }
  194. if tt.userdata != string(userdata) {
  195. t.Errorf("bad userdata (#%d): want %q, got %q", i, tt.userdata, userdata)
  196. }
  197. }
  198. }
  199. func TestFetchUserdataError(t *testing.T) {
  200. testErr := errors.New("test error")
  201. _, err := VMWare{readConfig: func(_ string) (string, error) { return "", testErr }}.FetchUserdata()
  202. if testErr != err {
  203. t.Errorf("bad error: want %v, got %v", testErr, err)
  204. }
  205. }
  206. func TestOvfTransport(t *testing.T) {
  207. tests := []struct {
  208. document string
  209. metadata datasource.Metadata
  210. userdata []byte
  211. }{
  212. {
  213. document: `<?xml version="1.0" encoding="UTF-8"?>
  214. <Environment xmlns="http://schemas.dmtf.org/ovf/environment/1"
  215. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  216. xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
  217. oe:id="CoreOS-vmw">
  218. <PlatformSection>
  219. <Kind>VMware ESXi</Kind>
  220. <Version>5.5.0</Version>
  221. <Vendor>VMware, Inc.</Vendor>
  222. <Locale>en</Locale>
  223. </PlatformSection>
  224. <PropertySection>
  225. <Property oe:key="foo" oe:value="42"/>
  226. <Property oe:key="guestinfo.coreos.config.url" oe:value="http://good.example.com"/>
  227. <Property oe:key="guestinfo.hostname" oe:value="test host"/>
  228. <Property oe:key="guestinfo.interface.0.name" oe:value="test name"/>
  229. <Property oe:key="guestinfo.interface.0.role" oe:value="public"/>
  230. <Property oe:key="guestinfo.interface.0.ip.0.address" oe:value="10.0.0.100/24"/>
  231. <Property oe:key="guestinfo.interface.0.ip.1.address" oe:value="10.0.0.101/24"/>
  232. <Property oe:key="guestinfo.interface.0.route.0.gateway" oe:value="10.0.0.1"/>
  233. <Property oe:key="guestinfo.interface.0.route.0.destination" oe:value="0.0.0.0"/>
  234. <Property oe:key="guestinfo.interface.1.mac" oe:value="test mac"/>
  235. <Property oe:key="guestinfo.interface.1.role" oe:value="private"/>
  236. <Property oe:key="guestinfo.interface.1.route.0.gateway" oe:value="10.0.0.2"/>
  237. <Property oe:key="guestinfo.interface.1.route.0.destination" oe:value="0.0.0.0"/>
  238. <Property oe:key="guestinfo.interface.1.ip.0.address" oe:value="10.0.0.102/24"/>
  239. </PropertySection>
  240. </Environment>`,
  241. metadata: datasource.Metadata{
  242. Hostname: "test host",
  243. PublicIPv4: net.ParseIP("10.0.0.101"),
  244. PrivateIPv4: net.ParseIP("10.0.0.102"),
  245. //NetworkConfig: map[string]string{
  246. // "interface.0.name": "test name",
  247. // "interface.0.ip.0.address": "10.0.0.100/24",
  248. // "interface.0.ip.1.address": "10.0.0.101/24",
  249. // "interface.0.route.0.gateway": "10.0.0.1",
  250. // "interface.0.route.0.destination": "0.0.0.0",
  251. // "interface.1.mac": "test mac",
  252. // "interface.1.route.0.gateway": "10.0.0.2",
  253. // "interface.1.route.0.destination": "0.0.0.0",
  254. // "interface.1.ip.0.address": "10.0.0.102/24",
  255. // },
  256. },
  257. userdata: []byte("test config"),
  258. },
  259. }
  260. for i, tt := range tests {
  261. file, err := ioutil.TempFile(os.TempDir(), "ovf")
  262. if err != nil {
  263. t.Errorf("error creating ovf file (#%d)", i)
  264. }
  265. defer os.Remove(file.Name())
  266. file.WriteString(tt.document)
  267. v := NewDatasource(file.Name())
  268. v.urlDownload = fakeDownloader
  269. metadata, err := v.FetchMetadata()
  270. userdata, err := v.FetchUserdata()
  271. if !reflect.DeepEqual(tt.metadata, metadata) {
  272. t.Errorf("bad metadata (#%d): want %#v, got %#v", i, tt.metadata, metadata)
  273. }
  274. if !reflect.DeepEqual(tt.userdata, userdata) {
  275. t.Errorf("bad userdata (#%d): want %#v, got %#v", i, tt.userdata, userdata)
  276. }
  277. }
  278. }