github.com/mirantis/virtlet@v1.5.2-0.20191204181327-1659b8a48e9b/pkg/blockdev/blockdev_test.go (about)

     1  /*
     2  Copyright 2018 Mirantis
     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  */
    16  
    17  package blockdev
    18  
    19  import (
    20  	"crypto/sha256"
    21  	"os"
    22  	"path/filepath"
    23  	"reflect"
    24  	"testing"
    25  
    26  	fake "github.com/Mirantis/virtlet/pkg/blockdev/fake"
    27  	"github.com/Mirantis/virtlet/pkg/utils"
    28  	fakeutils "github.com/Mirantis/virtlet/pkg/utils/fake"
    29  	testutils "github.com/Mirantis/virtlet/pkg/utils/testing"
    30  )
    31  
    32  func TestDevHeader(t *testing.T) {
    33  	for _, tc := range []struct {
    34  		name              string
    35  		content           []string
    36  		dmPath            string
    37  		fileSize          uint64
    38  		imageWrittenAgain bool
    39  		errors            [2]string
    40  	}{
    41  		{
    42  			name:     "image unchanged",
    43  			content:  []string{"image1", "image1"},
    44  			fileSize: 8704, // just added a sector
    45  		},
    46  		{
    47  			name:              "image change",
    48  			content:           []string{"image1", "image2"},
    49  			fileSize:          16384,
    50  			imageWrittenAgain: true,
    51  		},
    52  		{
    53  			name:     "first image too big",
    54  			content:  []string{"image1"},
    55  			fileSize: 4096,
    56  			errors: [2]string{
    57  				"too small",
    58  				"",
    59  			},
    60  		},
    61  		{
    62  			name:     "second image too big",
    63  			content:  []string{"image1", "image2"},
    64  			fileSize: 8704,
    65  			errors: [2]string{
    66  				"",
    67  				"too small",
    68  			},
    69  		},
    70  	} {
    71  		t.Run(tc.name, func(t *testing.T) {
    72  			fake.WithFakeRootDev(t, tc.fileSize, func(devPath, devDir string) {
    73  				for n, content := range tc.content {
    74  					if content == "" {
    75  						continue
    76  					}
    77  					cmd := fakeutils.NewCommander(nil, nil)
    78  
    79  					ldh := NewLogicalDeviceHandler(cmd, "", "")
    80  					headerExpectedToMatch := n > 0 && tc.content[n-1] == content
    81  					imageHash := sha256.Sum256([]byte(content))
    82  					headerMatches, err := ldh.EnsureDevHeaderMatches(devPath, imageHash)
    83  					if err != nil {
    84  						t.Fatalf("EnsureDevHeaderMatches: %v", err)
    85  					}
    86  
    87  					switch {
    88  					case headerMatches == headerExpectedToMatch:
    89  						// ok
    90  					case headerMatches:
    91  						t.Errorf("[%d] the header is expected to match but didn't", n)
    92  					case !headerMatches:
    93  						t.Errorf("[%d] the header is not expected to match but did", n)
    94  					}
    95  				}
    96  			})
    97  		})
    98  	}
    99  }
   100  
   101  func TestCreateRemoveVirtualBlockDevice(t *testing.T) {
   102  	fake.WithFakeRootDev(t, 0, func(devPath, devDir string) {
   103  		rec := testutils.NewToplevelRecorder()
   104  		cmd := fakeutils.NewCommander(rec, []fakeutils.CmdSpec{
   105  			{
   106  				Match:  "blockdev --getsz",
   107  				Stdout: "4",
   108  			},
   109  			{
   110  				Match: "dmsetup create",
   111  			},
   112  			{
   113  				Match: "dmsetup remove",
   114  			},
   115  		})
   116  		cmd.ReplaceTempPath("__dev__", "/dev")
   117  		symlinkPath := filepath.Join(devDir, "rootdevlink")
   118  		if err := os.Symlink(devPath, symlinkPath); err != nil {
   119  			t.Fatalf("Symlink(): %v", err)
   120  		}
   121  
   122  		ldh := NewLogicalDeviceHandler(cmd, "", "")
   123  		if err := ldh.Map(symlinkPath, "virtlet-dm-foobar", 1024); err != nil {
   124  			t.Fatalf("Map(): %v", err)
   125  		}
   126  		if err := ldh.Unmap("virtlet-dm-foobar"); err != nil {
   127  			t.Fatalf("Unmap(): %v", err)
   128  		}
   129  
   130  		expectedRecs := []*testutils.Record{
   131  			{
   132  				Name: "CMD",
   133  				Value: map[string]string{
   134  					"cmd":    "blockdev --getsz /dev/rootdevlink",
   135  					"stdout": "4",
   136  				},
   137  			},
   138  			{
   139  				Name: "CMD",
   140  				Value: map[string]string{
   141  					"cmd":   "dmsetup create virtlet-dm-foobar",
   142  					"stdin": "0 3 linear /dev/rootdev 1\n",
   143  				},
   144  			},
   145  			{
   146  				Name: "CMD",
   147  				Value: map[string]string{
   148  					"cmd": "dmsetup remove virtlet-dm-foobar",
   149  				},
   150  			},
   151  		}
   152  		if !reflect.DeepEqual(expectedRecs, rec.Content()) {
   153  			t.Errorf("bad commands recorded:\n%s\ninstead of\n%s", utils.ToJSON(rec.Content()), utils.ToJSON(expectedRecs))
   154  		}
   155  	})
   156  }
   157  
   158  func TestIsVirtletBlockDevice(t *testing.T) {
   159  	fake.WithFakeRootDevsAndSysfs(t, func(devPaths []string, table, devDir, sysfsDir string) {
   160  		cmd := fakeutils.NewCommander(nil, []fakeutils.CmdSpec{
   161  			{
   162  				Match:  "^dmsetup table$",
   163  				Stdout: table,
   164  			},
   165  		})
   166  		ldh := NewLogicalDeviceHandler(cmd, devDir, sysfsDir)
   167  		for _, devPath := range devPaths {
   168  			if _, err := ldh.EnsureDevHeaderMatches(devPath, sha256.Sum256([]byte("foobar"))); err != nil {
   169  				t.Fatalf("EnsureDevHeaderMatches(): %v", err)
   170  			}
   171  		}
   172  
   173  		devs, err := ldh.ListVirtletLogicalDevices()
   174  		if err != nil {
   175  			t.Fatalf("ListVirtletLogicalDevices(): %v", err)
   176  		}
   177  
   178  		expectedDevs := []string{
   179  			"virtlet-dm-5edfe2ad-9852-439b-bbfb-3fe8b7c72906",
   180  			"virtlet-dm-9a322047-1f0d-4395-8e43-6e1b310ce6f3",
   181  		}
   182  		if !reflect.DeepEqual(devs, expectedDevs) {
   183  			t.Errorf("bad Virtlet block device list: %s instead of %s", utils.ToJSONUnindented(devs), utils.ToJSONUnindented(expectedDevs))
   184  		}
   185  	})
   186  }