mirror of
				https://github.com/caddyserver/caddy.git
				synced 2025-10-30 18:22:49 -04:00 
			
		
		
		
	diagnostics: Add a few tests
This commit is contained in:
		
							parent
							
								
									388ff6bc0a
								
							
						
					
					
						commit
						6c17e4d4c8
					
				| @ -32,7 +32,8 @@ func Init(instanceID uuid.UUID) { | |||||||
| 	if enabled { | 	if enabled { | ||||||
| 		panic("already initialized") | 		panic("already initialized") | ||||||
| 	} | 	} | ||||||
| 	if instanceID.String() == "" { | 	if str := instanceID.String(); str == "" || | ||||||
|  | 		instanceID.String() == "00000000-0000-0000-0000-000000000000" { | ||||||
| 		panic("empty UUID") | 		panic("empty UUID") | ||||||
| 	} | 	} | ||||||
| 	instanceUUID = instanceID | 	instanceUUID = instanceID | ||||||
|  | |||||||
							
								
								
									
										109
									
								
								diagnostics/collection_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								diagnostics/collection_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,109 @@ | |||||||
|  | // Copyright 2015 Light Code Labs, LLC | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | // you may not use this file except in compliance with the License. | ||||||
|  | // You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | //     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | // See the License for the specific language governing permissions and | ||||||
|  | // limitations under the License. | ||||||
|  | 
 | ||||||
|  | package diagnostics | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 	"testing" | ||||||
|  | 
 | ||||||
|  | 	"github.com/google/uuid" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestInit(t *testing.T) { | ||||||
|  | 	reset() | ||||||
|  | 
 | ||||||
|  | 	id := doInit(t) // should not panic | ||||||
|  | 
 | ||||||
|  | 	defer func() { | ||||||
|  | 		if r := recover(); r == nil { | ||||||
|  | 			t.Errorf("Second call to Init should have panicked") | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  | 	Init(id) // should panic | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestInitEmptyUUID(t *testing.T) { | ||||||
|  | 	reset() | ||||||
|  | 	defer func() { | ||||||
|  | 		if r := recover(); r == nil { | ||||||
|  | 			t.Errorf("Call to Init with empty UUID should have panicked") | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  | 	Init(uuid.UUID([16]byte{})) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestSet(t *testing.T) { | ||||||
|  | 	reset() | ||||||
|  | 
 | ||||||
|  | 	// should be no-op since we haven't called Init() yet | ||||||
|  | 	Set("test1", "foobar") | ||||||
|  | 	if _, ok := buffer["test"]; ok { | ||||||
|  | 		t.Errorf("Should not have inserted item when not initialized") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// should work after we've initialized | ||||||
|  | 	doInit(t) | ||||||
|  | 	Set("test1", "foobar") | ||||||
|  | 	val, ok := buffer["test1"] | ||||||
|  | 	if !ok { | ||||||
|  | 		t.Errorf("Expected value to be in buffer, but it wasn't") | ||||||
|  | 	} else if val.(string) != "foobar" { | ||||||
|  | 		t.Errorf("Expected 'foobar', got '%v'", val) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// should not overfill buffer | ||||||
|  | 	maxBufferItemsTmp := maxBufferItems | ||||||
|  | 	maxBufferItems = 10 | ||||||
|  | 	for i := 0; i < maxBufferItems+1; i++ { | ||||||
|  | 		Set(fmt.Sprintf("overfill_%d", i), "foobar") | ||||||
|  | 	} | ||||||
|  | 	if len(buffer) > maxBufferItems { | ||||||
|  | 		t.Errorf("Should not exceed max buffer size (%d); has %d items", | ||||||
|  | 			maxBufferItems, len(buffer)) | ||||||
|  | 	} | ||||||
|  | 	maxBufferItems = maxBufferItemsTmp | ||||||
|  | 
 | ||||||
|  | 	// Should overwrite values | ||||||
|  | 	Set("test1", "foobar2") | ||||||
|  | 	val, ok = buffer["test1"] | ||||||
|  | 	if !ok { | ||||||
|  | 		t.Errorf("Expected value to be in buffer, but it wasn't") | ||||||
|  | 	} else if val.(string) != "foobar2" { | ||||||
|  | 		t.Errorf("Expected 'foobar2', got '%v'", val) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // doInit calls Init() with a valid UUID | ||||||
|  | // and returns it. | ||||||
|  | func doInit(t *testing.T) uuid.UUID { | ||||||
|  | 	id, err := uuid.Parse(testUUID) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Could not make UUID: %v", err) | ||||||
|  | 	} | ||||||
|  | 	Init(id) | ||||||
|  | 	return id | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // reset resets all the lovely package-level state; | ||||||
|  | // can be used as a set up function in tests. | ||||||
|  | func reset() { | ||||||
|  | 	instanceUUID = uuid.UUID{} | ||||||
|  | 	buffer = make(map[string]interface{}) | ||||||
|  | 	bufferItemCount = 0 | ||||||
|  | 	updating = false | ||||||
|  | 	enabled = false | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const testUUID = "0b6cfa22-0d4c-11e8-b11b-7a0058e13201" | ||||||
| @ -216,32 +216,39 @@ type Payload struct { | |||||||
| 	Data map[string]interface{} `json:"data,omitempty"` | 	Data map[string]interface{} `json:"data,omitempty"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | var ( | ||||||
| 	// httpClient should be used for HTTP requests. It | 	// httpClient should be used for HTTP requests. It | ||||||
| 	// is configured with a timeout for reliability. | 	// is configured with a timeout for reliability. | ||||||
| var httpClient = http.Client{Timeout: 1 * time.Minute} | 	httpClient = http.Client{Timeout: 1 * time.Minute} | ||||||
| 
 | 
 | ||||||
| 	// buffer holds the data that we are building up to send. | 	// buffer holds the data that we are building up to send. | ||||||
| var buffer = make(map[string]interface{}) | 	buffer          = make(map[string]interface{}) | ||||||
| var bufferItemCount = 0 | 	bufferItemCount = 0 | ||||||
| var bufferMu sync.RWMutex // protects both the buffer and its count | 	bufferMu        sync.RWMutex // protects both the buffer and its count | ||||||
| 
 | 
 | ||||||
| 	// updating is used to ensure only one | 	// updating is used to ensure only one | ||||||
| 	// update happens at a time. | 	// update happens at a time. | ||||||
| var updating bool | 	updating bool | ||||||
| var updateMu sync.Mutex | 	updateMu sync.Mutex | ||||||
| 
 | 
 | ||||||
| 	// updateTimer fires off the next update. | 	// updateTimer fires off the next update. | ||||||
| 	// If no update is scheduled, this is nil. | 	// If no update is scheduled, this is nil. | ||||||
| var updateTimer *time.Timer | 	updateTimer   *time.Timer | ||||||
| var updateTimerMu sync.Mutex | 	updateTimerMu sync.Mutex | ||||||
| 
 | 
 | ||||||
| 	// instanceUUID is the ID of the current instance. | 	// instanceUUID is the ID of the current instance. | ||||||
| 	// This MUST be set to emit diagnostics. | 	// This MUST be set to emit diagnostics. | ||||||
| var instanceUUID uuid.UUID | 	instanceUUID uuid.UUID | ||||||
| 
 | 
 | ||||||
| 	// enabled indicates whether the package has | 	// enabled indicates whether the package has | ||||||
| 	// been initialized and can be actively used. | 	// been initialized and can be actively used. | ||||||
| var enabled bool | 	enabled bool | ||||||
|  | 
 | ||||||
|  | 	// maxBufferItems is the maximum number of items we'll allow | ||||||
|  | 	// in the buffer before we start dropping new ones, in a | ||||||
|  | 	// rough (simple) attempt to keep memory use under control. | ||||||
|  | 	maxBufferItems = 100000 | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| const ( | const ( | ||||||
| 	// endpoint is the base URL to remote diagnostics server; | 	// endpoint is the base URL to remote diagnostics server; | ||||||
| @ -255,9 +262,4 @@ const ( | |||||||
| 	// this value should be a long duration to help alleviate | 	// this value should be a long duration to help alleviate | ||||||
| 	// extra load on the server. | 	// extra load on the server. | ||||||
| 	defaultUpdateInterval = 1 * time.Hour | 	defaultUpdateInterval = 1 * time.Hour | ||||||
| 
 |  | ||||||
| 	// maxBufferItems is the maximum number of items we'll allow |  | ||||||
| 	// in the buffer before we start dropping new ones, in a |  | ||||||
| 	// rough (simple) attempt to keep memory use under control. |  | ||||||
| 	maxBufferItems = 100000 |  | ||||||
| ) | ) | ||||||
|  | |||||||
							
								
								
									
										59
									
								
								diagnostics/diagnostics_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								diagnostics/diagnostics_test.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,59 @@ | |||||||
|  | // Copyright 2015 Light Code Labs, LLC | ||||||
|  | // | ||||||
|  | // Licensed under the Apache License, Version 2.0 (the "License"); | ||||||
|  | // you may not use this file except in compliance with the License. | ||||||
|  | // You may obtain a copy of the License at | ||||||
|  | // | ||||||
|  | //     http://www.apache.org/licenses/LICENSE-2.0 | ||||||
|  | // | ||||||
|  | // Unless required by applicable law or agreed to in writing, software | ||||||
|  | // distributed under the License is distributed on an "AS IS" BASIS, | ||||||
|  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||||
|  | // See the License for the specific language governing permissions and | ||||||
|  | // limitations under the License. | ||||||
|  | 
 | ||||||
|  | package diagnostics | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"testing" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func TestMakePayloadAndResetBuffer(t *testing.T) { | ||||||
|  | 	reset() | ||||||
|  | 	id := doInit(t) | ||||||
|  | 
 | ||||||
|  | 	buffer = map[string]interface{}{ | ||||||
|  | 		"foo1": "bar1", | ||||||
|  | 		"foo2": "bar2", | ||||||
|  | 	} | ||||||
|  | 	bufferItemCount = 2 | ||||||
|  | 
 | ||||||
|  | 	payloadBytes, err := makePayloadAndResetBuffer() | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Error making payload bytes: %v", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if len(buffer) != 0 { | ||||||
|  | 		t.Errorf("Expected buffer len to be 0, got %d", len(buffer)) | ||||||
|  | 	} | ||||||
|  | 	if bufferItemCount != 0 { | ||||||
|  | 		t.Errorf("Expected buffer item count to be 0, got %d", bufferItemCount) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	var payload Payload | ||||||
|  | 	err = json.Unmarshal(payloadBytes, &payload) | ||||||
|  | 	if err != nil { | ||||||
|  | 		t.Fatalf("Error deserializing payload: %v", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	if payload.InstanceID != id.String() { | ||||||
|  | 		t.Errorf("Expected instance ID to be set to '%s' but got '%s'", testUUID, payload.InstanceID) | ||||||
|  | 	} | ||||||
|  | 	if payload.Data == nil { | ||||||
|  | 		t.Errorf("Expected data to be set, but was nil") | ||||||
|  | 	} | ||||||
|  | 	if payload.Timestamp.IsZero() { | ||||||
|  | 		t.Errorf("Expected timestamp to be set, but was zero value") | ||||||
|  | 	} | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user