First, preface
In the previous article http://blog.csdn.net/u013970991/article/details/54862772 has introduced the "automated Mock system 0.9 version", today I will discuss with you our " Automated Mock System version 1.0 ".
second, the test personnel facing the test problem
My company is based on the Dubbo of micro-service transformation, service between the call link is lengthy, each service is a separate team in the maintenance, each team is constantly evolving and maintaining the various services, then the testers will be a very big challenge.
Every time a tester has a functional test, the test case needs to be re-written every time, and the data of the test case cannot be precipitated, especially when automated testing is done, the testers need to prepare the test data for a long time and are very inefficient.
At present, the interface Automation testing framework is also diverse, testng,junit,fitnesse, etc., but all need to test personnel with the ability to write test code, if you want to do the same as the manual interface testing of the same effect of automated testing is a lot of code accumulation, late maintenance code costs very large. Therefore, a simple configuration of the use case flow, no need to write test code of the system is more closely fit the actual work requirements.
For example: With the Internet payment system, a team has added the need to pay transactions, this time to test, the tester in addition to testing the payment transaction requirements itself is correct, but also to combine the upstream and downstream services as a whole regression testing, when developers often in the payment trading system using "hard Code" The way to the upstream and downstream systems to "baffle", if the tester to adjust the test data then the "bezel" should be adjusted, while the project is officially on-line, if the developer did not remove the "bezel" program clean, will face serious online problems.
three, Dubbo's mock function 1, Dubbo of the mock use
Dubbo's own mock function is first to perform a service downgrade, such as a service, when the service provider is all hung up, the client does not throw an exception, but instead passes the mock data back to the authorization failure.
Let's cite an example from the official website to illustrate:
<dubbo:reference interface= "Com.foo.BarService" mock= "Force"/>
We can set the current service as a mock by adding a mock= "force" to the desired reference tag. However, after setting the mock property is not finished, a mock class is required to correspond to our service interface class.
The rules are as follows:
Interface name + mock suffix, the service interface calls the failed mock implementation class, and the mock class must have an argument-free constructor.
If it corresponds to Com.foo.BarService, then the Barservicemock class is created.
public class Barservicemock implements Barservice {public
string SayHello (string name) {
//You can forge fault-tolerant data, This method only executes
return "Fault tolerant data" when the rpcexception is present;}
}
After the above settings, when the call Barservice for remote invocation, the direct request to the Barservicemock class above the simulation test. 2, the principle of Dubbo mock analysis
In the Dubbo configuration file
Classpath:/meta-inf/dubbo/internal/com.alibaba.dubbo.rpc.cluster.cluster
You can see the following configuration list:
Mock=com.alibaba.dubbo.rpc.cluster.support.wrapper.mockclusterwrapper
failover= Com.alibaba.dubbo.rpc.cluster.support.FailoverCluster
failfast= Com.alibaba.dubbo.rpc.cluster.support.FailfastCluster
failsafe= Com.alibaba.dubbo.rpc.cluster.support.FailsafeCluster
failback= Com.alibaba.dubbo.rpc.cluster.support.FailbackCluster
forking= Com.alibaba.dubbo.rpc.cluster.support.ForkingCluster
available= Com.alibaba.dubbo.rpc.cluster.support.AvailableCluster
switch= Com.alibaba.dubbo.rpc.cluster.support.SwitchCluster
mergeable= Com.alibaba.dubbo.rpc.cluster.support.MergeableCluster
broadcast= Com.alibaba.dubbo.rpc.cluster.support.BroadcastCluster
We can see that the configuration file actually has five Parkway by policy:
Availablecluster: Gets the available calls. Traverse all invokers to Judge Invoker.isavalible, as long as a direct call to True is returned, whether or not it succeeds.
Broadcastcluster: Broadcast call. Iterating through all the invokers, calling each call to catch the exception does not affect the other invoker calls.
Failbackcluster: Failed auto-recovery, failed for Invoker call, background record failed request, task timed re-send, usually used for notification.
Failfastcluster: Fast failure, only one call is initiated, failure is immediately error-guaranteed, usually for non-idempotent operations.
Failovercluster: Failover, when a failure occurs, retries another server, which is typically used for read operations, but retries result in a longer delay.
The Failovercluster policy is used by default in Dubbo, and Failovercluster is injected into mockclusterwrapper in the actual execution process:
A Mockclusterinvoker object is created inside the mockclusterwrapper. The actual creation is the Mockclusterinvoker that encapsulates the Failoverclusterinvoker, thus successfully embedding the mock mechanism among the invoker.
let's look at the internal implementation of Mockclusterinvoker:
* If no mock is set in the configuration, then the method call is forwarded directly to the actual invoker (i.e. Failoverclusterinvoker).
String Mockvalue = Directory.geturl (). Getmethodparameter (
invocation.getmethodname (), Constants.mock_key, Boolean.FALSE.toString ()). Trim ();
if (mockvalue.length () = = 0 | | mockvalue.equalsignorecase ("false"))
{
//no mock
result = This.invoker.invoke (invocation);
}
If you configure the Execute mock, such as a service demotion, it is returned directly after the mock execution.
else if (Mockvalue.startswith ("Force"))
{
if (logger.iswarnenabled ())
{
logger.info ("Force-mock: "+ invocation.getmethodname () +" Force-mock enabled, URL: "+ Directory.geturl ());
}
Force:direct mock
result = Domockinvoke (invocation, NULL);
}
In other cases, such as simply configuring Mock=fail:return null, the mock is executed according to the configuration when the normal invocation occurs.
Try
{
result = This.invoker.invoke (invocation);
}
catch (rpcexception rpcexception) {
if (rpcexception.isbiz ()) {
throw rpcexception;
}
else
{
if (logger.iswarnenabled ()) {
logger.info ("Fail-mock:" + invocation.getmethodname () + " Fail-mock enabled, URL: "
+ Directory.geturl (), rpcexception);
}
result = Domockinvoke (invocation, rpcexception);
}
}
3, Dubbo Mock of the applicable scene
Dubbo's mock function is primarily intended for service demotion, where the service provider performs fault-tolerant logic on the client, fault tolerance in the event of Rpcexception (such as network failure, timeout, etc.), and then performs degraded mock logic. It is not suitable for mock test systems.
iv. Realization of automatic mock system 1. Simple use case diagram of mock system
2. Architecture diagram of mock system
In order to realize the mock function based on Dubbo, we need to make some necessary changes to the Dubbo source code, through the above architecture diagram we can see, in fact, we are taking advantage of the filter chain filter chain of the Dubbo implementation of the Mechanism, in order to facilitate better understanding of everyone, The filter mechanism of Dubbo is briefly described below. 2.1. Filter principle analysis of Dubbo
Filter: is a recursive chained call used to add logic before and after a remote call actually executes, just like the filter concept in an AOP interceptor servlet.
The filter interface defines:
@SPI Public
interface Filter {
Result invoke (invoker<?> invoker,invocation invocation) throws rpcexception;
}
The filter implementation class needs to be @activate annotated, @Activate the group property is a string array, we can use this property to specify whether the filter is activated in consumer, provider, or both. The so-called activation is able to be acquired, forming the filter chain.
List<filter> Filters =extensionloader.getextensionloader (filter.class). Getact Ivateextension (INVOKER.GETURL (), key, group);
The KEY is Service_filter_key or Reference_filter_key
Group is consumer or provider
For more information about SPI please refer to another article I wrote earlier:
http://blog.csdn.net/u013970991/article/details/52036265
Protocolfilterwrapper: In the process of exposing and referencing the service, the filter chain of the service provider and the consumer is constructed based on whether the key is provider or consumer, and the filter is eventually encapsulated in the wrapper.
Public <T> exporter<t> Export (invoker<t>invoker) throws Rpcexception {
return Protocol.export ( Buildinvokerchain (Invoker, Constants.service_filter_key, Constants.provider));
}
Public <T> invoker<t> Refer (class<t> type,url URL) throws Rpcexception {
return Buildinvokerchain (Protocol.refer (type, URL), Constants.reference_filter_key, Constants.consumer);
}
Construct the filter chain, which is built by the Buildinvokerchain method in the Protocolfilterwrapper class when we get the activated filter set.
for (int i = Filters.size ()-1; I >= 0; I-) {
final Filter filter = Filters.get (i);
Final invoker<t> next = last;
last = new invoker<t> () {public
Result invoke (invocation invocation) throws Rpcexception {
return Filter.invoke (Next, invocation);
}
.... Other methods
};
}
2.2, Mock process introduction
Note: We have added a custom "Env=test" attribute in the configuration to indicate whether the current environment is test or formal, the user each time through the Dubbo request of the remote service, will first go through our custom filter, Our custom filter will first determine whether the current environment is test or formal, and if it is test, the environment directly accesses the mock configuration Center to get pre-configured mock data and encapsulate it as a user-defined response object return. 3, the mock System Configuration Center
The Mock Configuration Center is a system in which users relate mock data to the application environment, and the whole system is like a workflow engine:
Environment settings, application name settings, bezel rule setting->facade Service interface settings, method rule settings
Environment settings
Note: If the source IP address has not been mapped to the environment, click the Environment list navigation link, go to the Environment List page, click Add, enter the source IP and Environment name, click the OK button to implement the mapping of the source IP to the set environment. Each user can build their own test environment.
App Name settings
Note: Create an app name for the system you are using, and the mock configuration Center uses the name as the app name by default.
Bezel Rules
Note: each bezel rule is a unique bezel consisting of an environment name and an app name, select the environment name and app name in the bezel settings, and set the active state of the bezel.
Facade rules
Note: each facade is a Dubbo service interface class, where its own facade name corresponds to the full path and the bezel name to identify which facade service interface classes belong to which bezel. Method rules
Note: method rules are used to set the method that requires a mock in each facade, you can set the method execution time for different methods, the exception thrown by the method, and so on. 4. Other functions of mock system
Because many application projects after the development of a separate pressure test, and many times the application system and other business systems to form a dependency, if not the other application system can not complete the pressure test, in order to better support performance test group for the baffle pressure test, mock system support pressure measurement function, and the mock system itself can reach a single server above 1000TPS (8c8g).