diskconfig_test.go 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package baremetal
  15. import (
  16. "encoding/json"
  17. "reflect"
  18. "testing"
  19. "github.com/stretchr/testify/assert"
  20. "yunion.io/x/jsonutils"
  21. "yunion.io/x/log"
  22. api "yunion.io/x/onecloud/pkg/apis/compute"
  23. )
  24. func TestParseDiskConfig(t *testing.T) {
  25. type args struct {
  26. desc string
  27. }
  28. var tAda int = 2
  29. var zAda int = 0
  30. var tStrip64k int64 = 64
  31. var splits40 string = "40%, "
  32. var splits100_32 string = "100g,32g,"
  33. tests := []struct {
  34. name string
  35. args args
  36. wantBdc api.BaremetalDiskConfig
  37. wantErr bool
  38. }{
  39. {
  40. name: "rotate:[1-2,4-5]:MegaRaid",
  41. args: args{"rotate:[1-2,4-5]:MegaRaid"},
  42. wantBdc: api.BaremetalDiskConfig{
  43. Type: DISK_TYPE_ROTATE,
  44. Conf: DISK_CONF_NONE,
  45. Driver: DISK_DRIVER_MEGARAID,
  46. Count: 0,
  47. Range: []int64{1, 2, 4, 5},
  48. },
  49. wantErr: false,
  50. },
  51. {
  52. name: "rotate:[1-2,4,6]:raid10:marvelraid",
  53. args: args{"rotate:[1-2,4,6]:raid10:marvelraid"},
  54. wantBdc: api.BaremetalDiskConfig{
  55. Type: DISK_TYPE_ROTATE,
  56. Conf: DISK_CONF_RAID10,
  57. Driver: DISK_DRIVER_MARVELRAID,
  58. Count: 0,
  59. Range: []int64{1, 2, 4, 6},
  60. },
  61. wantErr: false,
  62. },
  63. {
  64. name: "rotate:[4,6]:raid10",
  65. args: args{"rotate:[4,6]:raid10"},
  66. wantBdc: api.BaremetalDiskConfig{
  67. Type: DISK_TYPE_ROTATE,
  68. Conf: DISK_CONF_RAID10,
  69. Count: 0,
  70. Range: []int64{4, 6},
  71. },
  72. wantErr: false,
  73. },
  74. {
  75. name: "rotate:[4]:raid10:(40%, )",
  76. args: args{"rotate:[4]:raid10:(40%, )"},
  77. wantBdc: api.BaremetalDiskConfig{
  78. Type: DISK_TYPE_ROTATE,
  79. Conf: DISK_CONF_RAID10,
  80. Count: 0,
  81. Splits: splits40,
  82. Range: []int64{4},
  83. },
  84. wantErr: false,
  85. },
  86. {
  87. name: "[12-13]:raid1:(100g,32g,):adapter0:strip64k",
  88. args: args{"[12-13]:raid1:(100g,32g,):adapter0:strip64k"},
  89. wantBdc: api.BaremetalDiskConfig{
  90. Type: DISK_TYPE_HYBRID,
  91. Conf: DISK_CONF_RAID1,
  92. Count: 0,
  93. Splits: splits100_32,
  94. Adapter: &zAda,
  95. Strip: &tStrip64k,
  96. Range: []int64{12, 13},
  97. },
  98. wantErr: false,
  99. },
  100. {
  101. name: "6:raid5:adapter2",
  102. args: args{"6:raid5:adapter2"},
  103. wantBdc: api.BaremetalDiskConfig{
  104. Type: DISK_TYPE_HYBRID,
  105. Conf: DISK_CONF_RAID5,
  106. Count: 6,
  107. Adapter: &tAda,
  108. },
  109. wantErr: false,
  110. },
  111. }
  112. for _, tt := range tests {
  113. t.Run(tt.name, func(t *testing.T) {
  114. gotBdc, err := ParseDiskConfig(tt.args.desc)
  115. if (err != nil) != tt.wantErr {
  116. t.Errorf("ParseDiskConfig() error = %v, wantErr %v", err, tt.wantErr)
  117. return
  118. }
  119. if !reflect.DeepEqual(gotBdc, tt.wantBdc) {
  120. t.Errorf("ParseDiskConfig() = %v, want %v", gotBdc, tt.wantBdc)
  121. }
  122. })
  123. }
  124. }
  125. var (
  126. testStorages = []*BaremetalStorage{
  127. // 0-11 disk on adapter2
  128. {
  129. Driver: DISK_DRIVER_MEGARAID,
  130. Rotate: true,
  131. Size: 2861056,
  132. Adapter: 2,
  133. },
  134. {
  135. Driver: DISK_DRIVER_MEGARAID,
  136. Rotate: true,
  137. Size: 2861056,
  138. Adapter: 2,
  139. },
  140. {
  141. Driver: DISK_DRIVER_MEGARAID,
  142. Rotate: true,
  143. Size: 2861056,
  144. Adapter: 2,
  145. },
  146. {
  147. Driver: DISK_DRIVER_MEGARAID,
  148. Rotate: true,
  149. Size: 2861056,
  150. Adapter: 2,
  151. },
  152. {
  153. Driver: DISK_DRIVER_MEGARAID,
  154. Rotate: true,
  155. Size: 2861056,
  156. Adapter: 2,
  157. },
  158. {
  159. Driver: DISK_DRIVER_MEGARAID,
  160. Rotate: true,
  161. Size: 2861056,
  162. Adapter: 2,
  163. },
  164. {
  165. Driver: DISK_DRIVER_MEGARAID,
  166. Rotate: true,
  167. Size: 2861056,
  168. Adapter: 2,
  169. },
  170. {
  171. Driver: DISK_DRIVER_MEGARAID,
  172. Rotate: true,
  173. Size: 2861056,
  174. Adapter: 2,
  175. },
  176. {
  177. Driver: DISK_DRIVER_MEGARAID,
  178. Rotate: true,
  179. Size: 2861056,
  180. Adapter: 2,
  181. },
  182. {
  183. Driver: DISK_DRIVER_MEGARAID,
  184. Rotate: true,
  185. Size: 2861056,
  186. Adapter: 2,
  187. },
  188. {
  189. Driver: DISK_DRIVER_MEGARAID,
  190. Rotate: true,
  191. Size: 2861056,
  192. Adapter: 2,
  193. },
  194. {
  195. Driver: DISK_DRIVER_MEGARAID,
  196. Rotate: true,
  197. Size: 2861056,
  198. Adapter: 2,
  199. },
  200. // 0-1 disk on adapter0
  201. {
  202. Driver: DISK_DRIVER_MEGARAID,
  203. Rotate: true,
  204. Size: 953344,
  205. Adapter: 0,
  206. },
  207. {
  208. Driver: DISK_DRIVER_MEGARAID,
  209. Rotate: true,
  210. Size: 953344,
  211. Adapter: 0,
  212. },
  213. }
  214. bitmainStorage = []*BaremetalStorage{
  215. {
  216. Driver: DISK_DRIVER_MARVELRAID,
  217. Rotate: true,
  218. Size: 3814912,
  219. Adapter: 0,
  220. Enclosure: 252,
  221. MaxStripSize: 1024,
  222. MinStripSize: 64,
  223. Model: "K7GTE9JL HGST HUS726040ALE610 APGNT907",
  224. Slot: 0,
  225. Status: "online",
  226. },
  227. {
  228. Driver: DISK_DRIVER_MARVELRAID,
  229. Rotate: true,
  230. Size: 3814912,
  231. Adapter: 0,
  232. Enclosure: 252,
  233. MaxStripSize: 1024,
  234. MinStripSize: 64,
  235. Model: "K7GTE9JL HGST HUS726040ALE610 APGNT907",
  236. Slot: 1,
  237. Status: "online",
  238. },
  239. {
  240. Driver: DISK_DRIVER_MARVELRAID,
  241. Rotate: true,
  242. Size: 3814912,
  243. Adapter: 0,
  244. Enclosure: 252,
  245. MaxStripSize: 1024,
  246. MinStripSize: 64,
  247. Model: "K7GTE9JL HGST HUS726040ALE610 APGNT907",
  248. Slot: 2,
  249. Status: "online",
  250. },
  251. {
  252. Driver: DISK_DRIVER_MARVELRAID,
  253. Rotate: true,
  254. Size: 3814912,
  255. Adapter: 0,
  256. Enclosure: 252,
  257. MaxStripSize: 1024,
  258. MinStripSize: 64,
  259. Model: "K7GTE9JL HGST HUS726040ALE610 APGNT907",
  260. Slot: 3,
  261. Status: "online",
  262. },
  263. {
  264. Driver: DISK_DRIVER_PCIE,
  265. Rotate: true,
  266. Size: 2200000,
  267. Adapter: 0,
  268. Enclosure: 252,
  269. MaxStripSize: 1024,
  270. MinStripSize: 64,
  271. Model: "NVME test",
  272. Slot: 4,
  273. Status: "online",
  274. },
  275. {
  276. Driver: DISK_DRIVER_PCIE,
  277. Rotate: true,
  278. Size: 2200000,
  279. Adapter: 0,
  280. Enclosure: 252,
  281. MaxStripSize: 1024,
  282. MinStripSize: 64,
  283. Model: "NVME test",
  284. Slot: 5,
  285. Status: "online",
  286. },
  287. }
  288. )
  289. func TestCalculateLayout(t *testing.T) {
  290. confs, err := NewBaremetalDiskConfigs(
  291. "[0-1]:raid1:(100g,32g,):adapter0",
  292. "6:raid5:adapter2",
  293. "6:raid5:adapter2",
  294. )
  295. if err != nil {
  296. t.Fatalf("NewDiskConfigs err: %v", err)
  297. }
  298. expectedLayoutJson := `
  299. [
  300. {
  301. "disks": [
  302. {
  303. "rotate": true,
  304. "driver": "MegaRaid",
  305. "size": 953344,
  306. "index": 0
  307. },
  308. {
  309. "rotate": true,
  310. "driver": "MegaRaid",
  311. "size": 953344,
  312. "index": 1
  313. }
  314. ],
  315. "conf": {
  316. "type": "hybrid",
  317. "conf": "raid1",
  318. "count": 0,
  319. "range": [
  320. 0,
  321. 1
  322. ],
  323. "splits": "100g,32g,",
  324. "size": [
  325. 102400,
  326. 32768,
  327. 818176
  328. ],
  329. "adapter": 0,
  330. "driver": ""
  331. },
  332. "size": 953344
  333. },
  334. {
  335. "disks": [
  336. {
  337. "adapter": 2,
  338. "driver": "MegaRaid",
  339. "size": 2861056,
  340. "rotate": true,
  341. "index": 0
  342. },
  343. {
  344. "rotate": true,
  345. "adapter": 2,
  346. "driver": "MegaRaid",
  347. "size": 2861056,
  348. "index": 1
  349. },
  350. {
  351. "rotate": true,
  352. "adapter": 2,
  353. "driver": "MegaRaid",
  354. "size": 2861056,
  355. "index": 2
  356. },
  357. {
  358. "rotate": true,
  359. "adapter": 2,
  360. "driver": "MegaRaid",
  361. "size": 2861056,
  362. "index": 3
  363. },
  364. {
  365. "rotate": true,
  366. "adapter": 2,
  367. "driver": "MegaRaid",
  368. "size": 2861056,
  369. "index": 4
  370. },
  371. {
  372. "rotate": true,
  373. "adapter": 2,
  374. "driver": "MegaRaid",
  375. "size": 2861056,
  376. "index": 5
  377. }
  378. ],
  379. "conf": {
  380. "type": "hybrid",
  381. "conf": "raid5",
  382. "count": 6,
  383. "range": null,
  384. "splits": "",
  385. "size": null,
  386. "adapter": 2,
  387. "driver": ""
  388. },
  389. "size": 14305280
  390. },
  391. {
  392. "disks": [
  393. {
  394. "rotate": true,
  395. "adapter": 2,
  396. "driver": "MegaRaid",
  397. "size": 2861056,
  398. "index": 6
  399. },
  400. {
  401. "rotate": true,
  402. "adapter": 2,
  403. "driver": "MegaRaid",
  404. "size": 2861056,
  405. "index": 7
  406. },
  407. {
  408. "rotate": true,
  409. "adapter": 2,
  410. "driver": "MegaRaid",
  411. "size": 2861056,
  412. "index": 8
  413. },
  414. {
  415. "rotate": true,
  416. "adapter": 2,
  417. "driver": "MegaRaid",
  418. "size": 2861056,
  419. "index": 9
  420. },
  421. {
  422. "rotate": true,
  423. "adapter": 2,
  424. "driver": "MegaRaid",
  425. "size": 2861056,
  426. "index": 10
  427. },
  428. {
  429. "rotate": true,
  430. "adapter": 2,
  431. "driver": "MegaRaid",
  432. "size": 2861056,
  433. "index": 11
  434. }
  435. ],
  436. "conf": {
  437. "type": "hybrid",
  438. "conf": "raid5",
  439. "count": 6,
  440. "range": null,
  441. "splits": "",
  442. "size": null,
  443. "adapter": 2,
  444. "driver": ""
  445. },
  446. "size": 14305280
  447. }
  448. ]
  449. `
  450. layout, err := CalculateLayout(confs, testStorages)
  451. if err != nil {
  452. t.Fatalf("CalculateLayout err: %v", err)
  453. }
  454. var expectedLayout []Layout
  455. err = json.Unmarshal([]byte(expectedLayoutJson), &expectedLayout)
  456. if err != nil {
  457. t.Fatalf("Unmarshal expectedLayoutJson err: %v", err)
  458. }
  459. assert := assert.New(t)
  460. if !assert.Equal(expectedLayout, layout) {
  461. t.Errorf("CalculateLayout() = %v, want %v", layout, expectedLayout)
  462. }
  463. }
  464. func TestCalculateLayout2(t *testing.T) {
  465. adapater0 := 0
  466. confs := []*api.BaremetalDiskConfig{
  467. {
  468. Adapter: &adapater0,
  469. Conf: DISK_CONF_RAID1,
  470. Count: 2,
  471. Driver: DISK_DRIVER_MEGARAID,
  472. Range: []int64{12, 13},
  473. Type: DISK_TYPE_ROTATE,
  474. },
  475. {
  476. Adapter: &adapater0,
  477. Conf: DISK_CONF_RAID10,
  478. Count: 12,
  479. Driver: DISK_DRIVER_MEGARAID,
  480. Range: []int64{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11},
  481. Type: DISK_TYPE_ROTATE,
  482. },
  483. {
  484. Adapter: &adapater0,
  485. Conf: DISK_CONF_NONE,
  486. Count: 1,
  487. Driver: DISK_DRIVER_PCIE,
  488. Range: []int64{0},
  489. Type: DISK_TYPE_SSD,
  490. },
  491. }
  492. storages := []*BaremetalStorage{}
  493. storageJson := `[
  494. {
  495. "adapter": 0,
  496. "block": 512,
  497. "driver": "MegaRaid",
  498. "enclousure": 65,
  499. "index": 0,
  500. "max_strip_size": 0,
  501. "min_strip_size": 0,
  502. "model": "HGST HUS728T8TAL5200 A9Y2VY1A1JPM",
  503. "rotate": true,
  504. "sector": 15626993664,
  505. "size": 7630368,
  506. "slot": 0,
  507. "status": "unconfigured_good"
  508. },
  509. {
  510. "adapter": 0,
  511. "block": 512,
  512. "driver": "MegaRaid",
  513. "enclousure": 65,
  514. "index": 0,
  515. "max_strip_size": 0,
  516. "min_strip_size": 0,
  517. "model": "HGST HUS728T8TAL5200 A9Y2VY1AMGGM",
  518. "rotate": true,
  519. "sector": 15626993664,
  520. "size": 7630368,
  521. "slot": 1,
  522. "status": "unconfigured_good"
  523. },
  524. {
  525. "adapter": 0,
  526. "block": 512,
  527. "driver": "MegaRaid",
  528. "enclousure": 65,
  529. "index": 0,
  530. "max_strip_size": 0,
  531. "min_strip_size": 0,
  532. "model": "HGST HUS728T8TAL5200 A9Y2VY1AN53M",
  533. "rotate": true,
  534. "sector": 15626993664,
  535. "size": 7630368,
  536. "slot": 2,
  537. "status": "unconfigured_good"
  538. },
  539. {
  540. "adapter": 0,
  541. "block": 512,
  542. "driver": "MegaRaid",
  543. "enclousure": 65,
  544. "index": 0,
  545. "max_strip_size": 0,
  546. "min_strip_size": 0,
  547. "model": "HGST HUS728T8TAL5200 A9Y2VY1ATVBM",
  548. "rotate": true,
  549. "sector": 15626993664,
  550. "size": 7630368,
  551. "slot": 3,
  552. "status": "unconfigured_good"
  553. },
  554. {
  555. "adapter": 0,
  556. "block": 512,
  557. "driver": "MegaRaid",
  558. "enclousure": 65,
  559. "index": 0,
  560. "max_strip_size": 0,
  561. "min_strip_size": 0,
  562. "model": "HGST HUS728T8TAL5200 A9Y2VY1AR4VM",
  563. "rotate": true,
  564. "sector": 15626993664,
  565. "size": 7630368,
  566. "slot": 4,
  567. "status": "unconfigured_good"
  568. },
  569. {
  570. "adapter": 0,
  571. "block": 512,
  572. "driver": "MegaRaid",
  573. "enclousure": 65,
  574. "index": 0,
  575. "max_strip_size": 0,
  576. "min_strip_size": 0,
  577. "model": "HGST HUS728T8TAL5200 A9Y2VY1ARYBM",
  578. "rotate": true,
  579. "sector": 15626993664,
  580. "size": 7630368,
  581. "slot": 5,
  582. "status": "unconfigured_good"
  583. },
  584. {
  585. "adapter": 0,
  586. "block": 512,
  587. "driver": "MegaRaid",
  588. "enclousure": 65,
  589. "index": 0,
  590. "max_strip_size": 0,
  591. "min_strip_size": 0,
  592. "model": "HGST HUS728T8TAL5200 A9Y2VY1AS36M",
  593. "rotate": true,
  594. "sector": 15626993664,
  595. "size": 7630368,
  596. "slot": 6,
  597. "status": "unconfigured_good"
  598. },
  599. {
  600. "adapter": 0,
  601. "block": 512,
  602. "driver": "MegaRaid",
  603. "enclousure": 65,
  604. "index": 0,
  605. "max_strip_size": 0,
  606. "min_strip_size": 0,
  607. "model": "HGST HUS728T8TAL5200 A9Y2VY1A1K6M",
  608. "rotate": true,
  609. "sector": 15626993664,
  610. "size": 7630368,
  611. "slot": 7,
  612. "status": "unconfigured_good"
  613. },
  614. {
  615. "adapter": 0,
  616. "block": 512,
  617. "driver": "MegaRaid",
  618. "enclousure": 65,
  619. "index": 0,
  620. "max_strip_size": 0,
  621. "min_strip_size": 0,
  622. "model": "HGST HUS728T8TAL5200 A9Y2VY1AM98M",
  623. "rotate": true,
  624. "sector": 15626993664,
  625. "size": 7630368,
  626. "slot": 8,
  627. "status": "unconfigured_good"
  628. },
  629. {
  630. "adapter": 0,
  631. "block": 512,
  632. "driver": "MegaRaid",
  633. "enclousure": 65,
  634. "index": 0,
  635. "max_strip_size": 0,
  636. "min_strip_size": 0,
  637. "model": "HGST HUS728T8TAL5200 A9Y2VY1ATTLM",
  638. "rotate": true,
  639. "sector": 15626993664,
  640. "size": 7630368,
  641. "slot": 9,
  642. "status": "unconfigured_good"
  643. },
  644. {
  645. "adapter": 0,
  646. "block": 512,
  647. "driver": "MegaRaid",
  648. "enclousure": 65,
  649. "index": 0,
  650. "max_strip_size": 0,
  651. "min_strip_size": 0,
  652. "model": "HGST HUS728T8TAL5200 A9Y2VY1AR3DM",
  653. "rotate": true,
  654. "sector": 15626993664,
  655. "size": 7630368,
  656. "slot": 10,
  657. "status": "unconfigured_good"
  658. },
  659. {
  660. "adapter": 0,
  661. "block": 512,
  662. "driver": "MegaRaid",
  663. "enclousure": 65,
  664. "index": 0,
  665. "max_strip_size": 0,
  666. "min_strip_size": 0,
  667. "model": "HGST HUS728T8TAL5200 A9Y2VY1AN3DM",
  668. "rotate": true,
  669. "sector": 15626993664,
  670. "size": 7630368,
  671. "slot": 11,
  672. "status": "unconfigured_good"
  673. },
  674. {
  675. "adapter": 0,
  676. "block": 512,
  677. "driver": "MegaRaid",
  678. "enclousure": 65,
  679. "index": 0,
  680. "max_strip_size": 0,
  681. "min_strip_size": 0,
  682. "model": "TOSHIBA AL15SEB060N 310253K0A07BFYVH",
  683. "rotate": true,
  684. "sector": 1171062784,
  685. "size": 571808,
  686. "slot": 12,
  687. "status": "online"
  688. },
  689. {
  690. "adapter": 0,
  691. "block": 512,
  692. "driver": "MegaRaid",
  693. "enclousure": 65,
  694. "index": 0,
  695. "max_strip_size": 0,
  696. "min_strip_size": 0,
  697. "model": "TOSHIBA AL15SEB060N 310253K0A0EDFYVH",
  698. "rotate": true,
  699. "sector": 1171062784,
  700. "size": 571808,
  701. "slot": 13,
  702. "status": "online"
  703. },
  704. {
  705. "adapter": 0,
  706. "block": 512,
  707. "dev": "nvme0n1",
  708. "driver": "",
  709. "enclousure": 0,
  710. "index": 0,
  711. "kernel": "unknown",
  712. "max_strip_size": 0,
  713. "min_strip_size": 0,
  714. "module": "INSPUR-NS8600G2U640",
  715. "pci_class": "unknown",
  716. "rotate": false,
  717. "sector": 12502446768,
  718. "size": 6104710,
  719. "slot": 0
  720. }
  721. ]`
  722. storageObj, err := jsonutils.ParseString(storageJson)
  723. if err != nil {
  724. t.Fatalf("parse json error: %v", err)
  725. }
  726. if err := storageObj.Unmarshal(&storages); err != nil {
  727. t.Fatalf("unmarshal json to storages: %v", err)
  728. }
  729. layout, err := CalculateLayout(confs, storages)
  730. if err != nil {
  731. t.Fatalf("calculate layout: %v", err)
  732. }
  733. log.Infof("layout: %+v", layout)
  734. }
  735. func TestCheckDisksAllocable(t *testing.T) {
  736. confs, err := NewBaremetalDiskConfigs(
  737. "[0-1]:raid1:(100g,32g,):adapter0",
  738. "6:raid5:adapter2",
  739. "6:raid5:adapter2",
  740. )
  741. bitmainConfs, err := NewBaremetalDiskConfigs("MarvelRaid:raid10:(60g,)")
  742. if err != nil {
  743. t.Fatalf("NewDiskConfigs err: %v", err)
  744. }
  745. layout, err := CalculateLayout(confs, testStorages)
  746. defaultLayout, err := CalculateLayout([]*api.BaremetalDiskConfig{&BaremetalDefaultDiskConfig}, testStorages[12:])
  747. if err != nil {
  748. t.Fatalf("CalculateLayout err: %v", err)
  749. }
  750. bitmainLayout, err := CalculateLayout(bitmainConfs, bitmainStorage)
  751. if err != nil {
  752. t.Fatalf("Calculate bitmain layout err: %v", err)
  753. }
  754. tdiskDefault := []*api.DiskConfig{
  755. {SizeMb: -1},
  756. {SizeMb: -1},
  757. }
  758. tdisk1 := []*api.DiskConfig{
  759. {SizeMb: 960000},
  760. {SizeMb: -1},
  761. {SizeMb: -1},
  762. {SizeMb: -1},
  763. }
  764. tdisk2 := []*api.DiskConfig{
  765. {SizeMb: -1},
  766. {SizeMb: -1},
  767. {SizeMb: -1},
  768. {SizeMb: -1},
  769. }
  770. tdisk3 := []*api.DiskConfig{
  771. {SizeMb: 102398},
  772. {SizeMb: -1},
  773. {SizeMb: -1},
  774. {SizeMb: -1},
  775. }
  776. btdisk1 := []*api.DiskConfig{
  777. {SizeMb: 61438},
  778. {SizeMb: -1},
  779. }
  780. btdisk2 := []*api.DiskConfig{
  781. {SizeMb: 61440},
  782. {SizeMb: -1},
  783. }
  784. btdisk3 := []*api.DiskConfig{
  785. {SizeMb: -1},
  786. {SizeMb: -1},
  787. }
  788. btPcieDisk := []*api.DiskConfig{
  789. {SizeMb: 44440},
  790. {SizeMb: -1},
  791. {SizeMb: -1},
  792. {SizeMb: -1},
  793. {SizeMb: -1},
  794. }
  795. type args struct {
  796. layouts []Layout
  797. disks []*api.DiskConfig
  798. }
  799. tests := []struct {
  800. name string
  801. args args
  802. want bool
  803. extraCount int
  804. }{
  805. {
  806. name: "default none type config should allocable",
  807. args: args{
  808. layouts: defaultLayout,
  809. disks: tdiskDefault,
  810. },
  811. want: true,
  812. extraCount: 0,
  813. },
  814. {
  815. name: "should not allocable",
  816. args: args{
  817. layouts: layout,
  818. disks: tdisk1,
  819. },
  820. want: false,
  821. extraCount: 0,
  822. },
  823. {
  824. name: "should allocable",
  825. args: args{
  826. layouts: layout,
  827. disks: tdisk2,
  828. },
  829. want: true,
  830. extraCount: 1,
  831. },
  832. {
  833. name: "should allocable2",
  834. args: args{
  835. layouts: layout,
  836. disks: tdisk3,
  837. },
  838. want: true,
  839. extraCount: 1,
  840. },
  841. {
  842. name: "Bitmain allocable 61438 should true",
  843. args: args{
  844. layouts: bitmainLayout,
  845. disks: btdisk1,
  846. },
  847. want: true,
  848. extraCount: 2,
  849. },
  850. {
  851. name: "Bitmain allocable 61440 should false",
  852. args: args{
  853. layouts: bitmainLayout,
  854. disks: btdisk2,
  855. },
  856. want: false,
  857. extraCount: 0,
  858. },
  859. {
  860. name: "Bitmain allocable autoextend should true",
  861. args: args{
  862. layouts: bitmainLayout,
  863. disks: btdisk3,
  864. },
  865. want: true,
  866. extraCount: 2,
  867. },
  868. {
  869. name: "Bitmain allocable PCIE disk should true",
  870. args: args{
  871. layouts: bitmainLayout,
  872. disks: btPcieDisk,
  873. },
  874. want: true,
  875. extraCount: 0,
  876. },
  877. }
  878. for _, tt := range tests {
  879. t.Run(tt.name, func(t *testing.T) {
  880. if got, extraDisks := CheckDisksAllocable(tt.args.layouts, tt.args.disks); got != tt.want || len(extraDisks) != tt.extraCount {
  881. t.Errorf("CheckDisksAllocable() = %v, %d, want %v %d", got, len(extraDisks), tt.want, tt.extraCount)
  882. }
  883. })
  884. }
  885. }
  886. var testStorages2 string = `
  887. [
  888. {
  889. "adapter": 0,
  890. "driver": "MarvelRaid",
  891. "model": "SSDSCKJB120G7R",
  892. "rotate": true,
  893. "size": 114473,
  894. "slot": 0,
  895. "sn": "PHDW80440155150A"
  896. },
  897. {
  898. "adapter": 0,
  899. "driver": "MarvelRaid",
  900. "model": "SSDSCKJB120G7R",
  901. "rotate": true,
  902. "size": 114473,
  903. "slot": 1,
  904. "sn": "PHDW80440180150A"
  905. },
  906. {
  907. "adapter": 0,
  908. "driver": "MegaRaid",
  909. "enclosure": 64,
  910. "max_strip_size": 1024,
  911. "min_strip_size": 64,
  912. "model": "BTYM73040578960CGNSSDSC2KG960G7R SCV1DL56",
  913. "rotate": false,
  914. "size": 915200,
  915. "slot": 0,
  916. "status": "offline"
  917. },
  918. {
  919. "adapter": 0,
  920. "driver": "MegaRaid",
  921. "enclosure": 64,
  922. "max_strip_size": 1024,
  923. "min_strip_size": 64,
  924. "model": "BTYM73040566960CGNSSDSC2KG960G7R SCV1DL56",
  925. "rotate": false,
  926. "size": 915200,
  927. "slot": 1,
  928. "status": "offline"
  929. },
  930. {
  931. "adapter": 0,
  932. "driver": "MegaRaid",
  933. "enclosure": 64,
  934. "max_strip_size": 1024,
  935. "min_strip_size": 64,
  936. "model": "BTYM734403W7960CGNSSDSC2KG960G7R SCV1DL56",
  937. "rotate": false,
  938. "size": 915200,
  939. "slot": 2,
  940. "status": "offline"
  941. },
  942. {
  943. "adapter": 0,
  944. "driver": "MegaRaid",
  945. "enclosure": 64,
  946. "max_strip_size": 1024,
  947. "min_strip_size": 64,
  948. "model": "BTYM734600B1960CGNSSDSC2KG960G7R SCV1DL56",
  949. "rotate": false,
  950. "size": 915200,
  951. "slot": 3,
  952. "status": "offline"
  953. },
  954. {
  955. "adapter": 0,
  956. "driver": "MegaRaid",
  957. "enclosure": 64,
  958. "max_strip_size": 1024,
  959. "min_strip_size": 64,
  960. "model": "TOSHIBA AL14SEB18EQY EB012850A192FL7E",
  961. "rotate": true,
  962. "size": 1716352,
  963. "slot": 4,
  964. "status": "offline"
  965. },
  966. {
  967. "adapter": 0,
  968. "driver": "MegaRaid",
  969. "enclosure": 64,
  970. "max_strip_size": 1024,
  971. "min_strip_size": 64,
  972. "model": "TOSHIBA AL14SEB18EQY EB012850A1A4FL7E",
  973. "rotate": true,
  974. "size": 1716352,
  975. "slot": 5,
  976. "status": "offline"
  977. },
  978. {
  979. "adapter": 0,
  980. "driver": "MegaRaid",
  981. "enclosure": 64,
  982. "max_strip_size": 1024,
  983. "min_strip_size": 64,
  984. "model": "TOSHIBA AL14SEB18EQY EB012850A190FL7E",
  985. "rotate": true,
  986. "size": 1716352,
  987. "slot": 6,
  988. "status": "offline"
  989. },
  990. {
  991. "adapter": 0,
  992. "driver": "MegaRaid",
  993. "enclosure": 64,
  994. "max_strip_size": 1024,
  995. "min_strip_size": 64,
  996. "model": "TOSHIBA AL14SEB18EQY EB012850A15WFL7E",
  997. "rotate": true,
  998. "size": 1716352,
  999. "slot": 7,
  1000. "status": "offline"
  1001. },
  1002. {
  1003. "adapter": 0,
  1004. "driver": "MegaRaid",
  1005. "enclosure": 64,
  1006. "max_strip_size": 1024,
  1007. "min_strip_size": 64,
  1008. "model": "TOSHIBA AL14SEB18EQY EB012850A18CFL7E",
  1009. "rotate": true,
  1010. "size": 1716352,
  1011. "slot": 8,
  1012. "status": "offline"
  1013. },
  1014. {
  1015. "adapter": 0,
  1016. "driver": "MegaRaid",
  1017. "enclosure": 64,
  1018. "max_strip_size": 1024,
  1019. "min_strip_size": 64,
  1020. "model": "TOSHIBA AL14SEB18EQY EB012850A1ABFL7E",
  1021. "rotate": true,
  1022. "size": 1716352,
  1023. "slot": 9,
  1024. "status": "offline"
  1025. },
  1026. {
  1027. "adapter": 0,
  1028. "driver": "MegaRaid",
  1029. "enclosure": 64,
  1030. "max_strip_size": 1024,
  1031. "min_strip_size": 64,
  1032. "model": "TOSHIBA AL14SEB18EQY EB012850A1ACFL7E",
  1033. "rotate": true,
  1034. "size": 1716352,
  1035. "slot": 10,
  1036. "status": "offline"
  1037. },
  1038. {
  1039. "adapter": 0,
  1040. "driver": "MegaRaid",
  1041. "enclosure": 64,
  1042. "max_strip_size": 1024,
  1043. "min_strip_size": 64,
  1044. "model": "TOSHIBA AL14SEB18EQY EB012840A23VFL7E",
  1045. "rotate": true,
  1046. "size": 1716352,
  1047. "slot": 11,
  1048. "status": "offline"
  1049. },
  1050. {
  1051. "adapter": 0,
  1052. "driver": "MegaRaid",
  1053. "enclosure": 64,
  1054. "max_strip_size": 1024,
  1055. "min_strip_size": 64,
  1056. "model": "TOSHIBA AL14SEB18EQY EB012840A21SFL7E",
  1057. "rotate": true,
  1058. "size": 1716352,
  1059. "slot": 12,
  1060. "status": "offline"
  1061. },
  1062. {
  1063. "adapter": 0,
  1064. "driver": "MegaRaid",
  1065. "enclosure": 64,
  1066. "max_strip_size": 1024,
  1067. "min_strip_size": 64,
  1068. "model": "TOSHIBA AL14SEB18EQY EB012850A191FL7E",
  1069. "rotate": true,
  1070. "size": 1716352,
  1071. "slot": 13,
  1072. "status": "offline"
  1073. },
  1074. {
  1075. "adapter": 0,
  1076. "driver": "MegaRaid",
  1077. "enclosure": 64,
  1078. "max_strip_size": 1024,
  1079. "min_strip_size": 64,
  1080. "model": "TOSHIBA AL14SEB18EQY EB012850A15UFL7E",
  1081. "rotate": true,
  1082. "size": 1716352,
  1083. "slot": 14,
  1084. "status": "offline"
  1085. },
  1086. {
  1087. "adapter": 0,
  1088. "driver": "MegaRaid",
  1089. "enclosure": 64,
  1090. "max_strip_size": 1024,
  1091. "min_strip_size": 64,
  1092. "model": "TOSHIBA AL14SEB18EQY EB012840A23TFL7E",
  1093. "rotate": true,
  1094. "size": 1716352,
  1095. "slot": 15,
  1096. "status": "offline"
  1097. },
  1098. {
  1099. "adapter": 0,
  1100. "driver": "MegaRaid",
  1101. "enclosure": 64,
  1102. "max_strip_size": 1024,
  1103. "min_strip_size": 64,
  1104. "model": "TOSHIBA AL14SEB18EQY EB012850A13GFL7E",
  1105. "rotate": true,
  1106. "size": 1716352,
  1107. "slot": 16,
  1108. "status": "offline"
  1109. },
  1110. {
  1111. "adapter": 0,
  1112. "driver": "MegaRaid",
  1113. "enclosure": 64,
  1114. "max_strip_size": 1024,
  1115. "min_strip_size": 64,
  1116. "model": "TOSHIBA AL14SEB18EQY EB012850A13JFL7E",
  1117. "rotate": true,
  1118. "size": 1716352,
  1119. "slot": 17,
  1120. "status": "offline"
  1121. },
  1122. {
  1123. "adapter": 0,
  1124. "driver": "MegaRaid",
  1125. "enclosure": 64,
  1126. "max_strip_size": 1024,
  1127. "min_strip_size": 64,
  1128. "model": "TOSHIBA AL14SEB18EQY EB012850A19EFL7E",
  1129. "rotate": true,
  1130. "size": 1716352,
  1131. "slot": 18,
  1132. "status": "offline"
  1133. },
  1134. {
  1135. "adapter": 0,
  1136. "driver": "MegaRaid",
  1137. "enclosure": 64,
  1138. "max_strip_size": 1024,
  1139. "min_strip_size": 64,
  1140. "model": "TOSHIBA AL14SEB18EQY EB012850A19UFL7E",
  1141. "rotate": true,
  1142. "size": 1716352,
  1143. "slot": 19,
  1144. "status": "offline"
  1145. },
  1146. {
  1147. "adapter": 0,
  1148. "driver": "MegaRaid",
  1149. "enclosure": 64,
  1150. "max_strip_size": 1024,
  1151. "min_strip_size": 64,
  1152. "model": "TOSHIBA AL14SEB18EQY EB012850A1BSFL7E",
  1153. "rotate": true,
  1154. "size": 1716352,
  1155. "slot": 20,
  1156. "status": "offline"
  1157. },
  1158. {
  1159. "adapter": 0,
  1160. "driver": "MegaRaid",
  1161. "enclosure": 64,
  1162. "max_strip_size": 1024,
  1163. "min_strip_size": 64,
  1164. "model": "TOSHIBA AL14SEB18EQY EB012850A1B5FL7E",
  1165. "rotate": true,
  1166. "size": 1716352,
  1167. "slot": 21,
  1168. "status": "offline"
  1169. },
  1170. {
  1171. "adapter": 0,
  1172. "driver": "MegaRaid",
  1173. "enclosure": 64,
  1174. "max_strip_size": 1024,
  1175. "min_strip_size": 64,
  1176. "model": "TOSHIBA AL14SEB18EQY EB012850A16FFL7E",
  1177. "rotate": true,
  1178. "size": 1716352,
  1179. "slot": 22,
  1180. "status": "offline"
  1181. },
  1182. {
  1183. "adapter": 0,
  1184. "driver": "MegaRaid",
  1185. "enclosure": 64,
  1186. "max_strip_size": 1024,
  1187. "min_strip_size": 64,
  1188. "model": "TOSHIBA AL14SEB18EQY EB012850A165FL7E",
  1189. "rotate": true,
  1190. "size": 1716352,
  1191. "slot": 23,
  1192. "status": "offline"
  1193. }
  1194. ]
  1195. `
  1196. func TestStorageLoad(t *testing.T) {
  1197. ss := make([]*BaremetalStorage, 0)
  1198. confs, err := NewBaremetalDiskConfigs(
  1199. "2:raid1:MarvelRaid",
  1200. "4:raid10:MegaRaid",
  1201. "raid5",
  1202. )
  1203. if err != nil {
  1204. t.Fatalf("NewDiskConfigs err: %v", err)
  1205. }
  1206. json.Unmarshal([]byte(testStorages2), &ss)
  1207. _, err = CalculateLayout(confs, ss)
  1208. if err != nil {
  1209. t.Fatalf("CalculateLayout err: %v", err)
  1210. }
  1211. }
  1212. func TestCalculateSize(t *testing.T) {
  1213. type args struct {
  1214. conf string
  1215. storages []*BaremetalStorage
  1216. }
  1217. tests := []struct {
  1218. name string
  1219. args args
  1220. want int64
  1221. }{
  1222. {
  1223. name: "NoneRaid",
  1224. args: args{
  1225. conf: "",
  1226. storages: testStorages,
  1227. },
  1228. want: 2861056*12 + 953344*2,
  1229. },
  1230. {
  1231. name: "RAID1",
  1232. args: args{
  1233. conf: DISK_CONF_RAID1,
  1234. storages: testStorages,
  1235. },
  1236. want: 953344 * (12 + 2) / 2,
  1237. },
  1238. }
  1239. for _, tt := range tests {
  1240. t.Run(tt.name, func(t *testing.T) {
  1241. if got := CalculateSize(tt.args.conf, tt.args.storages); got != tt.want {
  1242. t.Errorf("CalculateSize() = %v, want %v", got, tt.want)
  1243. }
  1244. })
  1245. }
  1246. }
  1247. func TestGetDiskSpecs(t *testing.T) {
  1248. tests := []struct {
  1249. name string
  1250. storages []*BaremetalStorage
  1251. want []*api.DiskSpec
  1252. }{
  1253. {
  1254. name: "empty storage",
  1255. storages: []*BaremetalStorage{},
  1256. want: []*api.DiskSpec{},
  1257. },
  1258. {
  1259. name: "normal input",
  1260. storages: testStorages,
  1261. want: []*api.DiskSpec{
  1262. {
  1263. Type: HDD_DISK_SPEC_TYPE,
  1264. Size: 2861056,
  1265. StartIndex: 0,
  1266. EndIndex: 11,
  1267. Count: 12,
  1268. },
  1269. {
  1270. Type: HDD_DISK_SPEC_TYPE,
  1271. Size: 953344,
  1272. StartIndex: 12,
  1273. EndIndex: 13,
  1274. Count: 2,
  1275. },
  1276. },
  1277. },
  1278. {
  1279. name: "discontinuity check",
  1280. storages: []*BaremetalStorage{
  1281. {
  1282. Rotate: false,
  1283. Size: 30,
  1284. },
  1285. {
  1286. Rotate: true,
  1287. Size: 20,
  1288. },
  1289. {
  1290. Rotate: true,
  1291. Size: 20,
  1292. },
  1293. {
  1294. Rotate: false,
  1295. Size: 30,
  1296. },
  1297. },
  1298. want: []*api.DiskSpec{
  1299. {
  1300. Type: getStorageDiskType(false),
  1301. Size: 30,
  1302. StartIndex: 0,
  1303. EndIndex: 0,
  1304. Count: 1,
  1305. },
  1306. {
  1307. Type: getStorageDiskType(true),
  1308. Size: 20,
  1309. StartIndex: 1,
  1310. EndIndex: 2,
  1311. Count: 2,
  1312. },
  1313. {
  1314. Type: getStorageDiskType(false),
  1315. Size: 30,
  1316. StartIndex: 3,
  1317. EndIndex: 3,
  1318. Count: 1,
  1319. },
  1320. },
  1321. },
  1322. }
  1323. for _, tt := range tests {
  1324. t.Run(tt.name, func(t *testing.T) {
  1325. if got := GetDiskSpecs(tt.storages); !reflect.DeepEqual(got, tt.want) {
  1326. t.Errorf("GetDiskSpecs() = %v, want %v", got, tt.want)
  1327. }
  1328. })
  1329. }
  1330. }
  1331. func TestValidateDiskConfigs(t *testing.T) {
  1332. tests := []struct {
  1333. name string
  1334. confs []*api.BaremetalDiskConfig
  1335. wantErr bool
  1336. }{
  1337. {
  1338. name: "empty",
  1339. confs: []*api.BaremetalDiskConfig{},
  1340. wantErr: false,
  1341. },
  1342. {
  1343. name: "none_raid",
  1344. confs: []*api.BaremetalDiskConfig{
  1345. {Conf: DISK_CONF_NONE},
  1346. {Conf: DISK_CONF_RAID0},
  1347. },
  1348. wantErr: true,
  1349. },
  1350. {
  1351. name: "raid_none_raid",
  1352. confs: []*api.BaremetalDiskConfig{
  1353. {Conf: DISK_CONF_RAID0},
  1354. {Conf: DISK_CONF_NONE},
  1355. {Conf: DISK_CONF_RAID5},
  1356. },
  1357. wantErr: true,
  1358. },
  1359. {
  1360. name: "nones",
  1361. confs: []*api.BaremetalDiskConfig{
  1362. {Conf: DISK_CONF_NONE},
  1363. {Conf: DISK_CONF_NONE},
  1364. },
  1365. wantErr: false,
  1366. },
  1367. {
  1368. name: "raids_nones",
  1369. confs: []*api.BaremetalDiskConfig{
  1370. {Conf: DISK_CONF_RAID0},
  1371. {Conf: DISK_CONF_RAID5},
  1372. {Conf: DISK_CONF_NONE},
  1373. {Conf: DISK_CONF_NONE},
  1374. },
  1375. wantErr: false,
  1376. },
  1377. }
  1378. for _, tt := range tests {
  1379. t.Run(tt.name, func(t *testing.T) {
  1380. if err := ValidateDiskConfigs(tt.confs); (err != nil) != tt.wantErr {
  1381. t.Errorf("ValidateDiskConfigs() error = %v, wantErr %v", err, tt.wantErr)
  1382. }
  1383. })
  1384. }
  1385. }
  1386. func TestRetrieveStorages(t *testing.T) {
  1387. type args struct {
  1388. diskConfig *api.BaremetalDiskConfig
  1389. storages []*BaremetalStorage
  1390. }
  1391. s1 := &BaremetalStorage{
  1392. Size: 1,
  1393. Driver: "MegaRaid",
  1394. Adapter: 0,
  1395. }
  1396. s2 := &BaremetalStorage{
  1397. Size: 1,
  1398. Driver: "MegaRaid",
  1399. Adapter: 0,
  1400. }
  1401. s3 := &BaremetalStorage{
  1402. Size: 2,
  1403. Driver: "MegaRaid",
  1404. Adapter: 0,
  1405. }
  1406. tests := []struct {
  1407. name string
  1408. args args
  1409. wantSelected []*BaremetalStorage
  1410. wantRest []*BaremetalStorage
  1411. }{
  1412. {
  1413. name: "select all",
  1414. args: args{
  1415. diskConfig: &api.BaremetalDiskConfig{
  1416. Driver: "MegaRaid",
  1417. Count: 0,
  1418. Type: api.DISK_TYPE_HYBRID,
  1419. },
  1420. storages: []*BaremetalStorage{s1, s2, s3},
  1421. },
  1422. wantSelected: []*BaremetalStorage{s1, s2, s3},
  1423. wantRest: []*BaremetalStorage{},
  1424. },
  1425. {
  1426. name: "select count 2",
  1427. args: args{
  1428. diskConfig: &api.BaremetalDiskConfig{
  1429. Driver: "MegaRaid",
  1430. Count: 2,
  1431. Type: api.DISK_TYPE_HYBRID,
  1432. },
  1433. storages: []*BaremetalStorage{s1, s2, s3},
  1434. },
  1435. wantSelected: []*BaremetalStorage{s1, s2},
  1436. wantRest: []*BaremetalStorage{s3},
  1437. },
  1438. {
  1439. name: "select by range",
  1440. args: args{
  1441. diskConfig: &api.BaremetalDiskConfig{
  1442. Driver: "MegaRaid",
  1443. Range: []int64{1, 2},
  1444. Type: api.DISK_TYPE_HYBRID,
  1445. },
  1446. storages: []*BaremetalStorage{s1, s2, s3},
  1447. },
  1448. wantSelected: []*BaremetalStorage{s2, s3},
  1449. wantRest: []*BaremetalStorage{s1},
  1450. },
  1451. }
  1452. for _, tt := range tests {
  1453. t.Run(tt.name, func(t *testing.T) {
  1454. gotSelected, gotRest, err := RetrieveStorages(tt.args.diskConfig, tt.args.storages)
  1455. if !reflect.DeepEqual(gotSelected, tt.wantSelected) {
  1456. t.Errorf("RetrieveStorages() gotSelected = %v, want %v, err: %s", gotSelected, tt.wantSelected, err)
  1457. }
  1458. if !reflect.DeepEqual(gotRest, tt.wantRest) {
  1459. t.Errorf("RetrieveStorages() gotRest = %v, want %v, err: %s", gotRest, tt.wantRest, err)
  1460. }
  1461. })
  1462. }
  1463. }
  1464. func TestGetSplitSizes(t *testing.T) {
  1465. type args struct {
  1466. size int64
  1467. splitConf string
  1468. }
  1469. var totalSize int64 = 22889472
  1470. size10p := int64(float64(totalSize) * 0.1)
  1471. tests := []struct {
  1472. name string
  1473. args args
  1474. want []int64
  1475. }{
  1476. {
  1477. name: "split gb",
  1478. args: args{
  1479. size: totalSize,
  1480. splitConf: "60g,",
  1481. },
  1482. want: []int64{61440, totalSize - 61440},
  1483. },
  1484. {
  1485. name: "split by percent",
  1486. args: args{
  1487. size: totalSize,
  1488. splitConf: "10%,",
  1489. },
  1490. want: []int64{
  1491. size10p,
  1492. totalSize - size10p,
  1493. },
  1494. },
  1495. }
  1496. for _, tt := range tests {
  1497. t.Run(tt.name, func(t *testing.T) {
  1498. if got := GetSplitSizes(tt.args.size, tt.args.splitConf); !reflect.DeepEqual(got, tt.want) {
  1499. t.Errorf("GetSplitSizes() = %v, want %v", got, tt.want)
  1500. }
  1501. })
  1502. }
  1503. }
  1504. var (
  1505. pcieStorages = []*BaremetalStorage{
  1506. {
  1507. Driver: DISK_DRIVER_LINUX,
  1508. Rotate: true,
  1509. Size: 51200,
  1510. Adapter: 0,
  1511. Index: 0,
  1512. },
  1513. {
  1514. Driver: DISK_DRIVER_PCIE,
  1515. Rotate: false,
  1516. Size: 61440,
  1517. Adapter: 0,
  1518. Index: 0,
  1519. },
  1520. }
  1521. pcie2Storages = []*BaremetalStorage{
  1522. {
  1523. Driver: DISK_DRIVER_LINUX,
  1524. Dev: "sda",
  1525. Rotate: true,
  1526. Size: 3815447,
  1527. Adapter: 0,
  1528. Index: 0,
  1529. },
  1530. {
  1531. Driver: DISK_DRIVER_PCIE,
  1532. Dev: "nvme0n1",
  1533. Rotate: false,
  1534. Size: 1953514,
  1535. Adapter: 0,
  1536. Index: 0,
  1537. },
  1538. {
  1539. Driver: DISK_DRIVER_PCIE,
  1540. Dev: "nvme1n1",
  1541. Rotate: false,
  1542. Size: 122104,
  1543. Adapter: 0,
  1544. Index: 0,
  1545. },
  1546. }
  1547. )
  1548. func TestPCIEStoragesAllocable(t *testing.T) {
  1549. adapter0 := 0
  1550. confs := []*api.BaremetalDiskConfig{
  1551. {
  1552. Adapter: &adapter0,
  1553. Conf: DISK_CONF_NONE,
  1554. Count: 1,
  1555. Driver: DISK_DRIVER_PCIE,
  1556. Range: []int64{0},
  1557. Type: DISK_TYPE_SSD,
  1558. },
  1559. {
  1560. Adapter: &adapter0,
  1561. Conf: DISK_CONF_NONE,
  1562. Count: 1,
  1563. Driver: DISK_DRIVER_LINUX,
  1564. Range: []int64{0},
  1565. Type: DISK_TYPE_ROTATE,
  1566. },
  1567. }
  1568. layouts, err := CalculateLayout(confs, pcieStorages)
  1569. if err != nil {
  1570. t.Errorf("CalculateLayout error: %v", err)
  1571. return
  1572. }
  1573. // log.Errorf("layouts: %s", jsonutils.Marshal(layouts))
  1574. disks := []*api.DiskConfig{
  1575. {
  1576. Backend: api.STORAGE_LOCAL,
  1577. Driver: "scsi",
  1578. SizeMb: 30720,
  1579. },
  1580. {
  1581. Backend: api.STORAGE_LOCAL,
  1582. Driver: "scsi",
  1583. Fs: "ext4",
  1584. Mountpoint: "/opt",
  1585. SizeMb: -1,
  1586. },
  1587. {
  1588. Backend: api.STORAGE_LOCAL,
  1589. Driver: "scsi",
  1590. Fs: "ext4",
  1591. Mountpoint: "/data",
  1592. SizeMb: -1,
  1593. },
  1594. }
  1595. if ok := IsDisksAllocable(layouts, disks); !ok {
  1596. t.Errorf("Disk not allocable")
  1597. }
  1598. }
  1599. func Test2PCIEStoragesAllocable(t *testing.T) {
  1600. adapter0 := 0
  1601. confs := []*api.BaremetalDiskConfig{
  1602. {
  1603. Adapter: &adapter0,
  1604. Conf: DISK_CONF_NONE,
  1605. Count: 0,
  1606. Driver: DISK_DRIVER_PCIE,
  1607. Range: []int64{1},
  1608. Type: DISK_TYPE_SSD,
  1609. },
  1610. }
  1611. layouts, err := CalculateLayout(confs, pcie2Storages)
  1612. if err != nil {
  1613. t.Errorf("CalculateLayout error: %v", err)
  1614. return
  1615. }
  1616. log.Errorf("layouts: %s", jsonutils.Marshal(layouts))
  1617. disks := []*api.DiskConfig{
  1618. {
  1619. Backend: api.STORAGE_LOCAL,
  1620. Driver: "scsi",
  1621. SizeMb: -1,
  1622. },
  1623. }
  1624. if ok := IsDisksAllocable(layouts, disks); !ok {
  1625. t.Errorf("Disk not allocable")
  1626. }
  1627. }