@@ -26,13 +26,15 @@ import (
2626 "context"
2727 "encoding/xml"
2828 "fmt"
29+ "os"
2930 "strings"
3031 "sync"
3132 "testing"
3233 "time"
3334
3435 "github.com/Azure/azure-amqp-common-go/v3/uuid"
3536 "github.com/Azure/azure-sdk-for-go/services/servicebus/mgmt/2015-08-01/servicebus"
37+ "github.com/joho/godotenv"
3638 "github.com/stretchr/testify/assert"
3739 "github.com/stretchr/testify/require"
3840
@@ -458,7 +460,12 @@ func (suite *serviceBusSuite) testSubscriptionManager(tests map[string]func(cont
458460 defer func (sName string ) {
459461 ctx , cancel := context .WithTimeout (context .Background (), defaultTimeout )
460462 defer cancel ()
461- if ! suite .NoError (sm .Delete (ctx , sName )) {
463+
464+ err = sm .Delete (ctx , sName )
465+
466+ if ! IsErrNotFound (err ) && ! suite .NoError (err ) {
467+ // not all tests actually create a subscription (some of these tests are
468+ // basically unittests)
462469 suite .Fail (err .Error ())
463470 }
464471 }(subName )
@@ -785,3 +792,130 @@ func checkZeroSubscriptionMessages(ctx context.Context, t *testing.T, topic *Top
785792
786793 assert .Fail (t , "message count never reached zero" )
787794}
795+
796+ func TestErrorMessagesWithMissingPrivileges (t * testing.T ) {
797+ _ = godotenv .Load ()
798+
799+ // we're obscuring the HTTP errors coming back from the service and
800+ // we shouldn't. Just testing some of the common scenarios with a
801+ // connection string that lacks Manage privileges.
802+ lowPrivCS := os .Getenv ("SERVICEBUS_CONNECTION_STRING_NO_MANAGE" )
803+ normalCS := os .Getenv ("SERVICEBUS_CONNECTION_STRING" )
804+
805+ if lowPrivCS == "" || normalCS == "" {
806+ t .Skip ("Need both SERVICEBUS_CONNECTION_STRING_NO_MANAGE and SERVICEBUS_CONNECTION_STRING" )
807+ }
808+
809+ nanoSeconds := time .Now ().UnixNano ()
810+
811+ topicName := fmt .Sprintf ("topic-%d" , nanoSeconds )
812+ queueName := fmt .Sprintf ("queue-%d" , nanoSeconds )
813+ subName := "subscription1"
814+ ruleName := "rule"
815+
816+ // create some entities that we need (there's a diff between something not being
817+ // found and something failing because of lack of authorization)
818+ cleanup := func () func () {
819+ ns , err := NewNamespace (NamespaceWithConnectionString (normalCS ))
820+ qm := ns .NewQueueManager ()
821+
822+ _ , err = qm .Put (context .Background (), queueName )
823+ require .NoError (t , err )
824+
825+ tm := ns .NewTopicManager ()
826+ _ , err = tm .Put (context .Background (), topicName )
827+ require .NoError (t , err )
828+
829+ sm , err := ns .NewSubscriptionManager (topicName )
830+ require .NoError (t , err )
831+
832+ _ , err = sm .Put (context .Background (), subName )
833+ require .NoError (t , err )
834+
835+ _ , err = sm .PutRule (context .Background (), subName , ruleName , TrueFilter {})
836+ require .NoError (t , err )
837+
838+ return func () {
839+ require .NoError (t , tm .Delete (context .Background (), topicName )) // should delete the subscription
840+ require .NoError (t , qm .Delete (context .Background (), queueName ))
841+ }
842+ }()
843+ defer cleanup ()
844+
845+ ns , err := NewNamespace (NamespaceWithConnectionString (lowPrivCS ))
846+ require .NoError (t , err )
847+
848+ ctx := context .Background ()
849+ wg := sync.WaitGroup {}
850+ wg .Add (3 )
851+
852+ go func () {
853+ defer wg .Done ()
854+
855+ qm := ns .NewQueueManager ()
856+
857+ _ , err = qm .Get (ctx , "not-found-queue" )
858+ require .True (t , IsErrNotFound (err ))
859+
860+ _ , err = qm .Get (ctx , queueName )
861+ require .EqualError (t , err , "request failed: 401 Unauthorized" )
862+
863+ _ , err = qm .List (ctx )
864+ require .EqualError (t , err , "request failed: 401 Unauthorized" )
865+
866+ _ , err = qm .Put (ctx , "canneverbecreated" )
867+ require .EqualError (t , err , "request failed: 401 Unauthorized" )
868+
869+ err = qm .Delete (ctx , queueName )
870+ require .EqualError (t , err , "request failed: 401 Unauthorized" )
871+ }()
872+
873+ go func () {
874+ defer wg .Done ()
875+
876+ tm := ns .NewTopicManager ()
877+
878+ _ , err = tm .Get (ctx , "not-found-topic" )
879+ require .True (t , IsErrNotFound (err ))
880+
881+ _ , err = tm .Get (ctx , topicName )
882+ require .EqualError (t , err , "request failed: 401 Unauthorized" )
883+
884+ _ , err = tm .Put (ctx , "canneverbecreated" )
885+ require .Contains (t , err .Error (), "error code: 401, Details: Authorization failed for specified action" )
886+
887+ _ , err = tm .List (ctx )
888+ require .Contains (t , err .Error (), "error code: 401, Details: Manage,EntityRead claims required for this operation" )
889+
890+ err = tm .Delete (ctx , topicName )
891+ require .Contains (t , err .Error (), "request failed: 401 Unauthorized" )
892+ }()
893+
894+ go func () {
895+ defer wg .Done ()
896+
897+ sm , err := ns .NewSubscriptionManager (topicName )
898+ require .NoError (t , err )
899+
900+ _ , err = sm .Get (ctx , "not-found-subscription" )
901+ require .Contains (t , err .Error (), "request failed: 401 SubCode=40100: Unauthorized" )
902+
903+ _ , err = sm .Get (ctx , subName )
904+ require .Contains (t , err .Error (), "request failed: 401 SubCode=40100: Unauthorized" )
905+
906+ _ , err = sm .Put (ctx , subName )
907+ require .Contains (t , err .Error (), "request failed: 401 SubCode=40100: Unauthorized" )
908+
909+ err = sm .Delete (ctx , subName )
910+ require .Contains (t , err .Error (), "request failed: 401 SubCode=40100: Unauthorized" )
911+
912+ _ , err = sm .List (ctx )
913+ require .Contains (t , err .Error (), "request failed: 401 SubCode=40100: Unauthorized" )
914+
915+ _ , err = sm .ListRules (ctx , subName )
916+ require .Contains (t , err .Error (), "request failed: 401 SubCode=40100: Unauthorized" )
917+
918+ }()
919+
920+ wg .Wait ()
921+ }
0 commit comments