~allenap/maas/xxx-a-thon

« back to all changes in this revision

Viewing changes to src/maasserver/tests/test_storage_layouts.py

  • Committer: Gavin Panella
  • Date: 2016-03-22 21:14:34 UTC
  • mfrom: (4657.1.157 maas)
  • Revision ID: gavin.panella@canonical.com-20160322211434-xzuovio86zvzo2js
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2015 Canonical Ltd.  This software is licensed under the
 
1
# Copyright 2015-2016 Canonical Ltd.  This software is licensed under the
2
2
# GNU Affero General Public License version 3 (see the file LICENSE).
3
3
 
4
4
"""Test the storage layouts."""
20
20
    MAX_PARTITION_SIZE_FOR_MBR,
21
21
    PARTITION_ALIGNMENT_SIZE,
22
22
)
23
 
from maasserver.models.partitiontable import PARTITION_TABLE_EXTRA_SPACE
 
23
from maasserver.models.partitiontable import (
 
24
    PARTITION_TABLE_EXTRA_SPACE,
 
25
    PREP_PARTITION_SIZE,
 
26
)
24
27
from maasserver.storage_layouts import (
25
28
    BcacheStorageLayout,
26
29
    BcacheStorageLayoutBase,
27
 
    calculate_size_from_precentage,
 
30
    calculate_size_from_percentage,
28
31
    EFI_PARTITION_SIZE,
29
32
    FlatStorageLayout,
30
33
    get_storage_layout_choices,
31
34
    get_storage_layout_for_node,
32
 
    is_precentage,
 
35
    is_percentage,
33
36
    LVMStorageLayout,
34
37
    MIN_BOOT_PARTITION_SIZE,
35
38
    MIN_ROOT_PARTITION_SIZE,
54
57
    return factory.make_Node(*args, **kwargs)
55
58
 
56
59
 
 
60
def make_ppc64el_Node_with_powernv_boot_method(*args, **kwargs):
 
61
    kwargs['bios_boot_method'] = "powernv"
 
62
    kwargs['with_boot_disk'] = False
 
63
    kwargs['architecture'] = "ppc64el/generic"
 
64
    return factory.make_Node(*args, **kwargs)
 
65
 
 
66
 
 
67
def make_ppc64el_Node_with_uefi_boot_method(*args, **kwargs):
 
68
    kwargs['bios_boot_method'] = "powerkvm"
 
69
    kwargs['with_boot_disk'] = False
 
70
    kwargs['architecture'] = "ppc64el/generic"
 
71
    return factory.make_Node(*args, **kwargs)
 
72
 
 
73
 
 
74
def make_arm64_Node_without_uefi_boot_method(*args, **kwargs):
 
75
    kwargs['bios_boot_method'] = "pxe"
 
76
    kwargs['with_boot_disk'] = False
 
77
    kwargs['architecture'] = "arm64/generic"
 
78
    return factory.make_Node(*args, **kwargs)
 
79
 
 
80
 
57
81
class TestFormHelpers(MAASServerTestCase):
58
82
 
59
83
    def test_get_storage_layout_choices(self):
84
108
            }, form.errors)
85
109
 
86
110
 
87
 
class TestIsPrecentageHelper(MAASServerTestCase):
88
 
    """Tests for `is_precentage`."""
 
111
class TestIsPercentageHelper(MAASServerTestCase):
 
112
    """Tests for `is_percentage`."""
89
113
 
90
114
    scenarios = [
91
115
        ('100%', {
92
116
            'value': '100%',
93
 
            'is_precentage': True,
 
117
            'is_percentage': True,
94
118
            }),
95
119
        ('10%', {
96
120
            'value': '10%',
97
 
            'is_precentage': True,
 
121
            'is_percentage': True,
98
122
            }),
99
123
        ('1.5%', {
100
124
            'value': '1.5%',
101
 
            'is_precentage': True,
 
125
            'is_percentage': True,
102
126
            }),
103
127
        ('1000.42%', {
104
128
            'value': '1000.42%',
105
 
            'is_precentage': True,
 
129
            'is_percentage': True,
106
130
            }),
107
131
        ('0.816112383915%', {
108
132
            'value': '0.816112383915%',
109
 
            'is_precentage': True,
 
133
            'is_percentage': True,
110
134
            }),
111
135
        ('1000', {
112
136
            'value': '1000',
113
 
            'is_precentage': False,
 
137
            'is_percentage': False,
114
138
            }),
115
139
        ('10', {
116
140
            'value': '10',
117
 
            'is_precentage': False,
 
141
            'is_percentage': False,
118
142
            }),
119
143
        ('0', {
120
144
            'value': '0',
121
 
            'is_precentage': False,
 
145
            'is_percentage': False,
122
146
            }),
123
147
        ('int(0)', {
124
148
            'value': 0,
125
 
            'is_precentage': False,
 
149
            'is_percentage': False,
126
150
            }),
127
151
    ]
128
152
 
129
153
    def test__returns_correct_result(self):
130
154
        self.assertEqual(
131
 
            self.is_precentage, is_precentage(self.value),
 
155
            self.is_percentage, is_percentage(self.value),
132
156
            "%s gave incorrect result." % self.value)
133
157
 
134
158
 
135
 
class TestCalculateSizeFromPrecentHelper(MAASServerTestCase):
136
 
    """Tests for `calculate_size_from_precentage`."""
 
159
class TestCalculateSizeFromPercentHelper(MAASServerTestCase):
 
160
    """Tests for `calculate_size_from_percentage`."""
137
161
 
138
162
    scenarios = [
139
163
        ('100%', {
140
164
            'input': 10000,
141
 
            'precent': '100%',
 
165
            'percent': '100%',
142
166
            'output': 10000,
143
167
            }),
144
168
        ('10%', {
145
169
            'input': 10000,
146
 
            'precent': '10%',
 
170
            'percent': '10%',
147
171
            'output': 1000,
148
172
            }),
149
173
        ('1%', {
150
174
            'input': 10000,
151
 
            'precent': '1%',
 
175
            'percent': '1%',
152
176
            'output': 100,
153
177
            }),
154
178
        ('5%', {
155
179
            'input': 4096,
156
 
            'precent': '5%',
 
180
            'percent': '5%',
157
181
            'output': int(ceil(4096 * .05)),
158
182
            }),
159
183
        ('0.816112383915%', {
160
184
            'input': 4096,
161
 
            'precent': '0.816112383915%',
 
185
            'percent': '0.816112383915%',
162
186
            'output': int(ceil(4096 * 0.00816112383915)),
163
187
            }),
164
188
    ]
166
190
    def test__returns_correct_result(self):
167
191
        self.assertEqual(
168
192
            self.output,
169
 
            calculate_size_from_precentage(self.input, self.precent),
170
 
            "%s gave incorrect result." % self.precent)
 
193
            calculate_size_from_percentage(self.input, self.percent),
 
194
            "%s gave incorrect result." % self.percent)
171
195
 
172
196
 
173
197
class TestStorageLayoutBase(MAASServerTestCase):
196
220
            "Node doesn't have any storage devices to configure.",
197
221
            str(error))
198
222
 
199
 
    def test_raises_error_when_precentage_to_low_for_boot_disk(self):
 
223
    def test_raises_error_when_percentage_to_low_for_boot_disk(self):
200
224
        node = make_Node_with_uefi_boot_method()
201
225
        factory.make_PhysicalBlockDevice(
202
226
            node=node, size=LARGE_BLOCK_DEVICE)
224
248
                    MIN_BOOT_PARTITION_SIZE)],
225
249
            }, error.message_dict)
226
250
 
227
 
    def test_raises_error_when_precentage_to_high_for_boot_disk(self):
 
251
    def test_raises_error_when_percentage_to_high_for_boot_disk(self):
228
252
        node = make_Node_with_uefi_boot_method()
229
253
        boot_disk = factory.make_PhysicalBlockDevice(
230
254
            node=node, size=LARGE_BLOCK_DEVICE)
231
255
        max_size = (
232
256
            boot_disk.size - EFI_PARTITION_SIZE - MIN_ROOT_PARTITION_SIZE)
233
 
        to_high_precent = max_size / float(boot_disk.size)
234
 
        to_high_precent = "%s%%" % ((to_high_precent + 1) * 100)
 
257
        to_high_percent = max_size / float(boot_disk.size)
 
258
        to_high_percent = "%s%%" % ((to_high_percent + 1) * 100)
235
259
        layout = StorageLayoutBase(node, {
236
 
            'boot_size': to_high_precent,
 
260
            'boot_size': to_high_percent,
237
261
            })
238
262
        error = self.assertRaises(StorageLayoutFieldsError, layout.configure)
239
263
        self.assertEqual({
256
280
                "Size is too large. Maximum size is %s." % max_size],
257
281
            }, error.message_dict)
258
282
 
259
 
    def test_raises_error_when_precentage_to_low_for_root_disk(self):
 
283
    def test_raises_error_when_percentage_to_low_for_root_disk(self):
260
284
        node = make_Node_with_uefi_boot_method()
261
285
        factory.make_PhysicalBlockDevice(
262
286
            node=node, size=LARGE_BLOCK_DEVICE)
284
308
                    MIN_ROOT_PARTITION_SIZE)],
285
309
            }, error.message_dict)
286
310
 
287
 
    def test_raises_error_when_precentage_to_high_for_root_disk(self):
 
311
    def test_raises_error_when_percentage_to_high_for_root_disk(self):
288
312
        node = make_Node_with_uefi_boot_method()
289
313
        boot_disk = factory.make_PhysicalBlockDevice(
290
314
            node=node, size=LARGE_BLOCK_DEVICE)
291
315
        max_size = (
292
316
            boot_disk.size - EFI_PARTITION_SIZE - MIN_BOOT_PARTITION_SIZE)
293
 
        to_high_precent = max_size / float(boot_disk.size)
294
 
        to_high_precent = "%s%%" % ((to_high_precent + 1) * 100)
 
317
        to_high_percent = max_size / float(boot_disk.size)
 
318
        to_high_percent = "%s%%" % ((to_high_percent + 1) * 100)
295
319
        layout = StorageLayoutBase(node, {
296
 
            'root_size': to_high_precent,
 
320
            'root_size': to_high_percent,
297
321
            })
298
322
        error = self.assertRaises(StorageLayoutFieldsError, layout.configure)
299
323
        self.assertEqual({
505
529
                mount_point="/",
506
530
                ))
507
531
 
 
532
    def test__creates_layout_for_powernv(self):
 
533
        node = make_ppc64el_Node_with_powernv_boot_method()
 
534
        boot_disk = factory.make_PhysicalBlockDevice(
 
535
            node=node, size=LARGE_BLOCK_DEVICE)
 
536
        layout = FlatStorageLayout(node)
 
537
        layout.configure()
 
538
 
 
539
        # Validate partition table.
 
540
        partition_table = boot_disk.get_partitiontable()
 
541
        self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
 
542
 
 
543
        # Validate root partition.
 
544
        partitions = partition_table.partitions.order_by('id').all()
 
545
        root_partition = partitions[0]
 
546
        self.assertIsNotNone(root_partition)
 
547
        self.assertEqual(
 
548
            round_size_to_nearest_block(
 
549
                boot_disk.size - PARTITION_TABLE_EXTRA_SPACE -
 
550
                PREP_PARTITION_SIZE,
 
551
                PARTITION_ALIGNMENT_SIZE,
 
552
                False),
 
553
            root_partition.size)
 
554
        self.assertThat(
 
555
            root_partition.get_effective_filesystem(),
 
556
            MatchesStructure.byEquality(
 
557
                fstype=FILESYSTEM_TYPE.EXT4,
 
558
                label="root",
 
559
                mount_point="/",
 
560
                ))
 
561
 
 
562
    def test__creates_layout_for_powerkvm(self):
 
563
        node = make_ppc64el_Node_with_uefi_boot_method()
 
564
        boot_disk = factory.make_PhysicalBlockDevice(
 
565
            node=node, size=LARGE_BLOCK_DEVICE)
 
566
        layout = FlatStorageLayout(node)
 
567
        layout.configure()
 
568
 
 
569
        # Validate partition table.
 
570
        partition_table = boot_disk.get_partitiontable()
 
571
        self.assertEqual(PARTITION_TABLE_TYPE.GPT, partition_table.table_type)
 
572
 
 
573
        # Validate root partition.
 
574
        partitions = partition_table.partitions.order_by('id').all()
 
575
        root_partition = partitions[0]
 
576
        self.assertIsNotNone(root_partition)
 
577
        self.assertEqual(
 
578
            round_size_to_nearest_block(
 
579
                boot_disk.size - PARTITION_TABLE_EXTRA_SPACE -
 
580
                PREP_PARTITION_SIZE,
 
581
                PARTITION_ALIGNMENT_SIZE,
 
582
                False),
 
583
            root_partition.size)
 
584
        self.assertThat(
 
585
            root_partition.get_effective_filesystem(),
 
586
            MatchesStructure.byEquality(
 
587
                fstype=FILESYSTEM_TYPE.EXT4,
 
588
                label="root",
 
589
                mount_point="/",
 
590
                ))
 
591
 
508
592
    def test__creates_layout_with_uefi_defaults(self):
509
593
        node = make_Node_with_uefi_boot_method()
510
594
        boot_disk = factory.make_PhysicalBlockDevice(
539
623
                mount_point="/",
540
624
                ))
541
625
 
 
626
    def test__creates_layout_for_arm64(self):
 
627
        node = make_arm64_Node_without_uefi_boot_method()
 
628
        boot_disk = factory.make_PhysicalBlockDevice(
 
629
            node=node, size=LARGE_BLOCK_DEVICE)
 
630
        layout = FlatStorageLayout(node)
 
631
        layout.configure()
 
632
 
 
633
        # Validate partition table.
 
634
        partition_table = boot_disk.get_partitiontable()
 
635
        self.assertEqual(PARTITION_TABLE_TYPE.MBR, partition_table.table_type)
 
636
 
 
637
        # Validate boot partition.
 
638
        partitions = partition_table.partitions.order_by('id').all()
 
639
        boot_partition = partitions[0]
 
640
        self.assertIsNotNone(boot_partition)
 
641
        self.assertEqual(
 
642
            round_size_to_nearest_block(
 
643
                MIN_BOOT_PARTITION_SIZE, PARTITION_ALIGNMENT_SIZE, False),
 
644
            boot_partition.size)
 
645
        self.assertThat(
 
646
            boot_partition.get_effective_filesystem(),
 
647
            MatchesStructure.byEquality(
 
648
                fstype=FILESYSTEM_TYPE.EXT4,
 
649
                label="boot",
 
650
                mount_point="/boot",
 
651
            ))
 
652
 
 
653
        # Validate root partition.
 
654
        root_partition = partitions[1]
 
655
        self.assertIsNotNone(root_partition)
 
656
        self.assertEqual(
 
657
            round_size_to_nearest_block(
 
658
                boot_disk.size - EFI_PARTITION_SIZE -
 
659
                PARTITION_TABLE_EXTRA_SPACE,
 
660
                PARTITION_ALIGNMENT_SIZE,
 
661
                False),
 
662
            root_partition.size)
 
663
        self.assertThat(
 
664
            root_partition.get_effective_filesystem(),
 
665
            MatchesStructure.byEquality(
 
666
                fstype=FILESYSTEM_TYPE.EXT4,
 
667
                label="root",
 
668
                mount_point="/",
 
669
            ))
 
670
 
542
671
    def test__creates_layout_with_boot_size(self):
543
672
        node = make_Node_with_uefi_boot_method()
544
673
        boot_disk = factory.make_PhysicalBlockDevice(
826
955
            volume_group.get_size(),
827
956
            layout.get_calculated_lv_size(volume_group))
828
957
 
829
 
    def test_raises_error_when_precentage_to_low_for_logical_volume(self):
 
958
    def test_raises_error_when_percentage_to_low_for_logical_volume(self):
830
959
        node = make_Node_with_uefi_boot_method()
831
960
        factory.make_PhysicalBlockDevice(
832
961
            node=node, size=LARGE_BLOCK_DEVICE)
854
983
                    MIN_ROOT_PARTITION_SIZE)],
855
984
            }, error.message_dict)
856
985
 
857
 
    def test_raises_error_when_precentage_to_high_for_logical_volume(self):
 
986
    def test_raises_error_when_percentage_to_high_for_logical_volume(self):
858
987
        node = make_Node_with_uefi_boot_method()
859
988
        factory.make_PhysicalBlockDevice(
860
989
            node=node, size=LARGE_BLOCK_DEVICE)
1238
1367
            },
1239
1368
            layout.errors)
1240
1369
 
1241
 
    def test_raises_error_when_precentage_to_low_for_cache_size(self):
 
1370
    def test_raises_error_when_percentage_to_low_for_cache_size(self):
1242
1371
        node = make_Node_with_uefi_boot_method()
1243
1372
        factory.make_PhysicalBlockDevice(
1244
1373
            node=node, size=LARGE_BLOCK_DEVICE)
1272
1401
                    MIN_BLOCK_DEVICE_SIZE)],
1273
1402
            }, error.message_dict)
1274
1403
 
1275
 
    def test_raises_error_when_precentage_to_high_for_cache_size(self):
 
1404
    def test_raises_error_when_percentage_to_high_for_cache_size(self):
1276
1405
        node = make_Node_with_uefi_boot_method()
1277
1406
        factory.make_PhysicalBlockDevice(
1278
1407
            node=node, size=LARGE_BLOCK_DEVICE)