github.com/stackdocker/rkt@v0.10.1-0.20151109095037-1aa827478248/stage1/init/pod_test.go (about)

     1  // Copyright 2014 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 main
    16  
    17  import (
    18  	"io/ioutil"
    19  	"os"
    20  	"regexp"
    21  	"testing"
    22  
    23  	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema"
    24  	"github.com/coreos/rkt/Godeps/_workspace/src/github.com/appc/spec/schema/types"
    25  )
    26  
    27  const tstprefix = "pod-test"
    28  
    29  func TestQuoteExec(t *testing.T) {
    30  	tests := []struct {
    31  		input  []string
    32  		output string
    33  	}{
    34  		{
    35  			input:  []string{`path`, `"arg1"`, `"'arg2'"`, `'arg3'`},
    36  			output: `"path" "\"arg1\"" "\"\'arg2\'\"" "\'arg3\'"`,
    37  		}, {
    38  			input:  []string{`path`},
    39  			output: `"path"`,
    40  		}, {
    41  			input:  []string{`path`, ``, `arg2`},
    42  			output: `"path" "" "arg2"`,
    43  		}, {
    44  			input:  []string{`path`, `"foo\bar"`, `\`},
    45  			output: `"path" "\"foo\\bar\"" "\\"`,
    46  		}, {
    47  			input:  []string{`path with spaces`, `"foo\bar"`, `\`},
    48  			output: `"path with spaces" "\"foo\\bar\"" "\\"`,
    49  		}, {
    50  			input:  []string{`path with "quo't'es" and \slashes`, `"arg"`, `\`},
    51  			output: `"path with \"quo\'t\'es\" and \\slashes" "\"arg\"" "\\"`,
    52  		}, {
    53  			input:  []string{`$path$`},
    54  			output: `"$path$"`,
    55  		},
    56  	}
    57  
    58  	for i, tt := range tests {
    59  		o := quoteExec(tt.input)
    60  		if o != tt.output {
    61  			t.Errorf("#%d: expected `%v` got `%v`", i, tt.output, o)
    62  		}
    63  	}
    64  }
    65  
    66  // TestAppToNspawnArgsOverridesImageManifestReadOnly tests
    67  // that the ImageManifest's `readOnly` volume setting will be
    68  // overrided by PodManifest.
    69  func TestAppToNspawnArgsOverridesImageManifestReadOnly(t *testing.T) {
    70  	falseVar := false
    71  	trueVar := true
    72  	tests := []struct {
    73  		imageManifestVolumeReadOnly bool
    74  		podManifestVolumeReadOnly   *bool
    75  		expectReadOnly              bool
    76  	}{
    77  		{
    78  			false,
    79  			nil,
    80  			false,
    81  		},
    82  		{
    83  			false,
    84  			&falseVar,
    85  			false,
    86  		},
    87  		{
    88  			false,
    89  			&trueVar,
    90  			true,
    91  		},
    92  		{
    93  			true,
    94  			nil,
    95  			true,
    96  		},
    97  		{
    98  			true,
    99  			&falseVar,
   100  			false,
   101  		},
   102  		{
   103  			true,
   104  			&trueVar,
   105  			true,
   106  		},
   107  	}
   108  
   109  	for i, tt := range tests {
   110  		podManifest := &schema.PodManifest{
   111  			Volumes: []types.Volume{
   112  				{
   113  					Name:     *types.MustACName("foo-mount"),
   114  					Kind:     "host",
   115  					Source:   "/host/foo",
   116  					ReadOnly: tt.podManifestVolumeReadOnly,
   117  				},
   118  			},
   119  		}
   120  		appManifest := &schema.RuntimeApp{
   121  			Mounts: []schema.Mount{
   122  				{
   123  					Volume: *types.MustACName("foo-mount"),
   124  					Path:   "/app/foo",
   125  				},
   126  			},
   127  			App: &types.App{
   128  				Exec:  []string{"/bin/foo"},
   129  				User:  "0",
   130  				Group: "0",
   131  				MountPoints: []types.MountPoint{
   132  					{
   133  						Name:     *types.MustACName("foo-mount"),
   134  						Path:     "/app/foo",
   135  						ReadOnly: tt.imageManifestVolumeReadOnly,
   136  					},
   137  				},
   138  			},
   139  		}
   140  
   141  		tmpDir, err := ioutil.TempDir("", tstprefix)
   142  		if err != nil {
   143  			t.Errorf("error creating tempdir: %v", err)
   144  		}
   145  		defer os.RemoveAll(tmpDir)
   146  
   147  		p := &Pod{Manifest: podManifest, Root: tmpDir}
   148  		output, err := p.appToNspawnArgs(appManifest)
   149  		if err != nil {
   150  			t.Errorf("#%d: unexpected error: `%v`", i, err)
   151  		}
   152  
   153  		if ro := hasBindROArg(output); ro != tt.expectReadOnly {
   154  			t.Errorf("#%d: expected: readOnly: %v, saw: %v", i, tt.expectReadOnly, ro)
   155  		}
   156  	}
   157  }
   158  
   159  func hasBindROArg(output []string) bool {
   160  	roRegexp := regexp.MustCompile("^--bind-ro=/host/foo:.*/app/foo$")
   161  	for i := len(output) - 1; i >= 0; i-- {
   162  		if roRegexp.MatchString(output[i]) {
   163  			return true
   164  		}
   165  	}
   166  	return false
   167  }