github.com/go-chef/chef@v0.30.1/node_test.go (about)

     1  package chef
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io"
     7  	"log"
     8  	"net/http"
     9  	"os"
    10  	"reflect"
    11  	"testing"
    12  
    13  	"github.com/stretchr/testify/assert"
    14  )
    15  
    16  var (
    17  	testNodeJSON = "test/node.json"
    18  )
    19  
    20  func TestNodeFromJSONDecoder(t *testing.T) {
    21  	if file, err := os.Open(testNodeJSON); err != nil {
    22  		t.Error("unexpected error", err, "during os.Open on", testNodeJSON)
    23  	} else {
    24  		dec := json.NewDecoder(file)
    25  		var n Node
    26  		if err := dec.Decode(&n); err == io.EOF {
    27  			log.Println(n)
    28  		} else if err != nil {
    29  			log.Fatal(err)
    30  		}
    31  	}
    32  }
    33  
    34  func TestNode_NewNode(t *testing.T) {
    35  	n := NewNode("testnode")
    36  	expect := Node{
    37  		Name:        "testnode",
    38  		Environment: "_default",
    39  		ChefType:    "node",
    40  		JsonClass:   "Chef::Node",
    41  	}
    42  
    43  	if !reflect.DeepEqual(n, expect) {
    44  		t.Errorf("NewNode returned %+v, want %+v", n, expect)
    45  	}
    46  }
    47  
    48  func TestNodesService_Methods(t *testing.T) {
    49  	setup()
    50  	defer teardown()
    51  
    52  	mux.HandleFunc("/nodes", func(w http.ResponseWriter, r *http.Request) {
    53  		switch {
    54  		case r.Method == "GET":
    55  			fmt.Fprintf(w, `{"node1":"https://chef/nodes/node1", "node2":"https://chef/nodes/node2"}`)
    56  		case r.Method == "POST":
    57  			fmt.Fprintf(w, `{ "uri": "http://localhost:4545/nodes/node1" }`)
    58  		}
    59  	})
    60  
    61  	mux.HandleFunc("/nodes/node1", func(w http.ResponseWriter, r *http.Request) {
    62  		switch {
    63  		case r.Method == "GET" || r.Method == "PUT":
    64  			fmt.Fprintf(w, `{
    65  	    "name": "node1",
    66  	    "json_class": "Chef::Node",
    67  	    "chef_type": "node",
    68  	    "chef_environment": "development"
    69  		}`)
    70  		case r.Method == "HEAD":
    71  		case r.Method == "DELETE":
    72  		}
    73  	})
    74  
    75  	// Test list
    76  	nodes, err := client.Nodes.List()
    77  	if err != nil {
    78  		t.Errorf("Nodes.List returned error: %v", err)
    79  	}
    80  
    81  	listWant := map[string]string{"node1": "https://chef/nodes/node1", "node2": "https://chef/nodes/node2"}
    82  
    83  	if !reflect.DeepEqual(nodes, listWant) {
    84  		t.Errorf("Nodes.List returned %+v, want %+v", nodes, listWant)
    85  	}
    86  
    87  	// test Get
    88  	node, err := client.Nodes.Get("node1")
    89  	if err != nil {
    90  		t.Errorf("Nodes.Get returned error: %v", err)
    91  	}
    92  
    93  	wantNode := NewNode("node1")
    94  	wantNode.Environment = "development"
    95  	if !reflect.DeepEqual(node, wantNode) {
    96  		t.Errorf("Nodes.Get returned %+v, want %+v", node, wantNode)
    97  	}
    98  
    99  	// test HEAD
   100  	err = client.Nodes.Head("node1")
   101  	if err != nil {
   102  		t.Errorf("Nodes.Head returned error: %v", err)
   103  	}
   104  
   105  	// test Post
   106  	res, err := client.Nodes.Post(wantNode)
   107  	if err != nil {
   108  		t.Errorf("Nodes.Post returned error: %s", err.Error())
   109  	}
   110  
   111  	postResult := &NodeResult{"http://localhost:4545/nodes/node1"}
   112  	if !reflect.DeepEqual(postResult, res) {
   113  		t.Errorf("Nodes.Post returned %+v, want %+v", res, postResult)
   114  	}
   115  
   116  	// test Put
   117  	putRes, err := client.Nodes.Put(node)
   118  	if err != nil {
   119  		t.Errorf("Nodes.Put returned error %+v", err)
   120  	}
   121  
   122  	if !reflect.DeepEqual(putRes, node) {
   123  		t.Errorf("Nodes.Post returned %+v, want %+v", putRes, node)
   124  	}
   125  
   126  	// test Delete
   127  	err = client.Nodes.Delete(node.Name)
   128  	if err != nil {
   129  		t.Errorf("Nodes.Delete returned error %+v", err)
   130  	}
   131  }
   132  
   133  func TestGetAttribute(t *testing.T) {
   134  	tests := []struct {
   135  		name   string
   136  		node   Node
   137  		paths  []string
   138  		result interface{}
   139  		err    error
   140  	}{
   141  		{
   142  			"no path",
   143  			Node{
   144  				NormalAttributes: map[string]interface{}{
   145  					"foo": "bar",
   146  				},
   147  			},
   148  			[]string{},
   149  			nil,
   150  			ErrNoPathProvided,
   151  		},
   152  		{
   153  			"normal attribute",
   154  			Node{
   155  				NormalAttributes: map[string]interface{}{
   156  					"foo": "bar",
   157  				},
   158  			},
   159  			[]string{"foo"},
   160  			"bar",
   161  			nil,
   162  		},
   163  		{
   164  			"nested normal attribute",
   165  			Node{
   166  				NormalAttributes: map[string]interface{}{
   167  					"foo": map[string]interface{}{
   168  						"bar": "foobar",
   169  					},
   170  				},
   171  			},
   172  			[]string{"foo", "bar"},
   173  			"foobar",
   174  			nil,
   175  		},
   176  		{
   177  			"missing normal attribute",
   178  			Node{
   179  				NormalAttributes: map[string]interface{}{
   180  					"foo": map[string]interface{}{
   181  						"buzz": "foobar",
   182  					},
   183  				},
   184  			},
   185  			[]string{"foo", "bar"},
   186  			nil,
   187  			ErrPathNotFound,
   188  		},
   189  		{
   190  			"automatic first",
   191  			Node{
   192  				AutomaticAttributes: map[string]interface{}{
   193  					"foo": map[string]interface{}{
   194  						"bar": 1,
   195  					},
   196  				},
   197  				OverrideAttributes: map[string]interface{}{
   198  					"foo": map[string]interface{}{
   199  						"bar": 2,
   200  					},
   201  				},
   202  			},
   203  			[]string{"foo", "bar"},
   204  			1,
   205  			nil,
   206  		},
   207  		{
   208  			"override first",
   209  			Node{
   210  				OverrideAttributes: map[string]interface{}{
   211  					"foo": map[string]interface{}{
   212  						"bar": 1,
   213  					},
   214  				},
   215  				NormalAttributes: map[string]interface{}{
   216  					"foo": map[string]interface{}{
   217  						"bar": 2,
   218  					},
   219  				},
   220  			},
   221  			[]string{"foo", "bar"},
   222  			1,
   223  			nil,
   224  		},
   225  		{
   226  			"normal first",
   227  			Node{
   228  				NormalAttributes: map[string]interface{}{
   229  					"foo": map[string]interface{}{
   230  						"bar": 1,
   231  					},
   232  				},
   233  				DefaultAttributes: map[string]interface{}{
   234  					"foo": map[string]interface{}{
   235  						"bar": 2,
   236  					},
   237  				},
   238  			},
   239  			[]string{"foo", "bar"},
   240  			1,
   241  			nil,
   242  		},
   243  		{
   244  			"correct order",
   245  			Node{
   246  				AutomaticAttributes: map[string]interface{}{
   247  					"foo": map[string]interface{}{
   248  						"bar": 4,
   249  					},
   250  				},
   251  				OverrideAttributes: map[string]interface{}{
   252  					"foo": map[string]interface{}{
   253  						"bar": 3,
   254  					},
   255  				},
   256  				NormalAttributes: map[string]interface{}{
   257  					"foo": map[string]interface{}{
   258  						"bar": 2,
   259  					},
   260  				},
   261  				DefaultAttributes: map[string]interface{}{
   262  					"foo": map[string]interface{}{
   263  						"bar": 1,
   264  					},
   265  				},
   266  			},
   267  			[]string{"foo", "bar"},
   268  			4,
   269  			nil,
   270  		},
   271  		{
   272  			"first full path",
   273  			Node{
   274  				OverrideAttributes: map[string]interface{}{
   275  					"foo": map[string]interface{}{
   276  						"buzz": "foobuzz",
   277  					},
   278  				},
   279  				NormalAttributes: map[string]interface{}{
   280  					"foo": map[string]interface{}{
   281  						"bar": "foobar",
   282  					},
   283  				},
   284  			},
   285  			[]string{"foo", "bar"},
   286  			"foobar",
   287  			nil,
   288  		},
   289  		{
   290  			"incomplete path",
   291  			Node{
   292  				NormalAttributes: map[string]interface{}{
   293  					"foo": map[string]interface{}{
   294  						"bar": map[string]interface{}{
   295  							"foobar": "buzz",
   296  						},
   297  					},
   298  				},
   299  			},
   300  			[]string{"foo", "bar"},
   301  			map[string]interface{}{"foobar": "buzz"},
   302  			nil,
   303  		},
   304  	}
   305  
   306  	for _, tt := range tests {
   307  		tt := tt
   308  
   309  		t.Run(tt.name, func(t *testing.T) {
   310  			result, err := tt.node.GetAttribute(tt.paths...)
   311  			assert.ErrorIs(t, err, tt.err)
   312  			assert.Equal(t, tt.result, result)
   313  		})
   314  	}
   315  }