github.com/GoogleCloudPlatform/testgrid@v0.0.174/resultstore/resultstore_test.go (about)

     1  /*
     2  Copyright 2019 The Kubernetes Authors.
     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 resultstore
    18  
    19  import (
    20  	"fmt"
    21  	"reflect"
    22  	"testing"
    23  	"time"
    24  
    25  	durationpb "github.com/golang/protobuf/ptypes/duration"
    26  	timestamppb "github.com/golang/protobuf/ptypes/timestamp"
    27  	"google.golang.org/genproto/googleapis/devtools/resultstore/v2"
    28  )
    29  
    30  func deepEqual(have, want interface{}) bool {
    31  	return reflect.DeepEqual(have, want)
    32  }
    33  
    34  func diff(have, want interface{}) string {
    35  	// TODO(fejta): something fancier
    36  	return fmt.Sprintf("got %v, want %v", have, want)
    37  }
    38  
    39  func TestDur(t *testing.T) {
    40  	cases := []struct {
    41  		name     string
    42  		dur      time.Duration
    43  		expected *durationpb.Duration
    44  	}{
    45  		{
    46  			name:     "basically works",
    47  			expected: &durationpb.Duration{},
    48  		},
    49  		{
    50  			name: "correct seconds",
    51  			dur:  time.Minute,
    52  			expected: &durationpb.Duration{
    53  				Seconds: 60,
    54  			},
    55  		},
    56  		{
    57  			name: "correct nanos",
    58  			dur:  300 * time.Nanosecond,
    59  			expected: &durationpb.Duration{
    60  				Nanos: 300,
    61  			},
    62  		},
    63  	}
    64  
    65  	for _, tc := range cases {
    66  		t.Run(tc.name, func(t *testing.T) {
    67  			if actual := dur(tc.dur); !deepEqual(actual, tc.expected) {
    68  				t.Errorf(diff(actual, tc.expected))
    69  			}
    70  		})
    71  	}
    72  }
    73  
    74  func TestStamp(t *testing.T) {
    75  	cases := []struct {
    76  		name     string
    77  		when     time.Time
    78  		expected *timestamppb.Timestamp
    79  	}{
    80  		{
    81  			name: "basically works",
    82  		},
    83  		{
    84  			name: "correct when only seconds",
    85  			when: time.Unix(15, 0),
    86  			expected: &timestamppb.Timestamp{
    87  				Seconds: 15,
    88  			},
    89  		},
    90  		{
    91  			name: "correct when only nanos",
    92  			when: time.Unix(0, 22),
    93  			expected: &timestamppb.Timestamp{
    94  				Nanos: 22,
    95  			},
    96  		},
    97  		{
    98  			name: "normal",
    99  			when: time.Unix(33, 4444),
   100  			expected: &timestamppb.Timestamp{
   101  				Seconds: 33,
   102  				Nanos:   4444,
   103  			},
   104  		},
   105  	}
   106  
   107  	for _, tc := range cases {
   108  		t.Run(tc.name, func(t *testing.T) {
   109  			if actual := stamp(tc.when); !deepEqual(actual, tc.expected) {
   110  				t.Errorf(diff(actual, tc.expected))
   111  			}
   112  		})
   113  	}
   114  }
   115  
   116  func TestTiming(t *testing.T) {
   117  	now := time.Now()
   118  	cases := []struct {
   119  		name     string
   120  		when     time.Time
   121  		d        time.Duration
   122  		expected *resultstore.Timing
   123  	}{
   124  		{
   125  			name: "basically works",
   126  		},
   127  		{
   128  			name: "only when",
   129  			when: now,
   130  			expected: &resultstore.Timing{
   131  				StartTime: stamp(now),
   132  			},
   133  		},
   134  		{
   135  			name: "only duration",
   136  			d:    time.Second,
   137  			expected: &resultstore.Timing{
   138  				Duration: dur(time.Second),
   139  			},
   140  		},
   141  	}
   142  
   143  	for _, tc := range cases {
   144  		t.Run(tc.name, func(t *testing.T) {
   145  			actual := timing(tc.when, tc.d)
   146  			if !deepEqual(actual, tc.expected) {
   147  				t.Errorf(diff(actual, tc.expected))
   148  			}
   149  		})
   150  	}
   151  }
   152  
   153  func TestFromTiming(t *testing.T) {
   154  	cases := []struct {
   155  		name string
   156  		t    *resultstore.Timing
   157  		when time.Time
   158  		dur  time.Duration
   159  	}{
   160  		{
   161  			name: "basically works",
   162  		},
   163  		{
   164  			name: "only StartTime works",
   165  			t: &resultstore.Timing{
   166  				StartTime: &timestamppb.Timestamp{
   167  					Seconds: 15,
   168  					Nanos:   7,
   169  				},
   170  			},
   171  			when: time.Unix(15, 7),
   172  		},
   173  		{
   174  			name: "only Duration works",
   175  			t: &resultstore.Timing{
   176  				Duration: &durationpb.Duration{
   177  					Seconds: 3,
   178  					Nanos:   4,
   179  				},
   180  			},
   181  			dur: 3*time.Second + 4*time.Nanosecond,
   182  		},
   183  	}
   184  
   185  	for _, tc := range cases {
   186  		t.Run(tc.name, func(t *testing.T) {
   187  			when, dur := fromTiming(tc.t)
   188  			if !when.Equal(tc.when) {
   189  				t.Errorf("when: %v != expected %v", when, tc.when)
   190  			}
   191  			if dur != tc.dur {
   192  				t.Errorf("dur: %v != expected %v", dur, tc.dur)
   193  			}
   194  		})
   195  	}
   196  }
   197  
   198  func TestProperties(t *testing.T) {
   199  	cases := []struct {
   200  		name     string
   201  		shock    bool
   202  		input    []string
   203  		expected []Property
   204  	}{
   205  		{
   206  			name: "basically works",
   207  		},
   208  		{
   209  			name:  "one pair works",
   210  			input: []string{"hello", "world"},
   211  			expected: []Property{
   212  				{
   213  					Key:   "hello",
   214  					Value: "world",
   215  				},
   216  			},
   217  		},
   218  		{
   219  			name:  "two pairs work",
   220  			input: []string{"key1", "value1", "key2", "value2"},
   221  			expected: []Property{
   222  				{
   223  					Key:   "key1",
   224  					Value: "value1",
   225  				},
   226  				{
   227  					Key:   "key2",
   228  					Value: "value2",
   229  				},
   230  			},
   231  		},
   232  		{
   233  			name:  "unbalanced pairs panic",
   234  			input: []string{"key1", "value1", "panic"},
   235  			shock: true,
   236  		},
   237  	}
   238  
   239  	for _, tc := range cases {
   240  		t.Run(tc.name, func(t *testing.T) {
   241  			var shocked bool
   242  			func() {
   243  				defer func() {
   244  					if r := recover(); r != nil {
   245  						shocked = true
   246  					}
   247  				}()
   248  				actual := Properties(tc.input...)
   249  				if !deepEqual(actual, tc.expected) {
   250  					t.Errorf(diff(actual, tc.expected))
   251  				}
   252  			}()
   253  			if shocked != tc.shock {
   254  				t.Errorf("shock %t != expected %t", shocked, tc.shock)
   255  			}
   256  		})
   257  	}
   258  }
   259  
   260  func TestFromTarget(t *testing.T) {
   261  	now := time.Now()
   262  	cases := []struct {
   263  		name     string
   264  		t        *resultstore.Target
   265  		expected Target
   266  	}{
   267  		{
   268  			name: "empty fromTarget works",
   269  			t: &resultstore.Target{
   270  				Name: "Empty Target",
   271  			},
   272  			expected: Target{
   273  				Name: "Empty Target",
   274  			},
   275  		},
   276  		{
   277  			name: "fromTarget with empty properties",
   278  			t: &resultstore.Target{
   279  				Name: "Empty Properties",
   280  				TargetAttributes: &resultstore.TargetAttributes{
   281  					Tags: []string{
   282  						"attr1",
   283  					},
   284  				},
   285  			},
   286  			expected: Target{
   287  				Name: "Empty Properties",
   288  				Tags: []string{
   289  					"attr1",
   290  				},
   291  			},
   292  		},
   293  		{
   294  			name: "fromTarget with properties",
   295  			t: &resultstore.Target{
   296  				Name: "Contain Properties",
   297  				TargetAttributes: &resultstore.TargetAttributes{
   298  					Tags: []string{
   299  						"attr1",
   300  						"attr2",
   301  					},
   302  				},
   303  				Properties: []*resultstore.Property{
   304  					{
   305  						Key:   "key1",
   306  						Value: "val1",
   307  					},
   308  					{
   309  						Key:   "key2",
   310  						Value: "val2",
   311  					},
   312  				},
   313  			},
   314  			expected: Target{
   315  				Name: "Contain Properties",
   316  				Tags: []string{
   317  					"attr1",
   318  					"attr2",
   319  				},
   320  				Properties: []Property{
   321  					{
   322  						Key:   "key1",
   323  						Value: "val1",
   324  					},
   325  					{
   326  						Key:   "key2",
   327  						Value: "val2",
   328  					},
   329  				},
   330  			},
   331  		},
   332  		{
   333  			name: "test all attributes of target",
   334  			t: &resultstore.Target{
   335  				Name: "All Attributes",
   336  				TargetAttributes: &resultstore.TargetAttributes{
   337  					Tags: []string{
   338  						"attr1",
   339  					},
   340  				},
   341  				Properties: []*resultstore.Property{
   342  					{
   343  						Key:   "key1",
   344  						Value: "val1",
   345  					},
   346  				},
   347  				Timing: &resultstore.Timing{
   348  					StartTime: stamp(now),
   349  					Duration:  dur(time.Second),
   350  				},
   351  				StatusAttributes: &resultstore.StatusAttributes{
   352  					Status:      resultstore.Status_STATUS_UNSPECIFIED,
   353  					Description: "description1",
   354  				},
   355  			},
   356  			expected: Target{
   357  				Name: "All Attributes",
   358  				Tags: []string{
   359  					"attr1",
   360  				},
   361  				Properties: []Property{
   362  					{
   363  						Key:   "key1",
   364  						Value: "val1",
   365  					},
   366  				},
   367  				Start:       now,
   368  				Duration:    time.Second,
   369  				Status:      resultstore.Status_STATUS_UNSPECIFIED,
   370  				Description: "description1",
   371  			},
   372  		},
   373  	}
   374  
   375  	for _, tc := range cases {
   376  		t.Run(tc.name, func(t *testing.T) {
   377  			tgt := fromTarget(tc.t)
   378  			if !deepEqual(tgt.Name, tc.expected.Name) {
   379  				t.Errorf(diff(tgt.Name, tc.expected.Name))
   380  			}
   381  			if !deepEqual(tgt.Tags, tc.expected.Tags) {
   382  				t.Errorf(diff(tgt.Tags, tc.expected.Tags))
   383  			}
   384  			if !deepEqual(tgt.Properties, tc.expected.Properties) {
   385  				t.Errorf(diff(tgt.Properties, tc.expected.Properties))
   386  			}
   387  			if !deepEqual(tgt.Duration, tc.expected.Duration) {
   388  				t.Errorf(diff(tgt.Duration, tc.expected.Duration))
   389  			}
   390  			if !deepEqual(tgt.Status, tc.expected.Status) {
   391  				t.Errorf(diff(tgt.Status, tc.expected.Status))
   392  			}
   393  			if !deepEqual(tgt.Description, tc.expected.Description) {
   394  				t.Errorf(diff(tgt.Description, tc.expected.Description))
   395  			}
   396  		})
   397  	}
   398  }