Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jv integration tests for runtime config #1899

Open
wants to merge 25 commits into
base: master
Choose a base branch
from

Conversation

JoukoVirtanen
Copy link
Contributor

Description

Integration tests for runtime configuration. The tests create various versions of the runtime configuration file and check that the configuration introspection endpoint returns the correct expected configuration.

Checklist

  • Investigated and inspected CI test results
  • Updated documentation accordingly

Automated testing

  • Added unit tests
  • Added integration tests
  • Added regression tests

If any of these don't apply, please comment below.

Testing Performed

TODO(replace-me)
Use this space to explain how you tested your PR, or, if you didn't test it, why you did not do so. (Valid reasons include "CI is sufficient" or "No testable changes")
In addition to reviewing your code, reviewers must also review your testing instructions, and make sure they are sufficient.

For more details, ref the Confluence page about this section.

} catch (const YAML::Exception& e) {
CLOG(ERROR) << "Failed to parse the configuration file: " << config_file << ". Error: " << e.what();
} catch (const std::exception& e) {
CLOG(ERROR) << "An unknown error occured while loading the configuration file: " << config_file << ". Error: " << e.what();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed

Copy link
Collaborator

@Molter73 Molter73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm less than half way through, I'll finish the review tomorrow.

collector/lib/ConfigLoader.cpp Outdated Show resolved Hide resolved
@@ -67,12 +67,20 @@ TEST(CollectorConfigTest, TestYamlConfigToConfigInvalid) {
}

TEST(CollectorConfigTest, TestYamlConfigToConfigEmpty) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update this test name.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@@ -41,6 +41,7 @@ func NewDockerCollectorManager(e executor.Executor, name string) *DockerCollecto
"/host/etc:ro": "/etc",
"/host/usr/lib:ro": "/usr/lib",
"/host/sys/kernel/debug:ro": "/sys/kernel/debug",
"/etc/stackrox:ro": "/tmp",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider creating a separate directory for this like /tmp/collector-test and use that instead of the full /tmp directory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 42 to 79
func AssertExternalIps(t *testing.T, enable bool, collectorIP string) {
AssertRepeated(t, func() bool {
body := QueryConfig(t, collectorIP)
var response types.RuntimeConfig
err := json.Unmarshal(body, &response)
assert.NoError(t, err)

return response.Networking.ExternalIps.Enable == enable
})
}

func AssertNoRuntimeConfig(t *testing.T, collectorIP string) {
AssertRepeated(t, func() bool {
body := QueryConfig(t, collectorIP)
return strings.TrimSpace(string(body)) == "{}"
})
}

// TODO: This should be in its own package
func AssertRepeated(t *testing.T, condition func() bool) {
tick := time.NewTicker(1 * time.Second)
timer := time.After(3 * time.Minute)

for {
select {
case <-tick.C:
if condition() {
// Condition has been met
return
}

case <-timer:
// TODO: This message should be passed in rather than hard coded here
t.Log("Timeout reached: Runtime configuration was not updated")
t.FailNow()
}
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably want to move all assertions to a separate pkg/assert or similar.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines 34 to 40
func QueryConfig(t *testing.T, collectorIP string) []byte {
log.Info("Querying: /state/config")
body, err := IntrospectionQuery(collectorIP, "/state/config")
assert.NoError(t, err)
log.Info("Response: %q", body)
return body
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not 100% sold this is something we need, from a test we could just do:

body, err := IntrospectionQuery(s.Collector().IP(), "/state/config")
s.Require().NoError(err)

This is simple enough and you can add the logging if you deem it necessary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@JoukoVirtanen JoukoVirtanen force-pushed the jv-integration-tests-for-runtime-config branch from b446ed0 to 347114d Compare November 6, 2024 19:21
@JoukoVirtanen JoukoVirtanen changed the base branch from master to jv-ROX-26726-collector-integration-tests-should-record-all-connections November 7, 2024 02:18
@JoukoVirtanen JoukoVirtanen changed the base branch from jv-ROX-26726-collector-integration-tests-should-record-all-connections to master November 7, 2024 02:23
@@ -33,7 +33,7 @@ loop:
case <-timer:
// we know they don't match at this point, but by using
// ElementsMatch we get much better logging about the differences
return assert.ElementsMatch(t, expected, s.Connections(containerID), "timed out waiting for networks")
return assert.ElementsMatch(t, expected, s.Connections(containerID), "timed out waiting for network connections")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in this file were made here https://github.com/stackrox/collector/pull/1902/files

@@ -32,7 +32,6 @@ const (
// us to use any comparable type as the key)
type ProcessMap map[types.ProcessInfo]interface{}
type LineageMap map[types.ProcessLineage]interface{}
type ConnMap map[types.NetworkInfo]interface{}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes in this file were made here https://github.com/stackrox/collector/pull/1902/files

Comment on lines 15 to 19
func AssertExternalIps(t *testing.T, enable bool, collectorIP string) {
AssertRepeated(t, func() bool {
body, err := collector.IntrospectionQuery(collectorIP, "/state/config")
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to do this here, but the IntrospectionQuery method needs to be part of a collector manager object, it would change this to be a lot simpler/clearer:

func AssertExternalIps(t *testing.T, enable bool, collector *CollectorManager) {
	AssertRepeated(t, func() bool {
		body, err := collector.IntrospectionQuery("/state/config")

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can be done in another PR. Maybe we should have an Introspection struct that could be a member of a Collector interface. The introspection object would get the IP address from the collector object.

integration-tests/pkg/types/runtime_config.go Outdated Show resolved Hide resolved
integration-tests/suites/runtime_config_file.go Outdated Show resolved Hide resolved
integration-tests/suites/runtime_config_file.go Outdated Show resolved Hide resolved
integration-tests/suites/runtime_config_file.go Outdated Show resolved Hide resolved
Copy link
Collaborator

@Molter73 Molter73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for splitting the tests up, as silly as it may sound, it's a lot easier to understand what is going on now.

The comments I left now are mostly on moving some comments around to leave the code blocks on their own. This should help reduce clutter a bit more, since the description of what will be done is provided up front and the code is left as clean as possible.

integration-tests/suites/runtime_config_file.go Outdated Show resolved Hide resolved
integration-tests/suites/runtime_config_file.go Outdated Show resolved Hide resolved
Comment on lines 124 to 127
// The runtime config file was deleted before starting collector so there should not be any config
assert.AssertNoRuntimeConfig(s.T(), collectorIP)
// Since there is no config the default is used, which means external IPs is disabled and we should
// expect a normalized connection
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// The runtime config file was deleted before starting collector so there should not be any config
assert.AssertNoRuntimeConfig(s.T(), collectorIP)
// Since there is no config the default is used, which means external IPs is disabled and we should
// expect a normalized connection
// The runtime config file was deleted before starting collector.
// Default configuration is external IPs disabled.
// We expect normalized connections.
assert.AssertNoRuntimeConfig(s.T(), collectorIP)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This same change can be applied to the other 2 tests.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was not applied to all tests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It has now been applied to all tests.

integration-tests/suites/runtime_config_file.go Outdated Show resolved Hide resolved
integration-tests/suites/runtime_config_file.go Outdated Show resolved Hide resolved
integration-tests/suites/runtime_config_file.go Outdated Show resolved Hide resolved
@JoukoVirtanen
Copy link
Contributor Author

JoukoVirtanen commented Nov 12, 2024

CI results

Run 1
Many Konflux integration tests failed. rhcos failed with

=== RUN   TestProcfsScraperDisableFeatureFlag/TestProcfsScraper
    expect_conn.go:181: 
        	Error Trace:	/tests/pkg/mock_sensor/expect_conn.go:181
        	            				/tests/suites/procfs_scraper.go:72
        	Error:      	elements differ
        	            	
        	            	extra elements in list A:
        	            	([]interface ***) (len=1) ***
        	            	 (types.EndpointInfo) ***
        	            	  Protocol: (string) (len=15) "L4_PROTOCOL_TCP",
        	            	  Address: (types.ListenAddress) ***
        	            	   AddressData: (string) (len=4) "\x00\x00\x00\x00",
        	            	   Port: (int) 80,
        	            	   IpNetwork: (string) (len=5) "\x00\x00\x00\x00 "
        	            	  ***,
        	            	  CloseTimestamp: (string) (len=5) "<nil>",
        	            	  Originator: (types.ProcessOriginator) ***
        	            	   ProcessName: (string) "",
        	            	   ProcessExecFilePath: (string) "",
        	            	   ProcessArgs: (string) ""
        	            	  ***
        	            	 ***
        	            	***
        	            	
        	            	
        	            	listA:
        	            	([]types.EndpointInfo) (len=1) ***
        	            	 (types.EndpointInfo) ***
        	            	  Protocol: (string) (len=15) "L4_PROTOCOL_TCP",
        	            	  Address: (types.ListenAddress) ***
        	            	   AddressData: (string) (len=4) "\x00\x00\x00\x00",
        	            	   Port: (int) 80,
        	            	   IpNetwork: (string) (len=5) "\x00\x00\x00\x00 "
        	            	  ***,
        	            	  CloseTimestamp: (string) (len=5) "<nil>",
        	            	  Originator: (types.ProcessOriginator) ***
        	            	   ProcessName: (string) "",
        	            	   ProcessExecFilePath: (string) "",
        	            	   ProcessArgs: (string) ""
        	            	  ***
        	            	 ***
        	            	***
        	            	
        	            	
        	            	listB:
        	            	([]types.EndpointInfo) ***
        	            	***
        	Test:       	TestProcfsScraperDisableFeatureFlag/TestProcfsScraper
        	Messages:   	timed out waiting for endpoints

The other konflux integration tests failed with either problems pulling the image. Both konflux and non-konflux cos integration tests failed with verifier errors.

Run 2:
Similar errors as above. No procfs test error. Collector also fails for fedora coreos.

Run 3:
rhcos had the following error

=== RUN   TestUdpNetworkFlow/TestUdpNetorkflow/sendto_recvmmsg
    udp_networkflow.go:274: 
        	Error Trace:	/tests/suites/udp_networkflow.go:274
        	            				/tests/suites/udp_networkflow.go:244
        	            				/tests/suites/udp_networkflow.go:105
        	            				/tests/suites/udp_networkflow.go:96
        	            				/go/pkg/mod/github.com/stretchr/[email protected]/suite/suite.go:115
        	Error:      	Received unexpected error:
        	            	Error response from daemon: container create: creating container storage: the container name "udp-server" is already in use by 0b88d4d870e77d5fed05bd5bad8a1dd1e5391d4e229d7ffb3d92a5bd57d0febf. You have to remove that container to be able to reuse that name: that name is already in use
        	            	create udp-server

I did not see a previous failure that caused this error. There were other failures unrelated to the changes in the PR.

@JoukoVirtanen JoukoVirtanen marked this pull request as ready for review November 12, 2024 23:16
@JoukoVirtanen JoukoVirtanen requested a review from a team as a code owner November 12, 2024 23:16
Copy link
Collaborator

@Molter73 Molter73 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look ok, but #1902 still has comments on it that haven't been addressed, if your intent is to merge the changes from that PR with this one, please close it so I can move my comments to this PR.

Comment on lines 36 to 37
tick := time.NewTicker(1 * time.Second)
timer := time.After(3 * time.Minute)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can these timeouts be configurable via some parameters?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@JoukoVirtanen JoukoVirtanen force-pushed the jv-integration-tests-for-runtime-config branch from 8420864 to 9b4f72e Compare November 14, 2024 01:54
@JoukoVirtanen
Copy link
Contributor Author

Changes look ok, but #1902 still has comments on it that haven't been addressed, if your intent is to merge the changes from that PR with this one, please close it so I can move my comments to this PR.

I have addressed the PR review comments in the other PR.

e8bb38d Starting work
23ee1b0 Working with config introspection endpoint. No checks for connections yet
1b919ee Moved code for introspection endpoint from mock sensor to own directory
91ee35e Testing with an invalid config
ae8bf37 Creates a container with an external connection and adds tests for it. Also made changes so that external connections can be checked for
34247e2 Mock server no longer maintains just a map of connections seen, but all connections
edf7ca3 Should be able to handle cidr blocks and non-cidr blocks
4b227bd Able to handle the case when there is only port data
dbed0a1 Brought in changes to server.go to handle external ips
fd24fe8 Apply suggestions from code review
3eb5e48 Cleanup
13f8539 Able to control if connections should be ordered or not. Also added comments
f9ea3fc Listening for new connection events instead of using a ticker
6d06416 Using ExpectSameElementsConnections instead of ExpectExactConnections
@JoukoVirtanen JoukoVirtanen force-pushed the jv-integration-tests-for-runtime-config branch from d734a7c to f092de4 Compare November 16, 2024 00:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants