diff options
Diffstat (limited to 'registry/user_test.go')
-rw-r--r-- | registry/user_test.go | 349 |
1 files changed, 349 insertions, 0 deletions
diff --git a/registry/user_test.go b/registry/user_test.go new file mode 100644 index 0000000..f0c9622 --- /dev/null +++ b/registry/user_test.go @@ -0,0 +1,349 @@ +/* +Copyright (c) 2019 Ben Morrison (gbmor) + +This file is part of Registry. + +Registry is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +Registry is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with Registry. If not, see <https://www.gnu.org/licenses/>. +*/ + +package registry // import "git.sr.ht/~gbmor/getwtxt/registry" + +import ( + "bufio" + "fmt" + "net/http" + "os" + "reflect" + "testing" +) + +var addUserCases = []struct { + name string + nick string + url string + wantErr bool + localOnly bool +}{ + { + name: "Legitimate User (Local Only)", + nick: "testuser1", + url: "http://localhost:8080/twtxt.txt", + wantErr: false, + localOnly: true, + }, + { + name: "Empty Query", + nick: "", + url: "", + wantErr: true, + localOnly: false, + }, + { + name: "Invalid URL", + nick: "foo", + url: "foobarringtons", + wantErr: true, + localOnly: false, + }, + { + name: "Garbage Data", + nick: "", + url: "", + wantErr: true, + localOnly: false, + }, +} + +// Tests if we can successfully add a user to the registry +func Test_Registry_AddUser(t *testing.T) { + registry := initTestEnv() + if !addUserCases[0].localOnly { + http.Handle("/twtxt.txt", http.HandlerFunc(twtxtHandler)) + go fmt.Println(http.ListenAndServe(":8080", nil)) + } + var buf = make([]byte, 256) + // read random data into case 5 + rando, _ := os.Open("/dev/random") + reader := bufio.NewReader(rando) + n, err := reader.Read(buf) + if err != nil || n == 0 { + t.Errorf("Couldn't set up test: %v\n", err) + } + addUserCases[3].nick = string(buf) + addUserCases[3].url = string(buf) + + statuses, err := registry.GetStatuses() + if err != nil { + t.Errorf("Error setting up test: %v\n", err) + } + + for n, tt := range addUserCases { + t.Run(tt.name, func(t *testing.T) { + if tt.localOnly { + t.Skipf("Local-only test. Skipping ... ") + } + + err := registry.AddUser(tt.nick, tt.url, nil, statuses) + + // only run some checks if we don't want an error + if !tt.wantErr { + if err != nil { + t.Errorf("Got error: %v\n", err) + } + + // make sure we have *something* in the registry + if reflect.ValueOf(registry.Users[tt.url]).IsNil() { + t.Errorf("Failed to add user %v registry.\n", tt.url) + } + + // see if the nick in the registry is the same + // as the test case. verifies the URL and the nick + // since the URL is used as the key + data := registry.Users[tt.url] + if data.Nick != tt.nick { + t.Errorf("Incorrect user data added to registry for user %v.\n", tt.url) + } + } + // check for the cases that should throw an error + if tt.wantErr && err == nil { + t.Errorf("Expected error for case %v, got nil\n", n) + } + }) + } +} +func Benchmark_Registry_AddUser(b *testing.B) { + registry := initTestEnv() + statuses, err := registry.GetStatuses() + if err != nil { + b.Errorf("Error setting up test: %v\n", err) + } + + b.ResetTimer() + for i := 0; i < b.N; i++ { + for _, tt := range addUserCases { + err := registry.AddUser(tt.nick, tt.url, nil, statuses) + if err != nil { + continue + } + registry.Users[tt.url] = &User{} + } + } +} + +var delUserCases = []struct { + name string + url string + wantErr bool +}{ + { + name: "Valid User", + url: "https://example.com/twtxt.txt", + wantErr: false, + }, + { + name: "Valid User", + url: "https://example3.com/twtxt.txt", + wantErr: false, + }, + { + name: "Already Deleted User", + url: "https://example3.com/twtxt.txt", + wantErr: true, + }, + { + name: "Empty Query", + url: "", + wantErr: true, + }, + { + name: "Garbage Data", + url: "", + wantErr: true, + }, +} + +// Tests if we can successfully delete a user from the registry +func Test_Registry_DelUser(t *testing.T) { + registry := initTestEnv() + var buf = make([]byte, 256) + // read random data into case 5 + rando, _ := os.Open("/dev/random") + reader := bufio.NewReader(rando) + n, err := reader.Read(buf) + if err != nil || n == 0 { + t.Errorf("Couldn't set up test: %v\n", err) + } + delUserCases[4].url = string(buf) + + for n, tt := range delUserCases { + t.Run(tt.name, func(t *testing.T) { + + err := registry.DelUser(tt.url) + if !reflect.ValueOf(registry.Users[tt.url]).IsNil() { + t.Errorf("Failed to delete user %v from registry.\n", tt.url) + } + if tt.wantErr && err == nil { + t.Errorf("Expected error but did not receive. Case %v\n", n) + } + if !tt.wantErr && err != nil { + t.Errorf("Unexpected error for case %v: %v\n", n, err) + } + }) + } +} +func Benchmark_Registry_DelUser(b *testing.B) { + registry := initTestEnv() + + data1 := &User{ + Nick: registry.Users[delUserCases[0].url].Nick, + Date: registry.Users[delUserCases[0].url].Date, + Status: registry.Users[delUserCases[0].url].Status, + } + + data2 := &User{ + Nick: registry.Users[delUserCases[1].url].Nick, + Date: registry.Users[delUserCases[1].url].Date, + Status: registry.Users[delUserCases[1].url].Status, + } + b.ResetTimer() + + for i := 0; i < b.N; i++ { + for _, tt := range delUserCases { + err := registry.DelUser(tt.url) + if err != nil { + continue + } + } + + registry.Users[delUserCases[0].url] = data1 + registry.Users[delUserCases[1].url] = data2 + } +} + +var getUserStatusCases = []struct { + name string + url string + wantErr bool +}{ + { + name: "Valid User", + url: "https://example.com/twtxt.txt", + wantErr: false, + }, + { + name: "Valid User", + url: "https://example3.com/twtxt.txt", + wantErr: false, + }, + { + name: "Nonexistent User", + url: "https://doesn't.exist/twtxt.txt", + wantErr: true, + }, + { + name: "Empty Query", + url: "", + wantErr: true, + }, + { + name: "Garbage Data", + url: "", + wantErr: true, + }, +} + +// Checks if we can retrieve a single user's statuses +func Test_Registry_GetUserStatuses(t *testing.T) { + registry := initTestEnv() + var buf = make([]byte, 256) + // read random data into case 5 + rando, _ := os.Open("/dev/random") + reader := bufio.NewReader(rando) + n, err := reader.Read(buf) + if err != nil || n == 0 { + t.Errorf("Couldn't set up test: %v\n", err) + } + getUserStatusCases[4].url = string(buf) + + for n, tt := range getUserStatusCases { + t.Run(tt.name, func(t *testing.T) { + + statuses, err := registry.GetUserStatuses(tt.url) + + if !tt.wantErr { + if reflect.ValueOf(statuses).IsNil() { + t.Errorf("Failed to pull statuses for user %v\n", tt.url) + } + // see if the function returns the same data + // that we already have + data := registry.Users[tt.url] + if !reflect.DeepEqual(data.Status, statuses) { + t.Errorf("Incorrect data retrieved as statuses for user %v.\n", tt.url) + } + } + + if tt.wantErr && err == nil { + t.Errorf("Expected error, received nil for case %v: %v\n", n, tt.url) + } + }) + } +} +func Benchmark_Registry_GetUserStatuses(b *testing.B) { + registry := initTestEnv() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + for _, tt := range getUserStatusCases { + _, err := registry.GetUserStatuses(tt.url) + if err != nil { + continue + } + } + } +} + +// Tests if we can retrieve all user statuses at once +func Test_Registry_GetStatuses(t *testing.T) { + registry := initTestEnv() + t.Run("Registry.GetStatuses()", func(t *testing.T) { + + statuses, err := registry.GetStatuses() + if reflect.ValueOf(statuses).IsNil() || err != nil { + t.Errorf("Failed to pull all statuses. %v\n", err) + } + + // Now do the same query manually to see + // if we get the same result + unionmap := NewTimeMap() + for _, v := range registry.Users { + for i, e := range v.Status { + unionmap[i] = e + } + } + if !reflect.DeepEqual(statuses, unionmap) { + t.Errorf("Incorrect data retrieved as statuses.\n") + } + }) +} +func Benchmark_Registry_GetStatuses(b *testing.B) { + registry := initTestEnv() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, err := registry.GetStatuses() + if err != nil { + continue + } + } +} |