Back to Repositories

Testing Cross-Service Communication Patterns in CAT Monitoring Framework

This test suite validates cross-service communication patterns in the CAT monitoring system, simulating client-server interactions and message passing between different components. It focuses on testing the PigeonCall and PigeonService transaction tracking functionality.

Test Coverage Overview

The test suite provides comprehensive coverage of cross-service communication scenarios in CAT.

Key areas tested include:
  • Client-to-server message flow validation
  • Service-to-service communication patterns
  • Message tree construction and domain tracking
  • IP address handling and routing verification
  • Multiple concurrent transaction scenarios

Implementation Analysis

The testing approach uses a continuous loop pattern to simulate real-world service interactions. The implementation leverages CAT’s core messaging components including Transaction, MessageTree, and TraceContextHelper to validate the cross-service tracking functionality.

Key patterns include:
  • Transaction creation and completion workflow
  • Message tree context management
  • Domain and IP address configuration
  • Event logging for client/server tracking

Technical Details

Testing tools and configuration:
  • JUnit test framework
  • CAT client library integration
  • DefaultMessageTree for message context
  • TraceContextHelper for thread management
  • Simulated network endpoints and services
  • Transaction status tracking
  • Thread sleep intervals for timing simulation

Best Practices Demonstrated

The test implementation showcases several testing best practices for distributed systems monitoring.

Notable practices include:
  • Comprehensive service interaction coverage
  • Clear separation of client and service message handling
  • Proper transaction lifecycle management
  • Realistic timing simulation
  • Structured message tree manipulation
  • Clean helper method organization

dianping/cat

cat-home/src/test/java/com/dianping/cat/report/page/cross/CrossTest.java

            
/*
 * Copyright (c) 2011-2018, Meituan Dianping. All Rights Reserved.
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 com.dianping.cat.report.page.cross;

import org.junit.Test;

import com.dianping.cat.Cat;
import com.dianping.cat.message.MessageTree;
import com.dianping.cat.message.Transaction;
import com.dianping.cat.message.context.TraceContextHelper;
import com.dianping.cat.message.spi.DefaultMessageTree;

public class CrossTest {
	@Test
	public void test() throws InterruptedException {
		while (true) {

			sendServiceMsg("CatClient-call", "cat", "10.1.2.15", "catClient", "10.1.2.16");

			sendClientMsg("Cat-Call-1", "cat", "10.1.2.15", "catServer", "10.1.2.17:3000");
			sendClientMsg("Cat-Call-2", "cat", "10.1.2.15", "catServer", "10.1.2.20:3000");
			sendClientMsg("Cat-Call-2", "cat", "10.1.2.15", "catServer", "10.1.2.20:3000");

			sendServiceMsg("Cat-Call-1", "catServer", "10.1.2.17", "cat", "10.1.2.15");
			sendServiceMsg("Cat-Call-2", "catServer", "10.1.2.20", "cat", "10.1.2.15");
			sendServiceMsg("Cat-Call-2", "catServer", "10.1.2.20", "cat", "10.1.2.15");

			sendClientMsg("CatServer-Call-1", "catServer", "10.1.2.17", "server", "10.1.2.18:3000");
			sendClientMsg("CatServer-Call-2", "catServer", "10.1.2.20", "server", "10.1.2.18:3000");
			sendClientMsg("CatServer-Call-2", "catServer", "10.1.2.20", "server", "10.1.2.18:3000");

			sendServiceMsg("Unipay-Call-1", "catServer", "10.1.2.17", "Unipay", "10.1.4.99");
			sendServiceMsg("Unipay-Call-2", "catServer", "10.1.2.20", "Unipay", "10.1.4.99");
			sendServiceMsg("Unipay-Call-2", "catServer", "10.1.2.20", "Unipay", "10.1.4.99");

			sendClientMsg("Unipay-Call-1", "Unipay", "10.1.4.99", "catServer", "10.1.2.17:3000");
			sendClientMsg("Unipay-Call-2", "Unipay", "10.1.4.99", "catServer", "10.1.2.20:3000");
			sendClientMsg("Unipay-Call-2", "Unipay", "10.1.4.99", "catServer", "10.1.2.20:3000");

			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	private void sendServiceMsg(String method, String server, String serverIp, String client, String clientIp) {
		Transaction t = Cat.newTransaction("PigeonService", method);
		MessageTree tree = TraceContextHelper.threadLocal().getMessageTree();
		((DefaultMessageTree) tree).setDomain(server);
		((DefaultMessageTree) tree).setIpAddress(serverIp);
		Cat.logEvent("PigeonService.client", clientIp);
		Cat.logEvent("PigeonService.app", client);
		t.setStatus(Transaction.SUCCESS);
		t.complete();
	}

	private void sendClientMsg(String method, String client, String clientIp, String server, String serverIp) {
		Transaction t = Cat.newTransaction("PigeonCall", method);
		MessageTree tree = TraceContextHelper.threadLocal().getMessageTree();
		((DefaultMessageTree) tree).setDomain(client);
		((DefaultMessageTree) tree).setIpAddress(clientIp);
		Cat.logEvent("PigeonCall.server", serverIp);
		Cat.logEvent("PigeonCall.app", server);
		try {
			Thread.sleep(100);
		} catch (InterruptedException e) {
		}
		t.setStatus(Transaction.SUCCESS);
		t.complete();
	}
}