diff --git a/storage/file/file_test.go b/storage/file/file_test.go new file mode 100644 index 0000000..6f8c6f6 --- /dev/null +++ b/storage/file/file_test.go @@ -0,0 +1,18 @@ +package file + +import ( + "context" + "testing" + + "github.com/micromdm/nanomdm/storage/test" +) + +func TestFileStorage(t *testing.T) { + s, err := New(t.TempDir()) + if err != nil { + t.Fatal(err) + } + + test.TestQueue(t, "EA4E19F1-7F8B-493D-BEAB-264B33BCF4E6", s) + test.TestRetrievePushInfo(t, context.Background(), s) +} diff --git a/storage/file/push.go b/storage/file/push.go index 197a9b2..8997401 100644 --- a/storage/file/push.go +++ b/storage/file/push.go @@ -3,6 +3,7 @@ package file import ( "context" "errors" + "os" "github.com/micromdm/nanomdm/mdm" ) @@ -13,7 +14,11 @@ func (s *FileStorage) RetrievePushInfo(_ context.Context, ids []string) (map[str for _, id := range ids { e := s.newEnrollment(id) tokenUpdate, err := e.readFile(TokenUpdateFilename) - if err != nil { + if errors.Is(err, os.ErrNotExist) { + // TokenUpdate file missing could be a non-existent or + // incomplete enrollment which should not trigger an error. + continue + } else if err != nil { return nil, err } msg, err := mdm.DecodeCheckin(tokenUpdate) diff --git a/storage/file/queue_test.go b/storage/file/queue_test.go deleted file mode 100644 index 2865ea7..0000000 --- a/storage/file/queue_test.go +++ /dev/null @@ -1,17 +0,0 @@ -package file - -import ( - "os" - "testing" - - "github.com/micromdm/nanomdm/storage/test" -) - -func TestQueue(t *testing.T) { - storage, err := New("test-db") - if err != nil { - t.Fatal(err) - } - test.TestQueue(t, "EA4E19F1-7F8B-493D-BEAB-264B33BCF4E6", storage) - os.RemoveAll("test-db") -} diff --git a/storage/mysql/push_test.go b/storage/mysql/push_test.go new file mode 100644 index 0000000..64c48a2 --- /dev/null +++ b/storage/mysql/push_test.go @@ -0,0 +1,23 @@ +package mysql + +import ( + "context" + "os" + "testing" + + "github.com/micromdm/nanomdm/storage/test" +) + +func TestRetrievePushInfo(t *testing.T) { + testDSN := os.Getenv("NANOMDM_MYSQL_STORAGE_TEST_DSN") + if testDSN == "" { + t.Skip("NANOMDM_MYSQL_STORAGE_TEST_DSN not set") + } + + storage, err := New(WithDSN(testDSN), WithDeleteCommands()) + if err != nil { + t.Fatal(err) + } + + test.TestRetrievePushInfo(t, context.Background(), storage) +} diff --git a/storage/storage.go b/storage/storage.go index d33293c..1885fe0 100644 --- a/storage/storage.go +++ b/storage/storage.go @@ -40,9 +40,15 @@ type ServiceStore interface { BootstrapTokenStore } -// PushStore stores and retrieves APNs push-related data. +// PushStore retrieves APNs push-related data. type PushStore interface { - RetrievePushInfo(context.Context, []string) (map[string]*mdm.Push, error) + // RetrievePushInfo retrieves push data for the given ids. + // + // If an ID does not exist or is not enrolled properly then + // implementations should silently skip returning any push data for + // them. It is up to the caller to discern any missing IDs from the + // returned map. + RetrievePushInfo(ctx context.Context, ids []string) (map[string]*mdm.Push, error) } // PushCertStore stores and retrieves APNs push certificates. diff --git a/storage/test/push.go b/storage/test/push.go new file mode 100644 index 0000000..9492a4b --- /dev/null +++ b/storage/test/push.go @@ -0,0 +1,19 @@ +package test + +import ( + "context" + "testing" + + "github.com/micromdm/nanomdm/storage" +) + +func TestRetrievePushInfo(t *testing.T, ctx context.Context, s storage.PushStore) { + t.Run("TestRetrievePushInfo", func(t *testing.T) { + _, err := s.RetrievePushInfo(ctx, []string{"INVALID"}) + if err != nil { + // should NOT recieve a "global" error for an enrollment that + // is merely invalid (or not enrolled yet, or not fully enrolled) + t.Errorf("should NOT have errored: %v", err) + } + }) +}