Verifying Distributed Protocols using MSC-Assertions, Run-time Monitoring, and Automatic Test Generation