github.com/coreos/rocket@v1.30.1-0.20200224141603-171c416fac02/rkt/image/common_test.go (about)

     1  // Copyright 2015 The rkt Authors
     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  
    15  package image
    16  
    17  import (
    18  	"fmt"
    19  	"net/url"
    20  	"path/filepath"
    21  	"testing"
    22  	"time"
    23  
    24  	dist "github.com/rkt/rkt/pkg/distribution"
    25  )
    26  
    27  func TestGuessAppcOrPath(t *testing.T) {
    28  	tests := []struct {
    29  		image        string
    30  		expectedType imageStringType
    31  	}{
    32  		// guess obvious absolute path as a path
    33  		{
    34  			image:        "/usr/libexec/rkt/stage1.aci",
    35  			expectedType: imageStringPath,
    36  		},
    37  		// guess stuff with colon as a name
    38  		{
    39  			image:        "example.com/stage1:1.2.3",
    40  			expectedType: imageStringName,
    41  		},
    42  		// guess stuff with ./ as a path
    43  		{
    44  			image:        "some/relative/../path/with/dots/file",
    45  			expectedType: imageStringPath,
    46  		},
    47  		// the same
    48  		{
    49  			image:        "./another/obviously/relative/path",
    50  			expectedType: imageStringPath,
    51  		},
    52  		// guess stuff ending with .aci as a path
    53  		{
    54  			image:        "some/relative/path/with/aci/extension.aci",
    55  			expectedType: imageStringPath,
    56  		},
    57  		// guess stuff without .aci, ./ and : as a name
    58  		{
    59  			image:        "example.com/stage1",
    60  			expectedType: imageStringName,
    61  		},
    62  		// another try
    63  		{
    64  			image:        "example.com/stage1,version=1.2.3,foo=bar",
    65  			expectedType: imageStringName,
    66  		},
    67  	}
    68  	for _, tt := range tests {
    69  		guessed := guessAppcOrPath(tt.image, []string{".aci"})
    70  		if tt.expectedType != guessed {
    71  			t.Errorf("expected %q to be guessed as %q, but got %q", tt.image, imageTypeToString(tt.expectedType), imageTypeToString(guessed))
    72  		}
    73  	}
    74  }
    75  
    76  func imageTypeToString(imType imageStringType) string {
    77  	switch imType {
    78  	case imageStringName:
    79  		return "name"
    80  	case imageStringPath:
    81  		return "path"
    82  	default:
    83  		return "unknown"
    84  	}
    85  }
    86  
    87  func TestSignatureURLFromImageURL(t *testing.T) {
    88  	tests := []struct {
    89  		i string
    90  		s string
    91  	}{
    92  		{
    93  			i: "http://example.com/image",
    94  			s: "http://example.com/image.aci.asc",
    95  		},
    96  		{
    97  			i: "http://example.com/image.aci",
    98  			s: "http://example.com/image.aci.asc",
    99  		},
   100  		{
   101  			i: "http://example.com/image.aci?foo=bar&baz=quux#blah",
   102  			s: "http://example.com/image.aci.asc?foo=bar&baz=quux#blah",
   103  		},
   104  	}
   105  	for _, tt := range tests {
   106  		iu, err := url.Parse(tt.i)
   107  		if err != nil {
   108  			t.Errorf("failed to parse %q as an image URL: %v", tt.i, err)
   109  			continue
   110  		}
   111  		su, err := url.Parse(tt.s)
   112  		if err != nil {
   113  			t.Errorf("failed to parse %q as a signature URL: %v", tt.s, err)
   114  			continue
   115  		}
   116  		got := ascURLFromImgURL(iu)
   117  		if su.String() != got.String() {
   118  			t.Errorf("expected signature URL for image URL %q to be %q, but got %q", iu.String(), su.String(), got.String())
   119  		}
   120  	}
   121  }
   122  
   123  func TestSignaturePathFromImagePath(t *testing.T) {
   124  	tests := []struct {
   125  		i string
   126  		s string
   127  	}{
   128  		{
   129  			i: "/some/path/to/image",
   130  			s: "/some/path/to/image.aci.asc",
   131  		},
   132  		{
   133  			i: "/some/path/to/image.aci",
   134  			s: "/some/path/to/image.aci.asc",
   135  		},
   136  	}
   137  	for _, tt := range tests {
   138  		got := ascPathFromImgPath(tt.i)
   139  		if tt.s != got {
   140  			t.Errorf("expected signature path for image path %q to be %q, but got %q", tt.i, tt.s, got)
   141  		}
   142  	}
   143  }
   144  
   145  func TestUseCached(t *testing.T) {
   146  	tests := []struct {
   147  		age int
   148  		use bool
   149  	}{
   150  		{
   151  			age: -11,
   152  			use: false,
   153  		},
   154  		{
   155  			age: -1,
   156  			use: true,
   157  		},
   158  	}
   159  	maxAge := 10
   160  	for _, tt := range tests {
   161  		age := time.Now().Add(time.Duration(tt.age) * time.Second)
   162  		got := useCached(age, maxAge)
   163  		if got != tt.use {
   164  			t.Errorf("expected useCached(%v, %v) to return %v, but it returned %v", age, maxAge, tt.use, got)
   165  		}
   166  	}
   167  }
   168  
   169  func TestDistFromImageString(t *testing.T) {
   170  	relPath1 := "some/relative/../path/with/dots/file.aci"
   171  	absPath1, err := filepath.Abs(relPath1)
   172  	if err != nil {
   173  
   174  		t.Fatalf("unexpected error: %v", err)
   175  	}
   176  	relPath2 := "some/relative/../path/with/dots/file"
   177  	absPath2, err := filepath.Abs(relPath2)
   178  	if err != nil {
   179  		t.Fatalf("unexpected error: %v", err)
   180  	}
   181  
   182  	tests := []struct {
   183  		in         string
   184  		distString string
   185  		err        error
   186  	}{
   187  		// Appc
   188  		{
   189  			"example.com/app01",
   190  			"cimd:appc:v=0:example.com/app01",
   191  			nil,
   192  		},
   193  		{
   194  			"example.com/app01:v1.0.0",
   195  			"cimd:appc:v=0:example.com/app01?version=v1.0.0",
   196  			nil,
   197  		},
   198  		{
   199  			"example.com/app01:v1.0.0,label01=?&*/",
   200  			"cimd:appc:v=0:example.com/app01?label01=%3F%26%2A%2F&version=v1.0.0",
   201  			nil,
   202  		},
   203  		{
   204  			"some-image-name",
   205  			"cimd:appc:v=0:some-image-name",
   206  			nil,
   207  		},
   208  		{
   209  			"some-image-name:v1.0.0",
   210  			"cimd:appc:v=0:some-image-name?version=v1.0.0",
   211  			nil,
   212  		},
   213  		{
   214  			"some-image-name:f6432b725a9a5f27eaecfa47a0cbab3c0ea00f22",
   215  			"cimd:appc:v=0:some-image-name?version=f6432b725a9a5f27eaecfa47a0cbab3c0ea00f22",
   216  			nil,
   217  		},
   218  		// ACIArchive
   219  		{
   220  			"file:///absolute/path/to/file.aci",
   221  			"cimd:aci-archive:v=0:file%3A%2F%2F%2Fabsolute%2Fpath%2Fto%2Ffile.aci",
   222  			nil,
   223  		},
   224  		{
   225  			"/absolute/path/to/file.aci",
   226  			"cimd:aci-archive:v=0:file%3A%2F%2F%2Fabsolute%2Fpath%2Fto%2Ffile.aci",
   227  			nil,
   228  		},
   229  		{
   230  			relPath1,
   231  			"cimd:aci-archive:v=0:" + url.QueryEscape("file://"+absPath1),
   232  			nil,
   233  		},
   234  		{
   235  			"https://example.com/app.aci",
   236  			"cimd:aci-archive:v=0:https%3A%2F%2Fexample.com%2Fapp.aci",
   237  			nil,
   238  		},
   239  		// Path with no .aci extension
   240  		{
   241  			"/absolute/path/to/file",
   242  			"",
   243  			fmt.Errorf("invalid image string %q", "file:///absolute/path/to/file"),
   244  		},
   245  		{
   246  			"/absolute/path/to/file.tar",
   247  			"",
   248  			fmt.Errorf("invalid image string %q", "file:///absolute/path/to/file.tar"),
   249  		},
   250  		{
   251  			relPath2,
   252  			"",
   253  			fmt.Errorf("invalid image string %q", "file://"+absPath2),
   254  		},
   255  		// Docker
   256  		{
   257  			"docker:busybox",
   258  			"cimd:docker:v=0:registry-1.docker.io/library/busybox:latest",
   259  			nil,
   260  		},
   261  		{
   262  			"docker://busybox",
   263  			"cimd:docker:v=0:registry-1.docker.io/library/busybox:latest",
   264  			nil,
   265  		},
   266  		{
   267  			"docker:busybox:latest",
   268  			"cimd:docker:v=0:registry-1.docker.io/library/busybox:latest",
   269  			nil,
   270  		},
   271  		{
   272  			"docker://busybox:latest",
   273  			"cimd:docker:v=0:registry-1.docker.io/library/busybox:latest",
   274  			nil,
   275  		},
   276  		{
   277  			"docker:busybox:1.0",
   278  			"cimd:docker:v=0:registry-1.docker.io/library/busybox:1.0",
   279  			nil,
   280  		},
   281  		{
   282  			"docker:busybox@sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6",
   283  			"cimd:docker:v=0:registry-1.docker.io/library/busybox@sha256:a59906e33509d14c036c8678d687bd4eec81ed7c4b8ce907b888c607f6a1e0e6",
   284  			nil,
   285  		},
   286  		{
   287  			"docker:myregistry.example.com:4000/busybox",
   288  			"cimd:docker:v=0:myregistry.example.com:4000/busybox:latest",
   289  			nil,
   290  		},
   291  		{
   292  			"docker:myregistry.example.com:4000/busybox",
   293  			"cimd:docker:v=0:myregistry.example.com:4000/busybox:latest",
   294  			nil,
   295  		},
   296  		{
   297  			"docker:myregistry.example.com:4000/busybox:1.0",
   298  			"cimd:docker:v=0:myregistry.example.com:4000/busybox:1.0",
   299  			nil,
   300  		},
   301  	}
   302  
   303  	for _, tt := range tests {
   304  		d, err := DistFromImageString(tt.in)
   305  		if err != nil {
   306  			if tt.err == nil {
   307  				t.Fatalf("unexpected error: %v", err)
   308  			}
   309  			if tt.err.Error() != err.Error() {
   310  				t.Fatalf("expected error %v, but got error %v", tt.err, err)
   311  			}
   312  			continue
   313  		} else {
   314  			if tt.err != nil {
   315  				t.Fatalf("expected error %v, but got nil error", tt.err)
   316  			}
   317  		}
   318  		td, err := dist.Parse(tt.distString)
   319  		if err != nil {
   320  			t.Fatalf("unexpected error: %v", err)
   321  		}
   322  		if !d.Equals(td) {
   323  			t.Fatalf("expected identical distribution but got %q != %q", tt.distString, d.CIMD().String())
   324  		}
   325  	}
   326  
   327  }