Giter VIP home page Giter VIP logo

znsio / specmatic Goto Github PK

View Code? Open in Web Editor NEW
244.0 10.0 50.0 6.49 MB

Turn your contracts into executable specifications. Contract Driven Development - Collaboratively Design & Independently Deploy MicroServices & MicroFrontends.

Home Page: https://specmatic.in

License: MIT License

Kotlin 99.79% Python 0.08% Shell 0.10% Nix 0.01% Dockerfile 0.01%
contract-testing microservices contract-driven-development cdd specmatic qontract

specmatic's Introduction

Specmatic

Maven Central GitHub release CI Build Quality Gate Status Twitter Follow Docker Pulls

Context

In a complex, interdependent eco-system, where each service is evolving rapidly, we want to make the dependencies between them explicit in the form of executable contracts. Contract Driven Development leverages API specifications like OpenAPI, AsyncAPI, etc. as executable contracts allowing teams to get instantaneous feedback while making changes to avoid accidental breakage.

With this ability, we can now independently deploy, at will, any service at any time without having to depend on expensive and fragile integration tests.

What is Specmatic

Specmatic embodies contract driven development (CDD) by leveraging API specifications as executable contracts.

  • Contract as Tests - Generating free tests on the fly based only on you API specifications making sure that your implementation is always adhering to your API specification
  • Contract as Stub - Stubbing a service based on its API specification, that too with the guarantee that your response mappings will always be in sync with your API specs
  • Backward Compatibility Testing (#NOCODE) - Identify backward breaking changes well ahead of time even before write any code based only on your API specifications
  • Central Contract Repository - Single source of truth for your API Specifications
  • API First Design - CDD encourages putting API design first rather than design being a byproduct of service implementation

Our Goal is to support various types of Interactions

Systems interact with each other through several means. Specmatic hopes to address all these mechanisms and not just web interactions.

  • API calls (JSon REST, SOAP XML, gRPC, Thrift, other binary protocols)
  • Events via Messaging (Kafka, Redis, ActiveMQ, RabbitMQ, Kinesis, etc.)
  • DB, Other Data Stores
  • File system
  • Libraries, SDK
  • OS Level Pipes

Specmatic's Product Roadmap

Learn more at specmatic.in

Get started now

Specmatic - Contract Driven Development - YouTube playlist

Youtube playlist

specmatic's People

Contributors

aeoncl avatar androa avatar burdeamit avatar dependabot[bot] avatar harikrishnan83 avatar jaydeepk avatar joelrosario avatar julianharty avatar matus-m avatar nashjain avatar sahilaug avatar snorkell avatar tejasdhole avatar vikram-rao avatar vishal07111998 avatar westse avatar zapheus-runplaywin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

specmatic's Issues

Better Sample Project

Is your feature request related to a problem? Please describe.
The usage of qontract is not very evident with the petstore example.

Describe the solution you'd like
Need to add a new sample project: ecommerce, which is more relatable to a large majority of people.

Describe alternatives you've considered
n/a

Additional context
Screenshot 2020-09-21 at 1 04 29 PM

Qontract hangs when contract file extension is wrong or contract file is missing

Describe the bug
When I run Qontract Stub Command with a non-existent contract file or a contract file with a mis-spelled extension name, the command does not give me any feedback, it simply hangs and I have Ctrl + C it.

Steps to reproduce

  1. Download latest version 0.17.0
  2. Run below command
java -jar qontract.jar non-existent-file.txt
  1. There is not feedback

Expected behavior

  1. In the scenario when the file is missing I want to see error message.
  2. When extension is wrong, I have to get a suitable error message.
  3. The command should exit with error code 1.

Screenshots
NA

System Information:

  • Mac OSX Catalina 15
  • Qontract version 0.17.0
  • JDK 11

Additional context
NA

Qontract test command through qontract.json

Description
Contract test command does'nt work when the qontract path is given in the qontract.json. The following commands works fine.
qontract test tests_new/contract/getRoom.qontract --host=localhost --port=5000
But gives an error if the qontract path is ommitted from the command and added to qontract.json instead.

Steps to reproduce

  1. add the path to qontract.json like this
    "test": [ "tests_new/contract/getRoom.qontract" ]
  2. Run this command: qontract test --host=localhost --port=5000

Expected behavior
getRoom.qontract should run in test mode
instead it gives an error:
Missing required parameter: '<path>'

System Information:

  • qontract version : 0.18.0

Qontract.json file to support wildcard paths

Is your feature request related to a problem? Please describe.
Too many contracts is making the qontract.json file to bloat
"stub": [ "tests_new/contract/external/vidyo/room/findRoom.qontract", "tests_new/contract/external/vidyo/room/createRoom.qontract", "tests_new/contract/external/idam/sendOTP.qontract", "tests_new/contract/external/idam/validateOTP.qontract", "tests_new/contract/external/vidyo/room/createScheduledRoom.qontract", "tests_new/contract/external/vidyo/room/createRoomPIN.qontract", "tests_new/contract/getRoom.qontract" ]
We are expecting this number to go to hundreds.

Describe the solution you'd like
Instead of listing the paths of all the qontract files, user should be able to provide wildcards eg. test: [contracts/**/*.qontract]

Documentation for qontract-node module

Is your feature request related to a problem? Please describe.
Users are not able to discover qontract node module

Describe the solution you'd like
Add a "Qontract for Javascrpt" page in the documentation. Try reusing README from qontract node project.

Improve "Match not found" error, state why it was not found

Is your feature request related to a problem? Please describe.
The error message is vague, and does not give enough information about what went wrong and where to look for the error.

But in fact, "Match not found" only happens when the request URL does not match the stub or contract.

Describe the solution you'd like
This error message needs to state that the URL didn't match.

The error for the request not matching stub / contract may need be different from when the stub expectation path itself does not match any contract scenario.

Describe alternatives you've considered
n/a

Additional context
n/a

Custom header object?

Is it possible to define a custom header object in the Qontract gherkin?

For example documentation shows the example for a Cookie header:
And request-header Cookie (string)

What I'm looking to achieve:
And request-header my-object {"key1": "val1"}

Passthrough url

Is your feature request related to a problem? Please describe.
n/a

Describe the solution you'd like
When a URL in a request is not recognised, we should be able to pass the request on to another service, provided to the stub at start up. The stub will act purely as a proxy between downstream and upstream.

The stub must not however proxy the request if it the URL is recognised but the format is wrong.

Describe alternatives you've considered
n/a

Additional context
n/a

Stub hangs if the specified file does not exist

Description
When the file passed to the stub does not exist, the stub neither displays an error nor exits.

Steps to reproduce

  1. Run the command qontract stub nonexistent.qontract
  2. Qontract runs, but prints nothing, nor does it exit.

Expected behavior
If any of the files or directories provided do not exist, Qontract should highlight this, but it should not die if there is at least one contracts to stub out.

However if all the contracts and directories specified do not exist, qontract should just die with an error message.

Screenshots
n/a

System Information:

  • OS & version: [e.g. MacOS 10.15.6]
  • Browser & version: Safari 13.1.2
  • Qontract version: 0.17.1
  • JDK version: 8

Additional context
n/a

XML support for namespaces

Is your feature request related to a problem? Please describe.
XML namespace prefixes can change, but this is acceptable. Parsers are supposed to use the actual namespaces referred to by the prefix.

For example,

<ns1:data xmlns:ns1="http://example.com/data"><name>Jane Doe</name></ns1:data>

is supposed to be equivalent to:

<ns2:data xmlns:ns2="http://example.com/data"><name>Jane Doe</name></ns2:data>

since the actual namespace value is the same in both.

WSDL codeine tools (such as jaxby) may generate a different namespace prefix for various XML data structures in a given WSDL file each time it is run. But Qontract treats the namespace prefix literally. So when codegen runs and a different namespace prefix is generated, even if the namespace value is the same, Qontract treats it as a different node name.

So in the above example, if the contract contained:

Given type <ns1:data xmlns:ns1="http://example.com/data"><name>(string)</name></ns1:data>

And the value in the payload is:

<ns2:data xmlns:ns2="http://example.com/data"><name>Jane Doe</name></ns2:data>

which might happen because the namespace changed when the code was generated, Qontract will consider them different, and return an error.

Describe the solution you'd like

Qontract should consider this xml type:

<ns1:data xmlns:ns1="http://example.com/data"><name>(string)</name></ns1:data>

to match this xml value:

<ns2:data xmlns:ns2="http://example.com/data"><name>Jane Doe</name></ns2:data>

given that the actual namespace value in both is the same, even though the namespace prefixes are different.

Describe alternatives you've considered
n/a

Additional context
n/a

Drop optional parameters without examples from test requests

Is your feature request related to a problem? Please describe.

When a contract runs in test mode, test requests are generated with random values for optional parameters without examples.

This is not ideal for 2 reasons:

  1. In general, random values in a request are risky since we don't know if the target application will accept them.
  2. From experience, when an example is not provided, it's most likely that the optional parameter was meant to be dropped.

For these reasons, if an optional parameter does not have an example, it should be dropped from the test request completely.

Describe the solution you'd like

EXAMPLE 1

Feature: Customer API
  Scenario Outline: Search
    Given json Customer
    | id      | (number) |
    | name    | (string) |
    | address | (string) |
    When GET /customer?id=(number)&name:opt=(string)&type:opt=(string)
    Then status 200
    And response-body (Customer)

  Examples:
  | id |
  | 10 |

Current behaviour:
When this is run in test mode, the test will have the specified example, but includes randomly generated name and type values.

Desired behaviour:
Qontract should drop the name and type query parameter completely, since query parameters are optional by default and examples are not specified.

{snip}
-> GET /customer?id=10
{snip}

EXAMPLE 2

Feature: Customer API
  Scenario Outline: Update customer details
    Given json Customer
    | name        | (string) |
    | address:opt | (string) |
    When POST /customer(id:number)
    Then status 200

  Examples:
  | id | name     |
  | 10 | Jane Doe |

Current behaviour:
When this is run in test mode, since address has not been specified, two tests are generated, one with the address, and one without.

Desired behaviour:
Qontract should drop the address key from the payload, since there it is optional and is no corresponding example. As a result, only one test should be run.

>> Request Start At Mon Sep 28 12:37:50 IST 2020
-> POST /customer(id:number)
-> Accept-Charset: UTF-8
-> Accept: */*
->
-> {
->     "name": "Jane Doe"
-> }
<- 200 OK
<- Vary: Origin
<- X-Qontract-Result: success
<- Content-Length: 0
<- Content-Type: text/plain
<- Connection: keep-alive
<-
<-
<< Response At Mon Sep 28 12:37:50 IST 2020 ==

Describe alternatives you've considered
n/a

Additional context
This has been a long standing issue, and I feel it's going to be coming up soon-ish, which is why I'm proposing fixing it now.

New syntax and behaviour for optional parameters

Is your feature request related to a problem? Please describe.

  1. Query params should be required unless declared optional.
  2. All optional params should be suffixed with :opt instead of ?, for portability across all param types.

Describe the solution you'd like

Here's the new proposed syntax.

Query params are required by default

Feature: Customer API
  Scenario Outline: Search
    Given json Customer
    | id      | (number) |
    | name    | (string) |
    | address | (string) |
    When GET /customer?name=(string)&type=(string)
    Then status 200
    And response-body (Customer)

Groups of query params

Note that in each scenario, none of the query params are optional.

Feature: Order Search API

  Background:
    Given json Product
    | id  | (number) |
    | qty | (number) |
    Given json Order
    | id       | (number)   |
    | products | (Product*) |
    | type     | (string)   |

  Scenario Outline: Search by type and customer name
    When GET /orders?type=(string)&customer_name=(string)
    Then status 200
    And response-body (Order*)

  Scenario Outline: Search by id and order status
    When GET /orders?customer_id=(number)&status=(string)
    Then status 200
    And response-body (Order*)

Optional query params

Feature: Customer API
  Scenario Outline: Search
    Given json Customer
    | id      | (number) |
    | name    | (string) |
    | address | (string) |
    When GET /customer?name=(string)&type:opt=(string)
    Then status 200
    And response-body (Customer)

Optional json keys

Feature: Customer API
  Scenario Outline: Search
    Given json Customer
    | id       | (number)     |
    | name:opt | (string)     |
    When GET /customer?name=(string)&type=(string)
    Then status 200
    And response-body (Customer)

Nullable values

Feature: Customer API
  Scenario Outline: Search
    Given json Customer
    | id   | (number)     |
    | name | (string:opt) |
    When GET /customer?name=(string)&type=(string)
    Then status 200
    And response-body (Customer)

Optional XML attributes

Feature: Customer API
  Scenario Outline: Search
    Given type Customer
    '''
    <customer><name>(string)</name><address something:optional="(string)">(string)</address></customer>
    '''

Optional form fields

Feature: Customer API
  Scenario Outline: Update
    When POST /customer
    And form-field name (string)
    And form-field address:opt (string)
    Then status 200

Optional request parts

Feature: Customer API
  Scenario Outline: Update
    When POST /customer
    And request-part name (string)
    And request-part address:opt (string)
    Then status 200

Optional headers

Feature: Customer API
  Scenario Outline: Update
    Given json Customer
    | id   | (number)     |
    | name | (string:opt) |
    When POST /customer
    And request-header X-SomeThentication:opt (boolean)
    And request-body (Customer)
    Then status 200

Ability to specify contracts for callbacks.

Design a solution which enables a contract to validate a web hook.

Unlike an API, where qontract invokes a provider API in test mode, the provider API makes an outbound API call when it invokes a web hook. It will need to invoke qontract, which will need to somehow trigger the web hook, and wait listening for the incoming call.

Generate state value if not specified, using the relevant pattern.

E.g.
Scenario:
Given fact id
When POST /
And request-body {"id": "(number)"}]

No value is specified against id. Qontract should examine the request, locate the id field, and use the (number) pattern in it's value to generate an id, and send it as state.

When sending the request, the generated id should be picked up from state.

This will enable id to be recognised as a number without having to declare it twice, in fact and in the request body.

Pass some context with fact setup.

E.g. of new syntax:
Scenario:
Given fact Pet id
When POST /
And request-body {"id": "(number)"}

The context will help the backend helper developer determine what

If for example there is an Order type in the same contract with an id field, the backend developer will not know which resource to create.

But the context will clarify this:
Scenario:
Given fact Order id
When POST /
And request-body {"id": "(number)"}

No fact will be setup with a resource type specifier.

Link to Getting Started invalid.

Description
The README file ends with a link to a URL that's no longer valid.

Steps to reproduce
Click the link to the Getting Started documentation.

Expected behavior
The browser should be redirected to the getting started documentation.

Screenshots
Not worth the fuss, a generic GitHub 404 page is displayed.

System Information:
Not client specific, therefore not very useful.

Additional context
I'll submit a PR with the revised link.

Generated contracts contain underscores in the response

Description
When the contract is generated, both from the proxy and from a postman collection, a response in which multiple keys have the same name results in each of those keys being assigned a variable name, and every additional instance of that name contains an extra underscore. This is fine for the request, but meaningless in the response.

Steps to reproduce

  1. Create a stub file with this response: {"info1": {"data": 1}, "info2": {"data": 2}, "info3": {"data": 3}}
  2. Generate a contract from it and see what it looks like.

Expected behavior
Variable names should not feature in the response types at all.

Screenshots
n/a

System Information:

  • OS & version: MacOS Catalina
  • Browser & version: Safari
  • Qontract version: 0.17.1
  • JDK version: 8

Additional context
n/a

JSON format for header value results in IllegalHeaderValueException in test mode

Description
If a JSON format is specified for a header value, Qontract cannot successfully generate a header value when running a test.

JSON values are generated using a pretty printer, so any JSON value takes up at least 3 lines. When the value of such a header is generated for the purpose of running a test, the http client throws an error because it sees a multilingual string. A header value can consist of only a single line.

Steps to reproduce

  1. Create a contract with this content:
# filename: header_test.qontract
Feature: Header test
  Scenario: Header value has JSON format
    Given type KeyValuePair
    | token | (string) |
    When GET /
    And request-header X-FormattedHeader (KeyValuePair)
    Then status 200
    And response-body (string)
  1. Run it as a stub (qontract stub header_test.qontract).
  2. Run it as a test against the stub from line 2 (qontract test header_test.qontract) to see the error.

You can do the same with the following contract as well:

# filename: header_test.qontract
Feature: Header test
  Scenario: Header value has JSON format
    Given type KeyValuePair {"token": "(string)"}
    When GET /
    And request-header X-FormattedHeader (KeyValuePair)
    Then status 200
    And response-body (string)

Expected behavior
When a JSON format is specified for any reason as part of a value that cannot have more than one line:

  1. It must be serialised without pretty printing,
  2. If there are multiple lines as a result, the error message should clearly state the cause of failure to be multiple lines.

Screenshots
n/a

System Information:

  • OS & version: macOS Catalina 10.15.7
  • Browser & version: Safari
  • Qontract version: 0.19.1
  • JDK version: 8

Additional context
n/a

bundle command fails to pick qontracts & stub data in mono repo

Description
If a stub source in qontract.json is within the mono repo, the bundle command fails to pick the source contracts and stub data in the zip file.

Steps to reproduce

  1. Create a qontract.json with stub source referring to contracts from within the same repo.
{
  "sources": [
    {
      "provider": "git",
      "stub": [
        "../contractsDir/1.qontract"
      ]
    }
  ]
}
  1. Run the bundle command: contract bundle

Expected behavior
The generated bundle.zip file should contain a base directory with the same name as the mono repo. The contracts and stub data should be placed within this base directory under the same path as it is placed in the actual mono repo.

System Information:

  • Qontract version: [0.20.1]

Additional context
n/a

Finer-graded control of responses

Is your feature request related to a problem? Please describe.
I would like to be able to implement fine-graded control of responses e.g. to response first with response A then next time with response B, or to assign weightings e.g. respond 70% of the time with the OK response (think HTTP 200 response), 10% with a server-error response (think HTTP 5xx responses), and 20% with a your request failed response (think HTTP 4xx responses).

These would enable me to automate and test using richer conversations.

Describe the solution you'd like
A mechanism where I could:

  • pre-specify the 'rules' that qontract (or a delegated utility) would return;
  • control the responses on-the-fly where I can do so without needing to shutdown or restart the qontract server.

Describe alternatives you've considered
hmmmm. Looking for another tool? To be honest, I've not really considered many alternatives, I can envisage this being a great enhancement if it's practical to implement.

Additional context
I mentioned a wishful idea of using a plugin architecture in #148 perhaps this is another example of where plugins might work well?

Document qontract.json and / or generate a template

Description

  1. Document the usage of contract configuration file qontract.json
  2. Command to generate template where we can fill the details
  3. Qontract JSON Syntax Validation

Steps to reproduce
N/A

Expected behavior

  1. Description about each section in qontract.json
  2. Error Message to guide the user when they miss mandatory sections in qontract.json

Screenshots
N/A

System Information:
N/A

Additional context
N/A

Recursive type definitions are not supported

Qontract goes into an infinite recursion when testing backward compatibility of the following:

Feature: Recursive
  Scenario: Recursive
    Given json Type
    | data | (Type) |
    When GET /
    Then status 200
    And response-body (Type)

Contribution Guide

Is your feature request related to a problem? Please describe.
There is no clear guidance on how another developer can contribute.

Describe the solution you'd like
Add a CONTRIBUTION.MD file describing how people can contribute

Additional context
This contains everything a developer needs to get started with development, test, and best practices.

Need way to run the server file provided in the documentation

Hey, Thanks for making awesome tool just need one help from your side to run this server which is provided in your documentation on local machine getting error as command not found -

# server.rb
require 'sinatra'

get '/' do
  'Welcome to Petstore!'
end

Sum types

Ability to define multiple things a value could be

E.g.
Given pattern Value (string or boolean)

Content substitution for passthrough responses

Is your feature request related to a problem? Please describe.
I would appreciate being able to substitute parameters in responses from the server before forwarding the revised response to the caller. This would improve the potency of qontract for testing client software in particular, for instance to be able to modify the Time-To-Live (TTL) value a server returns which would then cause the client to send a request to refresh (extend) the TTL far sooner than waiting for the period set in the server's response.

As an example (based on https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control), if a server responds with Cache-Control: public, max-age=604800, immutable I would love to be able to specify a new value for the max-age parameter that would be applied in-situ.

Describe the solution you'd like
There are various ways this could be specified, for instance a simplistic approach could be something along the lines of: var response = str.replace("max-age=604800", "max-age=120"); (bastardised JavaScript syntax).

This could be scoped, e.g.:

  • to a particularly request or response pattern;
  • or by using a namespace e.g. /api/login/*.

We could also consider a syntax where a formula is used to describe the substitution. For my immediate wishes this isn't necessary.

Describe alternatives you've considered
In a magical world, qontract could include a plug-in architecture where we could create and use plugins to provide more flexibility and/or reduce the burden and complexity of qontract's core codebase.

We could alternately implement this function by modifying the server and/or the client however doing so materially changes the system we're testing, and sometimes the source code and/or access to configuration files may not be available. The approach proposed here would enable black-box protocol testing and evaluations.

Additional context
Where substitution changes the content length and/or the response includes or is processed using a hash, then some additional processing may be needed for these circumstances.

Provider side status/Setup

Hi guys, very interesting initiative!
Please, I would like to know how the state of the provider can be configured before running each test on the provider's side?

thanks

Make strict mode the default when stub files are available

Is your feature request related to a problem? Please describe.
When I have provided stubs, and my request doesn't match any of the stubs, Qontract returns randomised values. But this is not helpful. I have provided stubs intentionally, and if they are not getting triggered, I need the reason for it, instead of randomised values.

If I don't have setup, random values don't help again. The takeaway when I see random values is that either my request hasn't matched my stubbed expectation, or my stub files have not been picked up.

Rarely do I actually need the random values.

Describe the solution you'd like
I'd like Qontract start in strict mode by default.

Describe alternatives you've considered
I considered running the stub in strict mode only when there are expectations. But that can get confusing.

  • If the stub has no expectations set, it will run in lenient mode, but when dynamic expectations are set, that should change. The randomised values here are a sign that stubs have not been setup.
  • If there are stub expectations setup but the request does not match, and Qontract is running in lenient mode, the randomised values are a sign that the request does not match the response.

In both the above situations, the randomised values are signs that there are something wrong, rather than being useful. So I think it will be better to just use strict mode, so that we get useful error messages instead of having to deduce what the problem must be.

Additional context
n/a

Stub in lenient (not strict) mode is not checking presence of query parameters in URL

Contract

Scenario Outline: Fetch pet details
       When GET /pets/(id:number)?name=(string)
       Then status 200
       And response-body (name:string)`

Stub

{
      "http-request": {
          "method": "GET",
          "path": "/pets/2",
          "query": {
              "name": "Archie"
          }
      },
      "http-response": {
          "status": 200,
          "body": "Golden Retriever"
      }
}

Curl

$ curl -vs http://0.0.0.0:9000/pets/2 2>&1 | less Golden Retriever

It is matching without query parameter. This should not happen. It should ideally verify if at least the query parameter name is present.

java.lang.NoClassDefFoundError: kotlin/KotlinNothingValueException

Description
I have a Java 11 Spring Boot app, when trying to run Provider unit test I get the java.lang.NoClassDefFoundError: kotlin/KotlinNothingValueException. I have brought in the Kotlin dependency as per the docs but no joy, any suggestions?

<dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib</artifactId> <version>1.4.10</version> </dependency>

`java.lang.NoClassDefFoundError: kotlin/KotlinNothingValueException

at run.qontract.test.QontractJUnitSupport.contractAsTest(QontractJUnitSupport.kt:69)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestFactoryMethod(TimeoutExtension.java:88)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestFactoryTestDescriptor.lambda$invokeTestMethod$1(TestFactoryTestDescriptor.java:95)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestFactoryTestDescriptor.invokeTestMethod(TestFactoryTestDescriptor.java:93)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:128)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58) 

Caused by: java.lang.ClassNotFoundException: kotlin.KotlinNothingValueException
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
... 63 more`

A way to dynamically set examples in a contract

Is your feature request related to a problem? Please describe.
After a login api call, I get a jwt token that is needed for the rest of the contract tests. I can get the jwp through a script or a karate test, but I need a way to make sure that rest of my contracts use this jwt token while running

Describe the solution you'd like
like we have loadDynamicEpectation api to dynamically change the stub, we should have a loadDynamicQontractExample : which can dyncamically load the value of the example through a script.

Describe alternatives you've considered
Instead of altering the qontract, we can have a concept of variables which can be used inside a qontract file, but still we would need a way to dynamicallyChange that variable.

Qontract node: Improvements

  • Setup Babel (transpilation to support older versions) DONE
  • Other commands (check backward compatibility, dynamically load stubs)
  • Typescript DONE
  • unit tests
  • Dev Hygiene
  • Dev contribution guide
  • Publishing rights to private nexus npm repository (Jio)

SonarQube does not run automatically for external PRs

Description
SonarQube failed for a pull request I instigated as a non-member of this codebase. See https://github.com/qontract/qontract/pull/147/checks?check_run_id=1585201400

Here is an extract from the log as the previous link may be ephemeral.

* What went wrong:
Execution failed for task ':sonarqube'.
> You're not authorized to run analysis. Please contact the project administrator.

Steps to reproduce
Submit a PR from a fork of this repo as a non-team member.

Expected behavior
The pre-submit checks should run to completion.

Screenshots
Screenshot 2020-12-20 at 17 33 53

System Information:
Not very relevant.

Additional context
This was my first PR to this repo.

Contract generator should not include Content-Type header

Is your feature request related to a problem? Please describe.
When generating a contract with the proxy or a Postman collection, Qontract currently dumps the Content-Type header into the generated contract and stubs. This is not helpful.

  1. The payload format (JSON / XML) is implicit in the Qontract datatype declaration. So declaring the Content-Type header is unnecessary.
  2. Most tools automatically send this header correctly, so having Qontract enforce it's presence is redundant.

Describe the solution you'd like
The contract generators in the proxy and Postman conversion features should not dump the Content-Type header.

Describe alternatives you've considered
n/a

Additional context
n/a

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.