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 { | ||||
| 		panic("already initialized") | ||||
| 	} | ||||
| 	if instanceID.String() == "" { | ||||
| 	if str := instanceID.String(); str == "" || | ||||
| 		instanceID.String() == "00000000-0000-0000-0000-000000000000" { | ||||
| 		panic("empty UUID") | ||||
| 	} | ||||
| 	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"` | ||||
| } | ||||
| 
 | ||||
| var ( | ||||
| 	// httpClient should be used for HTTP requests. It | ||||
| 	// 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. | ||||
| var buffer = make(map[string]interface{}) | ||||
| var bufferItemCount = 0 | ||||
| var bufferMu sync.RWMutex // protects both the buffer and its count | ||||
| 	buffer          = make(map[string]interface{}) | ||||
| 	bufferItemCount = 0 | ||||
| 	bufferMu        sync.RWMutex // protects both the buffer and its count | ||||
| 
 | ||||
| 	// updating is used to ensure only one | ||||
| 	// update happens at a time. | ||||
| var updating bool | ||||
| var updateMu sync.Mutex | ||||
| 	updating bool | ||||
| 	updateMu sync.Mutex | ||||
| 
 | ||||
| 	// updateTimer fires off the next update. | ||||
| 	// If no update is scheduled, this is nil. | ||||
| var updateTimer *time.Timer | ||||
| var updateTimerMu sync.Mutex | ||||
| 	updateTimer   *time.Timer | ||||
| 	updateTimerMu sync.Mutex | ||||
| 
 | ||||
| 	// instanceUUID is the ID of the current instance. | ||||
| 	// This MUST be set to emit diagnostics. | ||||
| var instanceUUID uuid.UUID | ||||
| 	instanceUUID uuid.UUID | ||||
| 
 | ||||
| 	// enabled indicates whether the package has | ||||
| 	// 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 ( | ||||
| 	// endpoint is the base URL to remote diagnostics server; | ||||
| @ -255,9 +262,4 @@ const ( | ||||
| 	// this value should be a long duration to help alleviate | ||||
| 	// extra load on the server. | ||||
| 	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