or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/maven-org-apache-flink--flink-architecture-tests-test

Architecture testing framework for Apache Flink test code using ArchUnit

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
mavenpkg:maven/org.apache.flink/flink-architecture-tests-test@2.1.x

To install, run

npx @tessl/cli install tessl/maven-org-apache-flink--flink-architecture-tests-test@2.1.0

0

# Flink Architecture Tests - Test

1

2

Flink Architecture Tests - Test provides architectural testing rules specifically designed for Apache Flink's test code infrastructure. Built on ArchUnit, it enables enforcement of architectural rules and coding standards within Flink's testing ecosystem, helping maintain code quality and architectural integrity across Flink's extensive test suite.

3

4

## Package Information

5

6

- **Package Name**: flink-architecture-tests-test

7

- **Package Type**: maven

8

- **Language**: Java

9

- **Group ID**: org.apache.flink

10

- **Artifact ID**: flink-architecture-tests-test

11

- **Installation**: Add as dependency in Maven `pom.xml`

12

13

```xml

14

<dependency>

15

<groupId>org.apache.flink</groupId>

16

<artifactId>flink-architecture-tests-test</artifactId>

17

<version>2.1.0</version>

18

<scope>test</scope>

19

</dependency>

20

```

21

22

## Core Imports

23

24

```java

25

import org.apache.flink.architecture.TestCodeArchitectureTestBase;

26

import org.apache.flink.architecture.rules.ITCaseRules;

27

import org.apache.flink.architecture.rules.BanJunit4Rules;

28

import org.apache.flink.architecture.common.Conditions;

29

import org.apache.flink.architecture.common.JavaFieldPredicates;

30

import org.apache.flink.architecture.common.Predicates;

31

import org.apache.flink.architecture.common.ImportOptions;

32

import com.tngtech.archunit.junit.ArchTest;

33

import com.tngtech.archunit.junit.ArchTests;

34

import com.tngtech.archunit.junit.AnalyzeClasses;

35

import com.tngtech.archunit.core.importer.ImportOption;

36

```

37

38

## Basic Usage

39

40

### Setting up Architectural Tests in a Flink Submodule

41

42

```java

43

package org.apache.flink.architecture;

44

45

import com.tngtech.archunit.junit.AnalyzeClasses;

46

import com.tngtech.archunit.junit.ArchTest;

47

import com.tngtech.archunit.junit.ArchTests;

48

import com.tngtech.archunit.core.importer.ImportOption;

49

import org.apache.flink.architecture.TestCodeArchitectureTestBase;

50

import org.apache.flink.architecture.common.ImportOptions;

51

52

@AnalyzeClasses(

53

packages = {"org.apache.flink.your.module"},

54

importOptions = {

55

ImportOption.OnlyIncludeTests.class,

56

ImportOptions.ExcludeScalaImportOption.class,

57

ImportOptions.ExcludeShadedImportOption.class

58

}

59

)

60

public class TestCodeArchitectureTest {

61

62

// Include common architectural tests from the base

63

@ArchTest

64

public static final ArchTests COMMON_TESTS =

65

ArchTests.in(TestCodeArchitectureTestBase.class);

66

}

67

```

68

69

### Configuration Files Setup

70

71

Create `archunit.properties` in `src/test/resources/`:

72

73

```properties

74

# Controls if the violation store is writable (enables updating existing violations)

75

freeze.store.default.allowStoreUpdate=true

76

77

# Path to store violations relative to project root

78

freeze.store.default.path=archunit-violations

79

80

# Allow creation of new violation stores (uncomment when setting up new tests)

81

# freeze.store.default.allowStoreCreation=true

82

83

# Re-freeze all violations to current state (uncomment for rule changes)

84

# freeze.refreeze=true

85

```

86

87

Create `log4j2-test.properties` in `src/test/resources/` for logging configuration during tests:

88

89

```properties

90

# Set root logger to OFF to prevent flooding build logs during architectural testing

91

rootLogger.level=OFF

92

```

93

94

## Architecture

95

96

Flink Architecture Tests - Test is built around several key components:

97

98

- **Base Test Class**: `TestCodeArchitectureTestBase` provides a central setup for common architectural tests

99

- **Rule Collections**: Modular rule classes (`ITCaseRules`, `BanJunit4Rules`) that group related architectural constraints

100

- **Utility Classes**: Base utility classes (`Conditions`, `JavaFieldPredicates`, `Predicates`) for building custom rules

101

- **Import Options**: Custom import filtering (`ImportOptions`) to exclude Scala and shaded classes from analysis

102

- **ArchUnit Integration**: Built on top of ArchUnit framework for Java architectural testing

103

- **Violation Storage**: Freezing mechanism to track and manage architectural violations over time

104

- **Modular Execution**: Rules are executed in individual submodules rather than centrally

105

106

## Capabilities

107

108

### Base Test Class Integration

109

110

Central setup class that provides common architectural tests for all Flink submodules.

111

112

```java { .api }

113

public class TestCodeArchitectureTestBase {

114

@ArchTest

115

public static final ArchTests ITCASE = ArchTests.in(ITCaseRules.class);

116

}

117

```

118

119

Use this class to include standard architectural tests in your submodule:

120

121

```java

122

import com.tngtech.archunit.junit.ArchTest;

123

import com.tngtech.archunit.junit.ArchTests;

124

import org.apache.flink.architecture.TestCodeArchitectureTestBase;

125

126

public class TestCodeArchitectureTest {

127

@ArchTest

128

public static final ArchTests COMMON_TESTS =

129

ArchTests.in(TestCodeArchitectureTestBase.class);

130

}

131

```

132

133

### Integration Test Rules

134

135

Enforces naming conventions and MiniCluster resource usage for integration tests.

136

137

```java { .api }

138

public class ITCaseRules {

139

@ArchTest

140

public static final ArchRule INTEGRATION_TEST_ENDING_WITH_ITCASE;

141

142

@ArchTest

143

public static final ArchRule ITCASE_USE_MINICLUSTER;

144

}

145

```

146

147

**INTEGRATION_TEST_ENDING_WITH_ITCASE**: Ensures that classes inheriting from `AbstractTestBase` have names ending with "ITCase".

148

149

**ITCASE_USE_MINICLUSTER**: Validates that ITCase tests use appropriate MiniCluster resources. Has different requirements for runtime vs non-runtime packages:

150

151

**For runtime packages** (`org.apache.flink.runtime.*`):

152

- Must use `InternalMiniClusterExtension` for JUnit 5

153

- Must use `MiniClusterWithClientResource` for JUnit 4

154

155

**For non-runtime packages**:

156

- Must use `MiniClusterExtension` for JUnit 5

157

- Must use `MiniClusterWithClientResource` for JUnit 4

158

159

JUnit 5 examples:

160

```java

161

// For runtime packages

162

@RegisterExtension

163

public static final InternalMiniClusterExtension MINI_CLUSTER_RESOURCE =

164

new InternalMiniClusterExtension(

165

new MiniClusterResourceConfiguration.Builder()

166

.setConfiguration(getFlinkConfiguration())

167

.build());

168

169

// For non-runtime packages

170

@RegisterExtension

171

public static final MiniClusterExtension MINI_CLUSTER_RESOURCE =

172

new MiniClusterExtension(

173

new MiniClusterResourceConfiguration.Builder()

174

.setConfiguration(getFlinkConfiguration())

175

.build());

176

177

// Alternative annotation-based approach

178

@ExtendWith(MiniClusterExtension.class)

179

public class MyITCase {

180

// test methods

181

}

182

```

183

184

JUnit 4 examples (legacy):

185

```java

186

@Rule

187

public final MiniClusterWithClientResource miniClusterResource =

188

new MiniClusterWithClientResource(

189

new MiniClusterResourceConfiguration.Builder()

190

.setNumberTaskManagers(1)

191

.setNumberSlotsPerTaskManager(PARALLELISM)

192

.build());

193

194

@ClassRule

195

public static final MiniClusterWithClientResource miniClusterResource =

196

new MiniClusterWithClientResource(

197

new MiniClusterResourceConfiguration.Builder()

198

.setNumberTaskManagers(1)

199

.setNumberSlotsPerTaskManager(PARALLELISM)

200

.build());

201

```

202

203

### JUnit 4 Migration Rules

204

205

Enforces migration from JUnit 4 to JUnit 5 by preventing new JUnit 4 dependencies.

206

207

```java { .api }

208

public class BanJunit4Rules {

209

@ArchTest

210

public static final ArchRule NO_NEW_ADDED_JUNIT4_TEST_RULE;

211

}

212

```

213

214

**NO_NEW_ADDED_JUNIT4_TEST_RULE**: Prevents classes in `org.apache.flink..` packages from depending on JUnit 4 classes (`junit`, `org.junit` packages). Uses freezing mechanism to track existing violations while preventing new ones.

215

216

### Utility Classes for Custom Rules

217

218

Core utility classes from `flink-architecture-tests-base` for building custom architectural rules.

219

220

#### Conditions

221

222

Generic conditions for testing architectural properties.

223

224

```java { .api }

225

public class Conditions {

226

/**

227

* Creates condition to check fulfillment of predicates

228

*/

229

public static <T> ArchCondition<T> fulfill(DescribedPredicate<T> predicate);

230

231

/**

232

* Tests leaf types of methods (return types, parameter types, exception types)

233

*/

234

public static ArchCondition<JavaMethod> haveLeafTypes(DescribedPredicate<JavaClass> predicate);

235

236

/**

237

* Tests leaf return types of methods

238

*/

239

public static ArchCondition<JavaMethod> haveLeafReturnTypes();

240

241

/**

242

* Tests leaf argument types of methods

243

*/

244

public static ArchCondition<JavaMethod> haveLeafArgumentTypes();

245

246

/**

247

* Tests leaf exception types of methods

248

*/

249

public static ArchCondition<JavaMethod> haveLeafExceptionTypes();

250

}

251

```

252

253

#### JavaFieldPredicates

254

255

Predicates for testing Java field properties.

256

257

```java { .api }

258

public class JavaFieldPredicates {

259

// Field modifier predicates

260

public static DescribedPredicate<JavaField> isPublic();

261

public static DescribedPredicate<JavaField> isStatic();

262

public static DescribedPredicate<JavaField> isNotStatic();

263

public static DescribedPredicate<JavaField> isFinal();

264

265

// Type matching predicates

266

public static DescribedPredicate<JavaField> ofType(Class<?> type);

267

public static DescribedPredicate<JavaField> ofType(String typeName);

268

public static DescribedPredicate<JavaField> isAssignableTo(Class<?> type);

269

270

// Annotation predicates

271

public static DescribedPredicate<JavaField> annotatedWith(Class<? extends Annotation> annotationType);

272

public static DescribedPredicate<JavaField> annotatedWith(String annotationTypeName);

273

}

274

```

275

276

#### Predicates

277

278

Complex field predicates combining multiple constraints.

279

280

```java { .api }

281

public class Predicates {

282

// Combined field predicates

283

public static DescribedPredicate<JavaField> arePublicStaticOfType(Class<?> type);

284

public static DescribedPredicate<JavaField> arePublicFinalOfType(Class<?> type);

285

public static DescribedPredicate<JavaField> arePublicStaticFinalAssignableTo(Class<?> type);

286

287

// Annotation combination predicates

288

public static DescribedPredicate<JavaField> arePublicFinalOfTypeWithAnnotation(

289

Class<?> type, Class<? extends Annotation> annotationType);

290

public static DescribedPredicate<JavaField> arePublicStaticFinalOfTypeWithAnnotation(

291

Class<?> type, Class<? extends Annotation> annotationType);

292

public static DescribedPredicate<JavaField> areStaticFinalOfTypeWithAnnotation(

293

Class<?> type, Class<? extends Annotation> annotationType);

294

295

// Utility methods

296

public static String getClassSimpleNameFromFqName(String fullyQualifiedName);

297

public static <T> DescribedPredicate<T> exactlyOneOf(DescribedPredicate<? super T>... predicates);

298

}

299

```

300

301

#### ImportOptions

302

303

Custom import filtering options for ArchUnit class analysis.

304

305

```java { .api }

306

public class ImportOptions {

307

/**

308

* Excludes Scala classes from analysis

309

*/

310

public static class ExcludeScalaImportOption implements ImportOption;

311

312

/**

313

* Excludes shaded/relocated classes from analysis

314

*/

315

public static class ExcludeShadedImportOption implements ImportOption;

316

317

/**

318

* Imports only main classes (excludes test classes)

319

*/

320

public static class MavenMainClassesOnly implements ImportOption;

321

}

322

```

323

324

### Rule Management Commands

325

326

When modifying existing rules, regenerate violation stores:

327

328

```bash

329

# Remove existing violation stores

330

rm -rf `find . -type d -name archunit-violations`

331

332

# Regenerate stores with current state

333

mvn test -Dtest="*TestCodeArchitectureTest*" \

334

-DfailIfNoTests=false \

335

-Darchunit.freeze.refreeze=true \

336

-Darchunit.freeze.store.default.allowStoreCreation=true \

337

-Dfast

338

```

339

340

## Types

341

342

### ArchUnit Core Types

343

344

```java { .api }

345

// From ArchUnit framework

346

import com.tngtech.archunit.junit.ArchTest;

347

import com.tngtech.archunit.junit.ArchTests;

348

import com.tngtech.archunit.junit.AnalyzeClasses;

349

import com.tngtech.archunit.lang.ArchRule;

350

import com.tngtech.archunit.lang.ArchCondition;

351

import com.tngtech.archunit.base.DescribedPredicate;

352

import com.tngtech.archunit.core.domain.JavaClass;

353

import com.tngtech.archunit.core.domain.JavaField;

354

import com.tngtech.archunit.core.domain.JavaMethod;

355

import com.tngtech.archunit.core.importer.ImportOption;

356

357

// Annotation for marking architectural test fields

358

@interface ArchTest {

359

}

360

361

// Container for multiple architectural tests

362

class ArchTests {

363

static ArchTests in(Class<?> testClass);

364

}

365

366

// Individual architectural rule

367

interface ArchRule {

368

ArchRule allowEmptyShould(boolean allow);

369

ArchRule as(String description);

370

}

371

372

// Annotation for specifying which classes to analyze

373

@interface AnalyzeClasses {

374

String[] packages();

375

Class<? extends ImportOption>[] importOptions() default {};

376

}

377

378

// Base types for predicates and conditions

379

interface DescribedPredicate<T> {

380

boolean test(T input);

381

DescribedPredicate<T> and(DescribedPredicate<? super T> other);

382

DescribedPredicate<T> or(DescribedPredicate<? super T> other);

383

}

384

385

interface ArchCondition<T> {

386

ArchCondition<T> and(ArchCondition<? super T> condition);

387

ArchCondition<T> or(ArchCondition<? super T> condition);

388

ArchCondition<T> as(String description);

389

}

390

391

// Import filtering interface

392

interface ImportOption {

393

boolean includes(Location location);

394

}

395

```

396

397

### Configuration Properties

398

399

The package uses ArchUnit's configuration system through `archunit.properties`:

400

401

- `freeze.store.default.allowStoreUpdate`: Controls if violation store is writable

402

- `freeze.store.default.allowStoreCreation`: Enables creation of new violation stores

403

- `freeze.refreeze`: Records current state of violations

404

- `freeze.store.default.path`: Path to store violations (default: "archunit-violations")

405

406

## Error Handling

407

408

When architectural tests fail, ArchUnit provides detailed violation reports including:

409

410

- Specific classes that violate the rules

411

- Line numbers and method details where applicable

412

- Clear descriptions of what constraint was violated

413

- Suggestions for fixing the violations

414

415

Common failure scenarios:

416

417

- **ITCase naming violations**: Tests inheriting from `AbstractTestBase` without "ITCase" suffix

418

- **Missing MiniCluster resources**: ITCase tests without proper cluster setup

419

- **Wrong MiniCluster type**: Runtime packages using `MiniClusterExtension` instead of `InternalMiniClusterExtension`

420

- **JUnit 4 dependencies**: New test code depending on legacy JUnit 4 classes

421

- **Configuration issues**: Missing or incorrect `archunit.properties` setup

422

- **Freezing violations**: Rules that have existing violations must be wrapped in `FreezingArchRule.freeze()`

423

424

### Troubleshooting

425

426

**Violation Store Issues:**

427

- If tests fail due to missing violation stores, set `freeze.store.default.allowStoreCreation=true` in `archunit.properties`

428

- To regenerate all violation stores after rule changes, use the `freeze.refreeze=true` option

429

- Violation stores are stored in the `archunit-violations` directory and should be committed to version control

430

431

**Rule Freezing Requirements:**

432

- Rules with existing violations must use `FreezingArchRule.freeze()` wrapper

433

- Frozen rules should have fixed descriptions using `.as(String)` to reduce maintenance overhead

434

- When modifying rule descriptions, regenerate violation stores to prevent false failures

435

436

**Package-Specific Rule Failures:**

437

- Runtime package tests must use `InternalMiniClusterExtension` for JUnit 5

438

- Non-runtime package tests must use `MiniClusterExtension` for JUnit 5

439

- Both can use `MiniClusterWithClientResource` for JUnit 4 compatibility