...

Source file src/github.com/coreos/go-systemd/v22/unit/serialize_test.go

Documentation: github.com/coreos/go-systemd/v22/unit

     1  // Copyright 2015 CoreOS, Inc.
     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 unit
    16  
    17  import (
    18  	"io/ioutil"
    19  	"testing"
    20  )
    21  
    22  func TestSerialize(t *testing.T) {
    23  	tests := []struct {
    24  		input  []*UnitOption
    25  		output string
    26  	}{
    27  		// no options results in empty file
    28  		{
    29  			[]*UnitOption{},
    30  			``,
    31  		},
    32  
    33  		// options with same section share the header
    34  		{
    35  			[]*UnitOption{
    36  				&UnitOption{"Unit", "Description", "Foo"},
    37  				&UnitOption{"Unit", "BindsTo", "bar.service"},
    38  			},
    39  			`[Unit]
    40  Description=Foo
    41  BindsTo=bar.service
    42  `,
    43  		},
    44  
    45  		// options with same name are not combined
    46  		{
    47  			[]*UnitOption{
    48  				&UnitOption{"Unit", "Description", "Foo"},
    49  				&UnitOption{"Unit", "Description", "Bar"},
    50  			},
    51  			`[Unit]
    52  Description=Foo
    53  Description=Bar
    54  `,
    55  		},
    56  
    57  		// multiple options printed under different section headers
    58  		{
    59  			[]*UnitOption{
    60  				&UnitOption{"Unit", "Description", "Foo"},
    61  				&UnitOption{"Service", "ExecStart", "/usr/bin/sleep infinity"},
    62  			},
    63  			`[Unit]
    64  Description=Foo
    65  
    66  [Service]
    67  ExecStart=/usr/bin/sleep infinity
    68  `,
    69  		},
    70  
    71  		// options are grouped into sections
    72  		{
    73  			[]*UnitOption{
    74  				&UnitOption{"Unit", "Description", "Foo"},
    75  				&UnitOption{"Service", "ExecStart", "/usr/bin/sleep infinity"},
    76  				&UnitOption{"Unit", "BindsTo", "bar.service"},
    77  			},
    78  			`[Unit]
    79  Description=Foo
    80  BindsTo=bar.service
    81  
    82  [Service]
    83  ExecStart=/usr/bin/sleep infinity
    84  `,
    85  		},
    86  
    87  		// options are ordered within groups, and sections are ordered in the order in which they were first seen
    88  		{
    89  			[]*UnitOption{
    90  				&UnitOption{"Unit", "Description", "Foo"},
    91  				&UnitOption{"Service", "ExecStart", "/usr/bin/sleep infinity"},
    92  				&UnitOption{"Unit", "BindsTo", "bar.service"},
    93  				&UnitOption{"X-Foo", "Bar", "baz"},
    94  				&UnitOption{"Service", "ExecStop", "/usr/bin/sleep 1"},
    95  				&UnitOption{"Unit", "Documentation", "https://foo.com"},
    96  			},
    97  			`[Unit]
    98  Description=Foo
    99  BindsTo=bar.service
   100  Documentation=https://foo.com
   101  
   102  [Service]
   103  ExecStart=/usr/bin/sleep infinity
   104  ExecStop=/usr/bin/sleep 1
   105  
   106  [X-Foo]
   107  Bar=baz
   108  `,
   109  		},
   110  
   111  		// utf8 characters are not a problem
   112  		{
   113  			[]*UnitOption{
   114  				&UnitOption{"©", "µ☃", "ÇôrèÕ$"},
   115  			},
   116  			`[©]
   117  µ☃=ÇôrèÕ$
   118  `,
   119  		},
   120  
   121  		// no verification is done on section names
   122  		{
   123  			[]*UnitOption{
   124  				&UnitOption{"Un\nit", "Description", "Foo"},
   125  			},
   126  			`[Un
   127  it]
   128  Description=Foo
   129  `,
   130  		},
   131  
   132  		// no verification is done on option names
   133  		{
   134  			[]*UnitOption{
   135  				&UnitOption{"Unit", "Desc\nription", "Foo"},
   136  			},
   137  			`[Unit]
   138  Desc
   139  ription=Foo
   140  `,
   141  		},
   142  
   143  		// no verification is done on option values
   144  		{
   145  			[]*UnitOption{
   146  				&UnitOption{"Unit", "Description", "Fo\no"},
   147  			},
   148  			`[Unit]
   149  Description=Fo
   150  o
   151  `,
   152  		},
   153  	}
   154  
   155  	for i, tt := range tests {
   156  		outReader := Serialize(tt.input)
   157  		outBytes, err := ioutil.ReadAll(outReader)
   158  		if err != nil {
   159  			t.Errorf("case %d: encountered error while reading output: %v", i, err)
   160  			continue
   161  		}
   162  
   163  		output := string(outBytes)
   164  		if tt.output != output {
   165  			t.Errorf("case %d: incorrect output", i)
   166  			t.Logf("Expected:\n%s", tt.output)
   167  			t.Logf("Actual:\n%s", output)
   168  		}
   169  	}
   170  }
   171  
   172  // TestSerializeSections - test just UnitSecton specific serialization.
   173  func TestSerializeSection(t *testing.T) {
   174  	tests := []struct {
   175  		input  []*UnitSection
   176  		output string
   177  	}{
   178  		// no options results in empty file
   179  		{
   180  			[]*UnitSection{},
   181  			``,
   182  		},
   183  
   184  		// options with same section share the header
   185  		{
   186  			[]*UnitSection{
   187  				&UnitSection{
   188  					Section: "Unit",
   189  					Entries: []*UnitEntry{
   190  						&UnitEntry{"Description", "Foo"},
   191  						&UnitEntry{"BindsTo", "bar.service"},
   192  					},
   193  				},
   194  			},
   195  			`[Unit]
   196  Description=Foo
   197  BindsTo=bar.service
   198  `,
   199  		},
   200  
   201  		// options with same name are not combined
   202  		{
   203  			[]*UnitSection{
   204  				&UnitSection{
   205  					Section: "Unit",
   206  					Entries: []*UnitEntry{
   207  						&UnitEntry{"Description", "Foo"},
   208  						&UnitEntry{"Description", "Bar"},
   209  					},
   210  				},
   211  			},
   212  			`[Unit]
   213  Description=Foo
   214  Description=Bar
   215  `,
   216  		},
   217  
   218  		// multiple options printed under different section headers
   219  		{
   220  			[]*UnitSection{
   221  				&UnitSection{
   222  					Section: "Unit",
   223  					Entries: []*UnitEntry{
   224  						&UnitEntry{"Description", "Foo"},
   225  					},
   226  				},
   227  				&UnitSection{
   228  					Section: "Service",
   229  					Entries: []*UnitEntry{
   230  						&UnitEntry{"ExecStart", "/usr/bin/sleep infinity"},
   231  					},
   232  				},
   233  			},
   234  			`[Unit]
   235  Description=Foo
   236  
   237  [Service]
   238  ExecStart=/usr/bin/sleep infinity
   239  `,
   240  		},
   241  
   242  		// utf8 characters are not a problem
   243  		{
   244  			[]*UnitSection{
   245  				&UnitSection{
   246  					Section: "©",
   247  					Entries: []*UnitEntry{
   248  						&UnitEntry{"µ☃", "ÇôrèÕ$"},
   249  					},
   250  				},
   251  			},
   252  			`[©]
   253  µ☃=ÇôrèÕ$
   254  `,
   255  		},
   256  
   257  		// no verification is done on section names
   258  		{
   259  			[]*UnitSection{
   260  				&UnitSection{
   261  					Section: "Un\nit",
   262  					Entries: []*UnitEntry{
   263  						&UnitEntry{"Description", "Foo"},
   264  					},
   265  				},
   266  			},
   267  			`[Un
   268  it]
   269  Description=Foo
   270  `,
   271  		},
   272  
   273  		// no verification is done on option names
   274  		{
   275  			[]*UnitSection{
   276  				&UnitSection{
   277  					Section: "Unit",
   278  					Entries: []*UnitEntry{
   279  						&UnitEntry{"Desc\nription", "Foo"},
   280  					},
   281  				},
   282  			},
   283  			`[Unit]
   284  Desc
   285  ription=Foo
   286  `,
   287  		},
   288  
   289  		// no verification is done on option values
   290  		{
   291  			[]*UnitSection{
   292  				&UnitSection{
   293  					Section: "Unit",
   294  					Entries: []*UnitEntry{
   295  						&UnitEntry{"Description", "Fo\no"},
   296  					},
   297  				},
   298  			},
   299  			`[Unit]
   300  Description=Fo
   301  o
   302  `,
   303  		},
   304  
   305  		// Duplicate sections are preserved.
   306  
   307  		{
   308  			[]*UnitSection{
   309  				&UnitSection{
   310  					Section: "Route",
   311  					Entries: []*UnitEntry{
   312  						&UnitEntry{"Gateway", "10.0.10.1"},
   313  						&UnitEntry{"Destination", "10.0.1.1/24"},
   314  					},
   315  				},
   316  				&UnitSection{
   317  					Section: "Route",
   318  					Entries: []*UnitEntry{
   319  						&UnitEntry{"Gateway", "10.0.10.2"},
   320  						&UnitEntry{"Destination", "10.0.2.1/24"},
   321  					},
   322  				},
   323  			},
   324  			`[Route]
   325  Gateway=10.0.10.1
   326  Destination=10.0.1.1/24
   327  
   328  [Route]
   329  Gateway=10.0.10.2
   330  Destination=10.0.2.1/24
   331  `,
   332  		},
   333  	}
   334  
   335  	for i, tt := range tests {
   336  		outReader := SerializeSections(tt.input)
   337  		outBytes, err := ioutil.ReadAll(outReader)
   338  		if err != nil {
   339  			t.Errorf("case %d: encountered error while reading output: %v", i, err)
   340  			continue
   341  		}
   342  
   343  		output := string(outBytes)
   344  		if tt.output != output {
   345  			t.Errorf("case %d: incorrect output", i)
   346  			t.Logf("Expected:\n%s", tt.output)
   347  			t.Logf("Actual:\n%s", output)
   348  		}
   349  	}
   350  }
   351  

View as plain text